Zum Inhalt springen

oneVcard Template-Engine


An ausgewählten Stellen steht dir die oneVcard Template-Engine zur Verfügung. Dadurch kannst du deinen Inhalt mit dynamischen Daten aufbereiten.

Einfache Platzhalter

Ein Feldname in doppelten geschwungenen Klammern wird durch den zugehörigen Wert ersetzt.

{{placeholder}}

Beispiel:

Daten:

{ "firstName": "Max", "lastName": "Mustermann" }

Vorlage:

Hallo {{firstName}} {{lastName}}!

Ergebnis:

Hallo Max Mustermann!

Fehlende Werte

Wenn ein Platzhalter keinen Wert in den Daten findet, wird er durch einen leeren String ersetzt.

Hallo {{name}}! → Hallo !

Pfadauflösung

Platzhalter können auf verschachtelte Felder in Objekten und Arrays zugreifen.

Verschachtelte Objekte

Verwende einen Punkt (.) als Trennzeichen:

{{user.address.city}}

Daten:

{
"user": {
"address": {
"city": "München"
}
}
}

Ergebnis: München

Arrays per Index

Arrays werden per nullbasiertem Index angesprochen:

{{contacts[0].name}}
{{contacts[1].email}}

Daten:

{
"contacts": [
{ "name": "Anna", "email": "anna@example.com" },
{ "name": "Bob", "email": "bob@example.com" }
]
}

Ergebnis: Anna / bob@example.com

Array-Filter

Du kannst ein Array nach einem bestimmten Feld filtern und dann auf das Ergebnis zugreifen:

{{contacts(type=billing_address)[0].name}}

Das filtert das contacts-Array nach allen Einträgen, bei denen type === "billing_address" ist und liefert den ersten Treffer.

Optionale Blöcke

Optionale Blöcke werden in doppelten eckigen Klammern geschrieben: [[ ... ]]

[[Straße: {{address.street}}]]
[[PLZ: {{address.zipCode}}]]

Daten:

{ "address": { "street": "Musterstraße 1" } }

Ergebnis:

Straße: Musterstraße 1

Der PLZ-Block fehlt komplett, weil address.zipCode nicht vorhanden ist.

Mehrere Platzhalter in einem Block

Alle Platzhalter im Block müssen vorhanden sein, damit der Block ausgegeben wird:

[[{{firstName}} {{lastName}}]]

Nur wenn beide Felder vorhanden sind, erscheint der Block.

Bedingungen

Mit Bedingungen kannst du Inhalte abhängig von den Daten ein- oder ausblenden.

Grundstruktur

{#if condition}
Content
{/if}
{#if condition}
Content
{:else}
Fallback
{/if}
{#if condition1}
Content 1
{:else if condition2}
Content 2
{:else}
Fallback
{/if}

Wahrheitswerte (Truthy/Falsy)

Wenn du einfach auf das Vorhandensein oder den Wahrheitswert eines Feldes prüfst:

WertErgebnis
true, "true", nicht-leerer Stringwahr
nicht-leeres Arraywahr
false, "false", 0, ""falsch
fehlendes / null / undefinedfalsch
{#if user.active}Konto ist aktiv{:else}Konto gesperrt{/if}

Vergleichsoperatoren

OperatorBedeutung
==gleich
!=ungleich
>größer als
<kleiner als
>=größer oder gleich
<=kleiner oder gleich
{#if user.age >= 18}Volljährig{:else}Minderjährig{/if}
{#if user.role == 'admin'}Administratorzugriff{/if}
{#if status != 'gesperrt'}Zugang erlaubt{/if}

Strings in Bedingungen werden in einfache oder doppelte Anführungszeichen gesetzt:

{#if country == "DE"}Willkommen in Deutschland{/if}
{#if country == 'AT'}Willkommen in Österreich{/if}

Logische Operatoren

Bedingungen können mit && (UND) und || (ODER) verknüpft werden:

{#if active && age >= 18}Zugriff erlaubt{/if}
{#if role == 'admin' || role == 'manager'}Verwaltung{/if}
{#if a || b || c}Mindestens eines trifft zu{/if}

Klammerung

Verwende Klammern, um die Auswertungsreihenfolge festzulegen:

{#if (role == 'admin' || role == 'editor') && active}Aktiver Redakteur{/if}
{#if age >= 18 && (member || promo)}Rabatt verfügbar{/if}

Block-Funktionen

Block-Funktionen umschließen einen Inhalt und transformieren oder steuern dessen Ausgabe.

{{#function attribute="value"}}
Inhalt
{{/function}}

join

Verbindet mehrere optionale Blöcke mit einem Trennzeichen. Blöcke, deren Platzhalter keinen Wert haben, werden automatisch übersprungen.

Attribute:

AttributBeschreibungStandard
delimiterTrennzeichen zwischen den Blöcken""
prefixText vor dem Ergebnis""
suffixText nach dem Ergebnis""

Beispiel - Adresszeile:

{{#join delimiter=", "}}
[[{{street}}]]
[[{{zipCode}} {{city}}]]
[[{{country}}]]
{{/join}}

Daten:

{ "street": "Musterstraße 1", "city": "München" }

Ergebnis: Musterstraße 1, München

zipCode und city fehlen. Ihre Blöcke werden übersprungen, keine doppelten Kommas.

Beispiel - mit Prefix und Suffix:

{{#join delimiter=" · " prefix="[" suffix="]"}}
[[{{tag1}}]][[{{tag2}}]][[{{tag3}}]]
{{/join}}

Daten:

{ "tag1": "Rechnung", "tag3": "Dringend" }

Ergebnis: [Rechnung · Dringend]

Zeilenumbruch als Trennzeichen:

Verwende \n für einen Zeilenumbruch:

{{#join delimiter="\n"}}[[{{line1}}]][[{{line2}}]][[{{line3}}]]{{/join}}

uppercase

Wandelt den gesamten Inhalt in Großbuchstaben um.

{{#uppercase}}{{salutation}} {{lastName}}{{/uppercase}}

Daten:

{ "salutation": "Herr", "lastName": "Müller" }

Ergebnis: HERR MÜLLER

format

Formatiert einen Wert nach einem bestimmten Stil.

Attribute:

AttributBeschreibung
styleFormatierungsstil: "phoneNumber" oder "date"

Telefonnummer formatieren (style="phoneNumber")

Formatiert eine Telefonnummer in das internationale Format.

AttributBeschreibungStandard
countryLändercode (ISO 3166-1) für Nummern ohne Vorwahlkeiner
{{#format style="phoneNumber"}}{{phoneNumber}}{{/format}}

Nummern mit internationalem Prefix (+49, +1, +44, …) werden automatisch korrekt dem jeweiligen Land zugeordnet, kein country-Attribut nötig:

+491782367141 → +49 178 2367141
+12025550123 → +1 202 555 0123
+447911123456 → +44 7911 123456

Nummern ohne Prefix benötigen das country-Attribut:

{{#format style="phoneNumber" country="DE"}}{{phoneNumber}}{{/format}}
089123456 → +49 89 123456

Kann die Nummer nicht geparst werden, wird der ursprüngliche Wert unverändert ausgegeben.

Datum formatieren (style="date")

Formatiert ein Datum nach einem Pattern oder einer Sprache.

AttributBeschreibungStandard
patternAusgabeformat (Token-Pattern, siehe unten)Locale-abhängig
localeSprach-/Regionsformat für die Ausgabe ohne pattern"de-DE"
inputFormatEingabeformat, wenn der Wert kein ISO-Datum ist (Token-Pattern)automatisch
Pattern-Tokens
TokenBeschreibungBeispiel
yyyy4-stelliges Jahr2025
yy2-stelliges Jahr25
MMMonat (2-stellig)06
ddTag (2-stellig)15
HHStunde (24h, 2-stellig)14
mmMinute (2-stellig)30
ssSekunde (2-stellig)00
MMMMMonatsname (ausgeschrieben)Juni
EEEWochentag (kurz)Mo.
EEEEWochentag (ausgeschrieben)Montag

Beispiele:

{{#format style="date" pattern="dd.MM.yyyy"}}{{createdAt}}{{/format}}

Eingabe: 2025-06-15 → Ausgabe: 15.06.2025

{{#format style="date" pattern="dd.MM.yyyy HH:mm"}}{{createdAt}}{{/format}}

Eingabe: 2025-06-15T14:30:00 → Ausgabe: 15.06.2025 14:30

{{#format style="date" pattern="EEEE, dd. MMMM yyyy" locale="de-DE"}}{{date}}{{/format}}

Eingabe: 2025-06-15 → Ausgabe: Sonntag, 15. Juni 2025

Eingabe mit Custom-Format (inputFormat)

Wenn deine Daten kein ISO-Datum enthalten, sondern z. B. 15.06.2025, nutze inputFormat:

{{#format style="date" inputFormat="dd.MM.yyyy" pattern="yyyy-MM-dd"}}{{date}}{{/format}}

Eingabe: 15.06.2025 → Ausgabe: 2025-06-15

Eingaben werden in dieser Reihenfolge geparst:

  1. Custom inputFormat (wenn angegeben)
  2. ISO 8601 (2025-06-15 oder 2025-06-15T14:30:00Z)
  3. Unix-Timestamp in Millisekunden

replace

Ersetzt alle Vorkommen eines Textes durch einen anderen.

Attribute:

AttributBeschreibung
fromDer zu ersetzende Text
toDer Ersatztext
{{#replace from="GmbH" to="AG"}}{{company}}{{/replace}}

Daten:

{ "company": "Muster GmbH" }

Ergebnis: Muster AG

Text löschen (Ersatz durch leeren String):

{{#replace from=" " to=""}}{{productCode}}{{/replace}}

Eingabe: AB 1234 CD → Ausgabe: AB1234CD

each

Iteriert über ein Array oder ein Objekt und gibt den Inhalt für jedes Element aus.

Attribute:

AttributBeschreibungStandard
dataPfad zum Array oder Objekt-
asName der Loop-Variableentry

Array von Objekten

{{#each data=users as="user"}}
- {{user.firstName}} {{user.lastName}}
{{/each}}

Daten:

{
"users": [
{ "firstName": "Anna", "lastName": "Schmidt" },
{ "firstName": "Bob", "lastName": "Müller" }
]
}

Ergebnis:

- Anna Schmidt
- Bob Müller

Bedingungen innerhalb von each

Du kannst {#if} innerhalb von {{#each}} verwenden. Die Bedingung wird mit den Daten des aktuellen Elements ausgewertet:

{{#each data=users as="user"}}
{#if user.active}✓ {{user.firstName}}{:else}✗ {{user.firstName}}{/if}
{{/each}}

Optionale Blöcke innerhalb von each

Optionale Blöcke [[ ]] funktionieren ebenfalls innerhalb des Loops:

{{#each data=contacts as="k"}}
[[{{k.firstName}} {{k.lastName}}]]
{{/each}}

Nur Kontakte, bei denen beide Felder vorhanden sind, erscheinen in der Ausgabe.

Objekte iterieren

Bei Objekten wird jedes Schlüssel-Wert-Paar als zweiteiliges Element übergeben:

  • entry.0 → der Schlüssel
  • entry.1 → der Wert
{{#each data=properties as="e"}}
{{e.0}}: {{e.1}}
{{/each}}

Daten:

{ "properties": { "color": "Blau", "size": "XL" } }

Ergebnis:

color: Blau
size: XL

Zugriff auf äußere Daten

Innerhalb des Loops hast du auch Zugriff auf alle Felder außerhalb des Arrays:

{{#each data=articles as="a"}}
{{a.name}} - Währung: {{currency}}
{{/each}}

Pipe-Syntax

Die Pipe-Syntax ist eine kompaktere Alternative zu Block-Funktionen, wenn du einen einzelnen Wert transformieren möchtest. Mehrere Pipes können hintereinandergeschaltet werden.

{{placeholder | function}}
{{placeholder | function(attribute="value")}}
{{placeholder | function1 | function2}}

Verfügbare Pipe-Funktionen

FunktionBeschreibung
uppercaseWandelt in Großbuchstaben um
format(...)Formatiert (Datum, Telefonnummer)
replace(...)Ersetzt Text

Beispiele:

{{name | uppercase}}

max mustermannMAX MUSTERMANN

{{phoneNumber | format(style="phoneNumber")}}

+491782367141+49 178 2367141

{{date | format(style="date" pattern="dd.MM.yyyy")}}

2025-06-1515.06.2025

{{articleName | replace(from=" " to="_") | uppercase}}

Artikel NameARTIKEL_NAME

Pipes in optionalen Blöcken

Pipes funktionieren auch innerhalb von [[ ]]-Blöcken. Die Block-Gültigkeit richtet sich dabei nach dem Quellwert, nicht nach dem formatierten Ergebnis:

[[{{phoneNumber | format(style="phoneNumber")}}]]

Der Block wird weggelassen, wenn phoneNumber fehlt oder leer ist, unabhängig davon, was die Formatierung zurückgeben würde.

Attribute in Pipe-Funktionen

Wie bei Block-Funktionen kannst du Attribute benannt oder positionell übergeben (mehr dazu in Attribute - benannt vs. positionell):

{{date | format(style="date" pattern="dd.MM.yyyy")}} ← benannt
{{date | format("date" pattern="dd.MM.yyyy")}} ← style positionell
{{text | replace("old", "new")}} ← beide positionell

Globale Variablen

Das System stellt einige eingebaute Variablen unter dem Präfix g. zur Verfügung.

g.now - Aktuelles Datum und Uhrzeit

g.now liefert das aktuelle Datum und die aktuelle Uhrzeit zum Zeitpunkt der Template-Auswertung.

Ausgabe formatieren:

{{g.now | format(style="date" pattern="dd.MM.yyyy")}}

Ausgabe: 17.04.2026

{{g.now | format(style="date" pattern="dd.MM.yyyy HH:mm")}}

Ausgabe: 17.04.2026 09:45

In Bedingungen verwenden (mehr dazu im nächsten Kapitel):

{#if g.now < "2025-12-31"}Aktion läuft noch{:else}Aktion beendet{/if}

Datumsvergleiche

Datumswerte können direkt in Bedingungen verglichen werden. Das System erkennt ISO-8601-Datumsstrings automatisch und vergleicht sie korrekt als Zeitpunkte, nicht als Zeichenketten.

Unterstützte Datumsformate in Bedingungen

FormatBeispiel
ISO-Datum"2025-12-31"
ISO-Datum mit Uhrzeit"2025-12-31T23:59:59"
ISO-Datum mit Zeitzone"2025-12-31T23:59:59Z"

Beispiele

Aktionszeitraum prüfen:

{#if g.now >= "2025-01-01" && g.now <= "2025-12-31"}
Aktion 2025 ist aktiv
{/if}

Ablaufdatum aus den Daten prüfen:

{#if contract.validUntil >= g.now}
Vertrag ist gültig
{:else}
Vertrag ist abgelaufen
{/if}

Zwei Datumsfelder miteinander vergleichen:

{#if delivery.arrival < delivery.planned}
Frühzeitig geliefert
{:else if delivery.arrival == delivery.planned}
Pünktlich geliefert
{:else}
Verspätet
{/if}

Attribute - benannt vs. positionell

Attribute in Block-Funktionen und Pipes können auf zwei Arten angegeben werden.

Benannte Attribute

Der Attributname wird explizit angegeben. Reihenfolge spielt keine Rolle.

{{#format style="date" pattern="dd.MM.yyyy"}}{{date}}{{/format}}
{{#format pattern="dd.MM.yyyy" style="date"}}{{date}}{{/format}} ← gleichwertig

Positionelle Attribute

Der Wert wird in Anführungszeichen ohne Schlüsselname angegeben. Die Reihenfolge legt fest, welchem Parameter der Wert zugeordnet wird.

{{#format "phoneNumber"}}{{phoneNumber}}{{/format}}
{{#format "date" pattern="dd.MM.yyyy"}}{{date}}{{/format}}

Positionelle Attribute können mit benannten gemischt werden. Benannte Attribute haben immer Vorrang.

Positionelle Reihenfolge je Funktion

FunktionPosition 0Position 1Position 2
formatstylelocale / countrypattern
replacefromto-

Kurzschreibweise (Pipe):

{{phoneNumber | format("phoneNumber")}}
{{date | format("date" pattern="dd.MM.yyyy")}}
{{text | replace("old", "new")}}

Bekannte Limitierungen

Verschachtelte {{#each}}-Blöcke

Mehrere ineinander verschachtelte {{#each}}-Blöcke werden aktuell nicht unterstützt. Nur die äußerste Ebene wird korrekt verarbeitet.

{{#each data=categories as="cat"}}
{{#each data=cat.articles as="art"}} ← funktioniert nicht
{{art.name}}
{{/each}}
{{/each}}

{#if} außerhalb von {{#each}}-Inhalt

Wenn eine Bedingung auf Felder verweist, die nur innerhalb eines {{#each}}-Loops existieren, muss die Bedingung innerhalb des {{#each}}-Blocks stehen, was unterstützt wird. Bedingungen, die Loop-Variablen von außen referenzieren, sind nicht möglich.

Schnellreferenz

Syntax-Übersicht

SyntaxBeschreibung
{{field}}Einfacher Platzhalter
{{obj.field}}Verschachteltes Feld
{{arr[0].field}}Array-Zugriff per Index
{{arr(key=val)[0].field}}Array-Filter
[[...{{field}}...]]Optionaler Block (weggelassen wenn leer)
{#if cond}...{/if}Bedingung
{#if cond}...{:else}...{/if}Bedingung mit Else
{#if cond}...{:else if cond2}...{:else}...{/if}Mehrfach-Bedingung
{{#join delimiter=","}}...{{/join}}Blöcke verbinden
{{#uppercase}}...{{/uppercase}}Großschreibung
{{#format style="date" pattern="..."}}...{{/format}}Datumsformatierung
{{#format style="phoneNumber"}}...{{/format}}Telefonnummer-Formatierung
{{#replace from="x" to="y"}}...{{/replace}}Text ersetzen
{{#each data=list as="item"}}...{{/each}}Schleife
{{field | function}}Pipe
{{field | function | function2}}Pipe-Kette
g.nowAktuelles Datum/Uhrzeit

Vergleichsoperatoren

OperatorBedeutung
==gleich
!=ungleich
>größer als
<kleiner als
>=größer oder gleich
<=kleiner oder gleich
&&logisches UND
||logisches ODER

Datumstoken (Auswahl)

TokenAusgabe
yyyy2025
MM06
dd15
HH:mm14:30
dd.MM.yyyy15.06.2025
MMMM yyyyJuni 2025
EEEE, dd. MMMM yyyySonntag, 15. Juni 2025