# Handlebars-Syntaxreferenz

Bringen Sie mit Handlebars Parameter und props in Ihre Vorlage ein, von der Textanzeige bis zur Erstellung von Tabellen und bedingten Inhalten.

Beim Entwerfen einer Vorlage müssen Sie häufig Daten in den Inhalt integrieren: den Namen eines Empfängers aus `params`, eine Überschrift aus `props` oder eine Liste von Produkten, die als Tabellenzeilen angezeigt werden. Tembuilder verwendet **Handlebars**, um diese Werte mit Ihrem HTML/CSS zu verbinden. Mit seiner Syntax können Sie markieren, wo Daten angezeigt werden sollen, und beschreiben, wie Inhalte angezeigt werden sollen.

Schreiben Sie beispielsweise `{{ params.recipient }}` dorthin, wo der Name des Empfängers hingehört. Wenn Sie eine Vorschau des Dokuments anzeigen oder ein PDF generieren, liest Tembuilder den passenden Wert und ersetzt den Ausdruck durch den tatsächlichen Inhalt. Dadurch können Sie dasselbe Design mit unterschiedlichen Datensätzen wiederverwenden.

Diese Anleitung führt Sie durch das Lesen von Werten aus [Parameters](/docs/de/data/parameters/) und [Props](/docs/de/data/parameters-props/), das bedingte Anzeigen von Inhalten, das Wiederholen von Listen und die Verwendung erweiterter Syntax, wenn Ihre Vorlage komplexere Datenstrukturen benötigt.

## 1. Von der Vorlage zum Dokument

Beginnen Sie mit einem einfachen Beispiel: Sie haben eine Abschnittsstütze `heading` mit dem Wert `Invoice` erstellt und einen Parameter `recipient` mit dem Wert `Tembuilder` deklariert. Platzieren Sie im HTML des Abschnitts jeden Wert an der Stelle, an der er angezeigt werden soll, indem Sie `{{ ... }}` verwenden:

```handlebars
<h1>{{ props.heading }}</h1>
<p>{{ params.recipient }}</p>
```

```html
<h1>Invoice</h1>
<p>Tembuilder</p>
```

<figure class="doc-sim data-assets-illustration" aria-label="HTML Vorlage und Daten werden zu Dokumentinhalten">
<div class="sim-stage"><div class="ds-flow"><div class="ds-code"><code>{{ props.heading }} → Invoice</code><code>{{ params.recipient }} → Tembuilder</code></div><span class="ds-flow-arrow">→</span><div class="ds-paper"><small>Tembuilder</small><strong>Rechnung</strong><div><p>Tembuilder</p></div></div></div></div>
<figcaption>Ausdrücke werden vor der PDF-Paginierung ersetzt.</figcaption>
</figure>

## 2. Wählen Sie den richtigen Datenpfad

| Pfad | Liest |
| --- | --- |
| `{{ params.recipient }}` | Für diesen Lauf bereitgestellte Daten, nachdem Standardwerte angewendet wurden. |
| `{{ props.heading }}` | Props für den Teil, der kompiliert wird. In einem Abschnitt überschreiben Abschnittswerte gleichnamige Global-Werte. |
| `{{ global.props.company }}` | Global props explizit, auch wenn ein Abschnitt denselben Namen überschreibt. |
| `{{ @root.params.recipient }}` | Run-Daten aus einer Schleife oder einem `with`-Block. |

Verwenden Sie explizite `params.`-Pfade anstelle bloßer Parameternamen. Stammparameternamen werden aus Kompatibilitätsgründen ebenfalls offengelegt, Namen wie `props`, `params` und `global` werden jedoch vom Plattformkontext belegt.

Jeder Abschnitt, jede Kopf- und Fußzeile wird mit seinem eigenen Kontext zusammengestellt. `@root` bedeutet das Stammverzeichnis dieser Zusammenstellung, nicht einen anderen Abschnitt. [Variants](/docs/de/data/variants/) wählt Propsüberschreibungen aus, bevor Ausdrücke ausgeführt werden.

## 3. Text, Zahlen, Boolesche Werte und fehlende Werte

Das folgende Objekt sind **Laufdaten**: Geben Sie seine Felder in Run ein, ohne einen äußeren `params`-Wrapper hinzuzufügen. Deklarieren Sie passende Typen in Parameters → Schema.

```json
{
  "recipient": "Tembuilder & Tembuilder",
  "quantity": 2,
  "balance": 0,
  "paid": false,
  "totalLabel": "250,000 VND"
}
```

```handlebars
<p>{{ params.recipient }} · {{ params.quantity }}</p>
<p>{{ params.totalLabel }}</p>
{{#if params.paid}}Paid{{else}}Awaiting payment{{/if}}
```

Text wird als Text angezeigt, Zahlen zeigen ihren Wert an und das direkte Drucken eines Booleschen Werts erzeugt `true` oder `false`. Verwenden Sie eine Bedingung für eine leserfreundliche Beschriftung. Behalten Sie `2` numerisch und `false` boolesch bei; `"2"` und `"false"` sind Zeichenfolgen.

Ein ungelöster Wert gibt normalerweise nichts aus. Dies ist kein Ersatz für die Deklaration erforderlicher Felder oder die Validierung von Laufdaten. Ungültige Syntax oder ein unbekannter Helfer stoppt die Kompilierung.

Handlebars berechnet `quantity * price` nicht, ruft `.toFixed(2)` nicht auf und formatiert Datumsangaben/Währungen nicht automatisch. Bereiten Sie vor dem Rendern Summen und formatierte Zeichenfolgen vor. `{{ params.quantity + 1 }}` und `{{ params.total.toFixed(2) }}` sind keine unterstützten JavaScript-Ausdrücke.

## 4. Objekt- und Eigenschaftsnamen

```json
{
  "recipient": { "name": "Tembuilder", "address": { "city": "Hanoi" } },
  "labels": { "invoice_title": "Invoice", "postal_code": "10000" }
}
```

```handlebars
<p>{{ params.recipient.name }} · {{ params.recipient.address.city }}</p>
<h2>{{ params.labels.invoice_title }}</h2>
<p>{{ params.labels.postal_code }}</p>
```

Verwenden Sie Feldnamen wie `recipientName` oder `postal_code`. Der Editor ersetzt Leerzeichen, Bindestriche und andere Zeichen außerhalb von Buchstaben, Ziffern und Unterstrichen durch `_`; Das erste Zeichen muss ein Buchstabe oder ein Unterstrich sein. Für ein vorhandenes importiertes Schema mit Schlüsseln wie `postal code` kann Handlebars diese mit `{{ params.labels.[postal code] }}` lesen. Diese Syntax ändert nichts an den Namensregeln des Editors. Um ein Objekt sinnvoll darzustellen, wählen Sie seine Felder aus oder iterieren Sie sie. Das Drucken des gesamten Objekts ist keine JSON-Serialisierung.

## 5. Bedingungen: `if`, `else`, `unless`

```handlebars
{{#if params.paid}}
  <p>Payment received</p>
{{else if params.overdue}}
  <p>Payment overdue</p>
{{else}}
  <p>Awaiting payment</p>
{{/if}}
{{#unless params.paid}}<p>Please pay before the due date.</p>{{/unless}}
{{#if params.balance includeZero=true}}<p>Balance: {{ params.balance }}</p>{{/if}}
```

`if` nimmt den negativen Zweig für `false`, `null`, fehlende Werte, eine leere Zeichenfolge, Null und ein leeres Array. `includeZero=true` bewirkt, dass Null den positiven Zweig einnimmt. Ein leeres Objekt und die Zeichenfolge `"false"` nehmen den positiven Zweig. `unless` kehrt den Zustand um. `if` ändert den aktuellen Kontext nicht.

Auf dieser Plattform gibt es keine integrierten `eq`-, `gt`-, `and`- oder `or`-Helfer. Berechnen Sie einen booleschen Wert wie `overdue` in der Eingabe, anstatt `{{#if params.balance > 0}}` zu schreiben.

## 6. Arrays: `each` und leere Zustände

```json
{
  "items": [{ "name": "Design", "quantity": 2 }, { "name": "Review", "quantity": 1 }],
  "tags": ["Draft", "Internal"]
}
```

```handlebars
<table>
  <thead><tr><th>Item</th><th>Quantity</th></tr></thead>
  <tbody>
    {{#each params.items}}
      <tr><td>{{ this.name }}</td><td>{{ this.quantity }}</td></tr>
    {{else}}
      <tr><td colspan="2">No items</td></tr>
    {{/each}}
  </tbody>
</table>
{{#each params.tags}}<span>{{ this }}</span>{{/each}}
```

`this` ist das aktuelle Element: ein Objekt für `items`, eine Zeichenfolge für `tags`. Mit `{{ params.items.[0].name }}` ist ein direkter Array-Zugriff möglich. Befolgen Sie für lange Tabellen die [Paginierungsanleitung](/docs/de/editor/pagination/).

<figure class="doc-sim data-assets-illustration" aria-label="Jedes Array-Element wird zu einer Tabellenzeile; Leere Arrays verwenden else">
<div class="sim-stage"><div class="ds-code"><code>{{#each params.items}}</code><code>  {{ this.name }} · {{ this.quantity }}</code><code>{{else}} No items {{/each}}</code></div><div class="ds-data-table"><div><b>Artikel</b><b>Menge</b></div><div><span>Design</span><span>2</span></div><div><span>Rezension</span><span>1</span></div></div></div>
<figcaption>Ein Element → eine Zeile. Eine leere Liste → der else-Zweig.</figcaption>
</figure>

## 7. Schleifenmetadaten und Objektiteration

| Ausdruck | Bedeutung innerhalb `each` |
| --- | --- |
| `@index` | Array-Position, beginnend bei Null. |
| `@first`, `@last` | Flags für erstes/letztes Array-Element. |
| `@key` | Eigenschaftsname beim Iterieren eines Objekts. |

```handlebars
{{#each params.tags}}
  {{#if @first}}<strong>Tags:</strong>{{/if}}
  {{ this }}{{#unless @last}}, {{/unless}}
{{/each}}
{{#each params.recipient}}
  <p>{{ @key }}: {{ this }}</p>
{{/each}}
```

Verwenden Sie `@index + 1` nicht zum Erstellen von Zeilennummern. Geben Sie ein `rowNumber`-Feld an, wenn Sie eine Nummerierung benötigen, die bei eins beginnt.

## 8. Kontext: `with`, übergeordnete Pfade und Root

```handlebars
{{#with params.recipient}}
  <p>{{ name }}</p>
{{else}}
  <p>No recipient</p>
{{/with}}
{{#each params.items}}
  <p>{{ this.name }} — {{ ../props.heading }}</p>
  <small>{{ @root.global.props.company }}</small>
{{/each}}
```

`with` und `each` ändern den Kontext. `../` kehrt zum übergeordneten Kontext zurück; `@root` bietet stabilen Zugriff auf das Kompilierungsstammverzeichnis über verschachtelte Schleifen hinweg. Für das Hinzufügen eines `if` ist kein weiterer `../` erforderlich.

Aliase erleichtern das Verfolgen verschachtelter Listen. Deklarieren Sie hier `groups` als Array von Objekten mit jeweils einem `name`- und einem `items`-Array:

```handlebars
{{#each params.groups as |group groupIndex|}}
  <h2>{{ group.name }}</h2>
  {{#each group.items as |item itemIndex|}}
    <p>{{ groupIndex }}.{{ itemIndex }} — {{ item.name }}</p>
  {{/each}}
{{/each}}
```

## 9. Dynamische Suche und Unterausdrücke

Verwenden Sie `lookup` für einen als Daten bereitgestellten Schlüssel. Deklarieren Sie `labels` als Objekt und `selectedKey` als Text. für `{ "labels": { "approved": "Approved" }, "selectedKey": "approved" }`:

```handlebars
<p>{{ lookup params.labels params.selectedKey }}</p>
{{#with (lookup params.labels params.selectedKey)}}<strong>{{ this }}</strong>{{/with}}
```

Klammern verschachteln ein Helferergebnis in einem anderen Helfer. Sie werten kein beliebiges JavaScript aus. Argumente in Anführungszeichen sind Literalzeichenfolgen, während Pfade ohne Anführungszeichen Daten lesen. `includeZero=true` ist eine benannte Hilfsoption, keine Zuweisung zu Eingabedaten.

## 10. HTML-Escape- und CSS-Werte

```handlebars
<p>{{ params.recipient }}</p>
```

Für `recipient` gleich `Tembuilder & Tembuilder` enthält die HTML-Quelle `Tembuilder &amp; Tembuilder` und das Dokument zeigt **Tembuilder & Tembuilder** an. Behalten Sie doppelte geschweifte Klammern für normale Eingaben bei.

`{{{ params.trustedHtml }}}` und `{{& params.trustedHtml }}` fügen HTML ein, ohne zu entkommen. Verwenden Sie sie nur für vertrauenswürdige, bereinigte Markups, die zu Dokumentelementen werden sollen. Escaping ist keine URL- oder CSS-Validierung. Validieren Sie die für `href`, `src` oder Stile vorgesehenen Werte.

Im CSS-Editor kann eine kontrollierte Farb-Prop direkt gelesen werden:

```css
h1 { color: {{ props.accent }}; }
```

Geben Sie `accent` eine gültige Farbe, z. B. `#2563eb`. Handlebars bietet Ersatz; Das Ergebnis muss weiterhin gültig sein CSS.

## 11. Kommentare, Leerzeichen und literale Klammern

```handlebars
{{! Internal note, omitted from output }}
{{!-- A longer note that can include {{ expressions }} --}}
<span>{{ params.recipient ~}}</span>
```

`~` neben einem Trennzeichen schneidet angrenzende Leerzeichen auf dieser Seite ab. Verwenden Sie es vorsichtig um Wörter herum, die ein Trennzeichen benötigen. Handlebars entfernt seine eigenen Kommentare während der Kompilierung. Tembuilder entfernt auch HTML-Kommentare während der Bereinigung, sodass keiner der Typen im endgültigen Dokument HTML verbleibt.

So zeigen Sie einen wörtlichen Ausdruck an, anstatt ihn auszuwerten:

```handlebars
<p>\{{ params.recipient }}</p>
```

Das Dokument zeigt `{{ params.recipient }}` an. Rohblöcke (`{{{{raw}}}}…{{{{/raw}}}}`) erfordern einen registrierten Blockhelfer; Diese Plattform stellt keinen `raw`-Helfer bereit.

## 12. Partials und andere erweiterte Funktionen

Ein Inline-Teil kann Markup **innerhalb einer kompilierten Quelle** wiederverwenden:

```handlebars
{{#*inline "recipientCard"}}
  <p>{{ name }}</p>
{{/inline}}
{{> recipientCard params.recipient}}
```

Es wird nicht automatisch für Abschnittsdateien, Kopf- oder Fußzeilen freigegeben. `{{> sharedCard}}` benötigt eine Definition; Tembuilder stellt keine Registrierung für benutzerdefinierte globale Partials oder benutzerdefinierte JavaScript-Helfer bereit.

Handlebars unterstützt auch Teilparameter, dynamische Teilauswahl, Teilblöcke und benutzerdefinierte Blockhelfer. Hierbei handelt es sich um Sprachfunktionen, nicht um ein Versprechen von Plattformregistrierungsfunktionen. Fügen Sie keine `registerHelper`-, `registerPartial`- oder Skript-Tags in die Vorlage HTML ein, in der Erwartung, dass sie die Kompilierung konfigurieren.

Der integrierte `log`-Helfer schreibt in das Protokoll der Ausführungsumgebung und nicht in PDF. Bevorzugen Sie Vorschau und Run, um die Ausgabe zu überprüfen. Vermeiden Sie die Protokollierung vertraulicher Laufdaten. Dekoratoren und Zugriff auf Prototypen/Methoden sind für die Dokumentenerstellung nicht erforderlich: Verwenden Sie einfache JSON-Werte und die dokumentierten Hilfsprogramme.

## 13. Vollständiges Abschnittsbeispiel

Erstellen Sie die Abschnittsstütze `heading = "Invoice"` und die Global-Stütze `company = "Tembuilder"`. Deklarieren Sie `recipient` (Objekt mit `name`: Text), `items` (Array von Objekten mit `name`: Text und `quantity`: Zahl), `paid` (Boolescher Wert) und `totalLabel` (Text). Run mit:

```json
{
  "recipient": { "name": "Tembuilder" },
  "items": [{ "name": "Design", "quantity": 2 }],
  "paid": false,
  "totalLabel": "250,000 VND"
}
```

In den Abschnitt HTML einfügen:

```handlebars
<h1>{{ props.heading }}</h1>
<p>{{ global.props.company }} → {{ params.recipient.name }}</p>
<ul>
  {{#each params.items}}
    <li>{{ this.name }} × {{ this.quantity }}</li>
  {{else}}
    <li>No items</li>
  {{/each}}
</ul>
<p>Total: {{ params.totalLabel }}</p>
<p>{{#if params.paid}}Paid{{else}}Awaiting payment{{/if}}</p>
```

Erwarteter Inhalt: **Rechnung**, **Tembuilder → Tembuilder**, **Design × 2**, **Gesamt: 250.000 VND**, **Zahlung ausstehend**. Versuchen Sie es mit einem leeren `items`-Array und `paid: true`, um beide alternativen Zweige in Preview/Run zu überprüfen.

## 14. Regeln zur Fehlerbehebung und KI-Erstellung

| Symptom | Überprüfen |
| --- | --- |
| Leerer Wert | Feldschreibweise, deklarierter Typ, Nutzlast ausführen, aktive Variante und aktueller Kontext. |
| Falscher Wert innerhalb einer Schleife | Verwenden Sie `this`, einen Alias, `../` oder `@root`, um den gewünschten Kontext auszuwählen. |
| Null ausgeblendet | Verwenden Sie `includeZero=true`, wobei Null ein gültiger angezeigter Wert ist. |
| Unerwarteter positiver Zustand | Suchen Sie nach einer Zeichenfolge `"false"` anstelle des booleschen Werts `false`. |
| Kompilierungsfehler | Passen Sie die Eröffnungs-/Schließnamen jedes Blocks an; Entfernen Sie JavaScript-Operatoren und nicht verfügbare Helfer/Teilfunktionen. |
| `[object Object]` | Wählen Sie Objektfelder aus oder iterieren Sie sie, anstatt das gesamte Objekt zu drucken. |

Für KI-Autoren: Behalten Sie deklarierte Feldnamen und -typen bei, verwenden Sie explizite Namespaces, berechnen Sie die Geschäftslogik vor dem Rendern, stellen Sie leere Zustände bereit, behalten Sie das Escapezeichen für gewöhnliche Werte bei und überprüfen Sie Beispiele sowohl anhand aufgefüllter als auch an leeren Daten. Ein fehlender Wert ist kein Beweis für eine erfolgreiche Bindung. Siehe [häufige Fehler](/docs/de/help/common-errors/).

## 15. Offizielle Handlebars-Referenzen

Verwenden Sie den [offiziellen Handlebars-Leitfaden](https://handlebarsjs.com/guide/) für die vollständige Sprachdokumentation. Das oben beschriebene Plattformverhalten hat Vorrang, wenn ein Upstream-Beispiel eine hostseitige Registrierung oder Laufzeitkonfiguration erfordert.

- [Ausdrücke, Escapezeichen, Pfade und Leerzeichen](https://handlebarsjs.com/guide/expressions.html)
- [Eingebaute Helfer](https://handlebarsjs.com/guide/builtin-helpers.html)
- [Schleifen- und Stammdatenvariablen](https://handlebarsjs.com/api-reference/data-variables.html)
- [Partials und Inline-Partials](https://handlebarsjs.com/guide/partials.html)
- [Benutzerdefinierte Blockhelfer](https://handlebarsjs.com/guide/block-helpers.html)
