Handlebars-Helper – Vollständige Referenz
In Pantarey werden Handlebars-Vorlagen an mehreren Stellen eingesetzt – z. B. bei der PDF-Erstellung, bei Textvorlagen oder in externen Aufgaben. Alle Vorlagen haben Zugriff auf dieselben Helper-Funktionen, mit denen sich Daten direkt im Template formatieren, berechnen und aufbereiten lassen.
So können Rechnungen, Berichte und Benachrichtigungen professionell gestaltet werden, ohne zusätzliche Prozessschritte.
Wo werden Handlebars-Vorlagen verwendet?
| Einsatzbereich | Service / Funktion |
|---|---|
| PDF-Dokumente | PDF aus Handlebars-Template erstellen |
| Texte generieren | Text aus Handlebars-Template erstellen |
| E-Mails aus Vorlage | E-Mail aus Handlebars-Template (Microsoft Graph) |
| Externe Aufgaben | Externer User Task – HTML-Vorlagen |
Grundlagen
Handlebars-Platzhalter werden mit doppelten geschweiften Klammern geschrieben:
<p>Kunde: {{kundenname}}</p>
<p>Betrag: {{currency_eur rechnungsbetrag}}</p>
Die Werte kommen aus dem content-Objekt, das beim Aufruf des Service Tasks übergeben wird.
Dreifache Klammern für HTML
Standardmäßig escaped Handlebars HTML-Sonderzeichen. Wenn der Ausgabewert HTML enthält (z. B. bei qrCode oder htmlify), müssen dreifache Klammern {{{ }}} verwendet werden.
Datum und Uhrzeit
| Helper | Beschreibung | Beispiel | Ergebnis |
|---|---|---|---|
dateTimeFormat |
Datum/Zeit formatieren (ISO → lokalisiert) | {{dateTimeFormat erstelldatum "de-DE" "Europe/Berlin"}} |
22.12.2024, 11:30 |
dateTimeFormatWithSettings |
Datum/Zeit mit erweiterten Optionen | {{dateTimeFormatWithSettings datum "de-DE" "Europe/Berlin"}} |
22.12.2024, 11:30 |
toGermanDate |
ISO-Datum → deutsches Format | {{toGermanDate "2025-01-15"}} |
15.01.2025 |
currentDate |
Heutiges Datum | {{currentDate "de-DE" "Europe/Berlin"}} |
08.04.2026 |
currentDateTime |
Heutiges Datum + Uhrzeit | {{currentDateTime "de-DE" "Europe/Berlin"}} |
08.04.2026, 14:30 |
addDaysToCurrentDate |
Tage zum heutigen Datum addieren | {{addDaysToCurrentDate 14}} |
22.04.2026 |
month_name |
Monatsname aus Datum | {{month_name "2025-03-15"}} |
März |
year |
Jahreszahl aus Datum | {{year "2025-03-15"}} |
2025 |
Beispiel – Zahlungsfrist:
<p>Rechnungsdatum: {{toGermanDate rechnungsdatum}}</p>
<p>Zahlbar bis: {{addDaysToCurrentDate 30}}</p>
Zahlen und Währung
| Helper | Beschreibung | Beispiel | Ergebnis |
|---|---|---|---|
currency_eur |
Euro-Formatierung | {{currency_eur 1234.56}} |
1.234,56 € |
currency_dollar |
Dollar-Formatierung | {{currency_dollar 1234.56}} |
$1,234.56 |
numberFormat |
Zahl mit Tausender-Trennzeichen | {{numberFormat 50000}} |
50.000 |
multiply |
Multiplikation | {{multiply preis menge}} |
|
add |
Addition | {{add wert1 wert2}} |
|
round |
Runden auf Dezimalstellen | {{round 3.14159 2}} |
3.14 |
Beispiel – Rechnungsposition:
<td>{{numberFormat menge}} Stk.</td>
<td>{{currency_eur einzelpreis}}</td>
<td>{{currency_eur (multiply einzelpreis menge)}}</td>
Bedingungen
Bedingungs-Helper sind Block-Helper – sie umschließen den Inhalt, der nur bei erfüllter Bedingung angezeigt wird.
| Helper | Beschreibung | Beispiel |
|---|---|---|
ifEquals |
Gleichheit prüfen | {{#ifEquals status "approved"}}Genehmigt{{/ifEquals}} |
greaterThan |
Größer als | {{#greaterThan betrag 1000}}Großauftrag{{/greaterThan}} |
lessThan |
Kleiner als | {{#lessThan betrag 100}}Kleinbetrag{{/lessThan}} |
greaterOrEqualThan |
Größer oder gleich | {{#greaterOrEqualThan punkte 50}}Bestanden{{/greaterOrEqualThan}} |
lessOrEqualThan |
Kleiner oder gleich | {{#lessOrEqualThan lagerbestand 10}}Nachbestellen{{/lessOrEqualThan}} |
Alle Bedingungs-Helper unterstützen einen {{else}}-Block:
{{#greaterThan betrag 1000}}
<span class="highlight">Großauftrag</span>
{{else}}
<span>Standardauftrag</span>
{{/greaterThan}}
Text und Formatierung
| Helper | Beschreibung | Beispiel |
|---|---|---|
replace |
Text ersetzen | {{replace firmenname "GmbH" "AG"}} |
htmlify |
Zeilenumbrüche → <br>, Seitenumbrüche → Page Break |
{{{htmlify beschreibung}}} |
renderString |
Handlebars-Ausdruck innerhalb eines Strings auswerten | {{{renderString dynamischerText this}}} |
buildString |
Strings zusammensetzen (z. B. als Sub-Expression) | {{{qrCode (buildString "BCD\n" bic "\n" name)}}} |
htmlify im Detail
Der htmlify-Helper wandelt Fließtext in HTML um:
- Zeilenumbrüche (
\n) werden zu<br> <pagebreak>wird zu einem Seitenumbruch (für PDFs)
<div>{{{htmlify freitextfeld}}}</div>
Dreifache Klammern
htmlify und renderString geben HTML zurück – immer {{{ }}} verwenden.
Listen und Paginierung
| Helper | Beschreibung | Beispiel |
|---|---|---|
concat |
Arrays zusammenführen | {{#each (concat listeA listeB)}}...{{/each}} |
sortBy |
Array sortieren | {{#each (sortBy positionen "preis")}}...{{/each}} |
paginate |
Array in Seiten aufteilen | {{#paginate positionen 10}}...{{/paginate}} |
Der concat-Helper führt beliebig viele Listen zu einer zusammen. Leere Werte werden übersprungen, einzelne Objekte oder Zahlen dürfen ebenfalls übergeben werden. In Kombination mit sortBy lassen sich getrennt gepflegte Listen gemeinsam und in einer definierten Reihenfolge ausgeben.
sortBy im Detail
Der sortBy-Helper gibt eine sortierte Kopie zurück – die Originaldaten bleiben unverändert. Zahlenwerte werden numerisch verglichen, alles andere alphabetisch.
| Aufruf | Wirkung |
|---|---|
{{sortBy positionen "preis"}} |
nach dem Feld preis, aufsteigend |
{{sortBy standorte}} |
flache Liste ohne Feldnamen, z. B. ["Berlin", "Aachen"] |
{{sortBy positionen "preis" dir="desc"}} |
absteigend |
{{sortBy positionen "kategorie" "preis"}} |
mehrere Felder – das zweite entscheidet nur bei Gleichstand |
{{sortBy positionen "kategorie" "-preis"}} |
ein Minuszeichen dreht die Richtung für dieses eine Feld um |
{{sortBy kunden "adresse.ort"}} |
verschachteltes Feld in Punktschreibweise |
{{sortBy positionen "lieferdatum" nullsLast=true}} |
leere Werte ans Ende statt an den Anfang |
Beispiel – Rechnungsposten aus zwei Listen zusammenführen und ordnen:
{{#each (sortBy (concat app_invoice_items_custom app_invoice_items_articles) "app_invoice_item_no")}}
<tr>
<td>{{this.app_invoice_item_no}}</td>
<td>{{this.app_description}}</td>
<td>{{currency_eur this.app_price}}</td>
</tr>
{{/each}}
paginate im Detail
Der paginate-Helper teilt ein Array in gleich große Abschnitte auf – ideal für mehrseitige PDFs, bei denen z. B. nur 10 Positionen pro Seite angezeigt werden sollen.
{{#paginate positionen 10}}
<div class="seite">
<h2>Seite {{add pageIndex 1}}</h2>
<table>
{{#each slice}}
<tr>
<td>{{this.bezeichnung}}</td>
<td>{{currency_eur this.betrag}}</td>
</tr>
{{/each}}
</table>
</div>
{{/paginate}}
Innerhalb des Blocks stehen zur Verfügung:
slice– die Einträge der aktuellen SeitepageIndex– der Seitenindex (beginnt bei 0)
QR-Code
| Helper | Beschreibung | Beispiel |
|---|---|---|
qrCode |
QR-Code als Data-URL erzeugen | <img src="{{{qrCode zahlungslink}}}" width="200" /> |
buildString |
Strings zusammenbauen (z. B. für strukturierte QR-Daten) | {{{qrCode (buildString "BCD\n" bic "\n" name)}}} |
QR-Codes werden als Base64-Data-URL erzeugt und direkt in ein <img>-Tag eingebettet. Die Gestaltung (Größe, Position) wird über HTML/CSS gesteuert.
Optionen
| Option | Standard | Beschreibung |
|---|---|---|
width |
200 |
Bildbreite in Pixel |
margin |
1 |
Rand um den QR-Code (in Modulen) |
errorCorrectionLevel |
"M" |
Fehlerkorrektur: "L", "M", "Q" oder "H" |
<img src="{{{qrCode produktUrl width=300 margin=2 errorCorrectionLevel="H"}}}" width="300" />
GiroCode-Beispiel (Zahlungs-QR-Code)
Der GiroCode (EPC-QR-Code) ermöglicht es, Überweisungsdaten direkt in Banking-Apps zu scannen. Der Aufbau folgt einem festen Zeilenformat:
<img src="{{{qrCode (buildString
"BCD\n001\n1\nSCT\n"
bic "\n"
empfaengerName "\n"
iban "\nEUR"
betrag "\n\n\nRechnung "
rechnungsnummer
) width=250 errorCorrectionLevel="M"}}}" width="250" />
Dreifache Klammern erforderlich
qrCode gibt eine Data-URL zurück, die data:image/png;base64,... enthält. Mit doppelten Klammern {{ }} würde das Ergebnis HTML-escaped und das Bild nicht angezeigt.
Praxisbeispiel: Rechnung
Das folgende Beispiel zeigt eine vollständige Rechnungsvorlage mit Kopfbereich, Positionstabelle, Summen, Zahlungs-QR-Code und bedingtem Hinweis:
<html>
<body>
<h1>Rechnung {{rechnungsnummer}}</h1>
<p>Datum: {{toGermanDate rechnungsdatum}}</p>
<p>Kunde: {{kundenname}}</p>
<table>
<thead>
<tr>
<th>Bezeichnung</th>
<th>Menge</th>
<th>Einzelpreis</th>
<th>Gesamt</th>
</tr>
</thead>
<tbody>
{{#each positionen}}
<tr>
<td>{{this.bezeichnung}}</td>
<td>{{numberFormat this.menge}}</td>
<td>{{currency_eur this.einzelpreis}}</td>
<td>{{currency_eur (multiply this.einzelpreis this.menge)}}</td>
</tr>
{{/each}}
</tbody>
</table>
<p><strong>Nettobetrag:</strong> {{currency_eur nettobetrag}}</p>
<p><strong>MwSt. 19 %:</strong> {{currency_eur (multiply nettobetrag 0.19)}}</p>
<p><strong>Gesamtbetrag:</strong> {{currency_eur bruttobetrag}}</p>
{{#greaterThan bruttobetrag 500}}
<p><em>Bitte überweisen Sie den Betrag innerhalb von 14 Tagen.</em></p>
{{/greaterThan}}
<div style="margin-top: 20px;">
<p>Scannen für Überweisung:</p>
<img src="{{{qrCode (buildString "BCD\n001\n1\nSCT\n" bic "\n" firmenname "\n" iban "\nEUR" bruttobetrag "\n\n\nRechnung " rechnungsnummer)}}}" width="200" />
</div>
<footer>
<p>Erstellt am {{currentDate "de-DE" "Europe/Berlin"}}</p>
</footer>
</body>
</html>
Zusammenfassung aller Helper
| Helper | Kategorie | Dreifache Klammern nötig |
|---|---|---|
dateTimeFormat |
Datum | Nein |
dateTimeFormatWithSettings |
Datum | Nein |
toGermanDate |
Datum | Nein |
currentDate |
Datum | Nein |
currentDateTime |
Datum | Nein |
addDaysToCurrentDate |
Datum | Nein |
month_name |
Datum | Nein |
year |
Datum | Nein |
currency_eur |
Zahlen | Nein |
currency_dollar |
Zahlen | Nein |
numberFormat |
Zahlen | Nein |
multiply |
Zahlen | Nein |
add |
Zahlen | Nein |
round |
Zahlen | Nein |
ifEquals |
Bedingung | Nein |
greaterThan |
Bedingung | Nein |
lessThan |
Bedingung | Nein |
greaterOrEqualThan |
Bedingung | Nein |
lessOrEqualThan |
Bedingung | Nein |
replace |
Text | Nein |
htmlify |
Text | Ja |
renderString |
Text | Ja |
buildString |
Text | — (Sub-Expression) |
concat |
Listen | Nein |
sortBy |
Listen | Nein |
paginate |
Listen | Nein |
qrCode |
QR-Code | Ja |