Liquid begegnet Ihnen in der JTL-Wawi an zwei Stellen: in E-Mail-Vorlagen und in Workflows, etwa als Bedingung oder als Wert, der in ein Feld geschrieben wird. Die Syntax sieht aus wie das Liquid, das man aus Shopify oder aus Tutorials kennt. In der Praxis verhält sie sich aber an einigen Stellen anders – und zwar oft ohne Fehlermeldung. Der Workflow läuft, das Ergebnis ist nur falsch.
Dieser Artikel sammelt die Stolperfallen, die uns im Support am häufigsten begegnen, und zeigt zwei vollständige Rezepte zum Kopieren.
Was Sie wissen sollten: JTL verwendet DotLiquid
Die JTL-Wawi arbeitet mit DotLiquid, einer .NET-Umsetzung von Liquid. Daraus ergeben sich die meisten Eigenheiten:
- Filter folgen der C#-Schreibweise und werden großgeschrieben.
- Nicht jeder Filter und nicht jede Eigenschaft aus anderen Liquid-Varianten steht zur Verfügung.
- Zeilenumbrüche zwischen Tags landen in der Ausgabe – das stört besonders in Workflows, deren Ergebnis verglichen wird.
Testen Sie Liquid-Änderungen immer zuerst an einem einzelnen Testauftrag bzw. mit einer Test-E-Mail an sich selbst, bevor ein Workflow automatisch auf alle Vorgänge losgelassen wird.
Stolperfalle 1: Filter kleingeschrieben
Das ist der Klassiker. Aus Tutorials übernommen, steht im Code:
{% assign strasse = Vorgang.Lieferung.Lieferadresse.Strasse | strip | downcase %}
Das sieht korrekt aus, liefert aber nicht das erwartete Ergebnis: Kleingeschriebene Filter werden in JTL stillschweigend ignoriert. Richtig ist:
{% assign strasse = Vorgang.Lieferung.Lieferadresse.Strasse | Strip | Downcase %}
Dasselbe gilt für die JTL-eigenen Filter in E-Mail-Vorlagen, etwa FormatDate, AddDays, Plus oder Nummer – alle mit großem Anfangsbuchstaben.
Vorsicht bei Beispielen aus Foren oder älteren Vorlagen: Ausdrücke wie | date: "%d.%m.%Y", | round: 2 oder | currency stammen aus anderen Liquid-Varianten. Prüfen Sie solche Zeilen, bevor Sie sich auf die Ausgabe verlassen.
Stolperfalle 2: slice und .size fehlen
Wer prüfen will, ob ein Text auf etwas Bestimmtes endet, greift in Liquid normalerweise zu slice mit negativem Index oder zu .size. Beides hat in JTL-Workflows nicht funktioniert.
Der Ausweg ist ein Marker-Trick: Man hängt an beide Texte dieselbe Endmarke an und prüft mit contains. Wenn „Straße + #ENDE#“ den Text „Leerzeichen + Zusatz + #ENDE#“ enthält, endet die Straße auf genau diesen Zusatz. Das führende Leerzeichen sorgt dafür, dass nur ganze Wörter treffen – „5“ passt dann nicht auf „15“.
Auch einen regulären Ausdruck gibt es nicht. Ob ein Text eine Ziffer enthält, prüft man mit einer Schleife über (0..9) – siehe Rezept 1.
Stolperfalle 3: contains trifft Teilstrings
contains prüft auf Teiltexte. Steht in einer Länderliste DE,AT,…, findet contains auch Codes, die zufällig als Teil eines anderen Eintrags vorkommen. Die Lösung: Liste und Suchbegriff mit Kommas einrahmen, also nach ,DE, statt nach DE suchen. Rezept 2 zeigt das.
Stolperfalle 4: Leerzeilen in der Ausgabe
Jede Zeile mit einem {% assign %}, {% if %} oder {% endif %} erzeugt einen Zeilenumbruch in der Ausgabe. In einer E-Mail fällt das als Leerzeile auf, in einem Workflow ist es schlimmer: Das Ergebnis lautet dann nicht JA, sondern Leerzeilen plus JA – und der Vergleich in der Bedingung schlägt fehl.
In JTL-Workflows unterdrückt ein Backslash \ am Zeilenende den Zeilenumbruch.
Setzen Sie den Backslash nicht hinter das eigentliche Ergebnis, das der Workflow vergleicht. Sonst hängt das \ am Wert, aus JA wird JA\, und die Bedingung greift nie.
In den mitgelieferten E-Mail-Vorlagen der Wawi sehen Sie stattdessen häufig Tags in der Form {% endif -%} mit Bindestrich. Wenn Sie eine Standardvorlage anpassen, behalten Sie diese Schreibweise bei.
Stolperfalle 5: Der falsche Variablenpfad
Ein Liquid-Ausdruck kann syntaktisch einwandfrei sein und trotzdem leer bleiben, weil der Pfad auf der jeweiligen Ebene nicht existiert. Beispiele aus der Praxis:
- In Workflows auf Lieferungs-/Versandebene steht die Lieferadresse unter
Vorgang.Lieferung.Lieferadresse.*. - Auf anderen Ebenen (z. B. Auftrag) liegt die Adresse unter einem anderen Pfad.
- E-Mail-Vorlagen im Format 2.0 arbeiten mit
Report.*; ältere Vorlagen und Beispiele verwenden andere Namen. Auch zwischen Wawi-Versionen haben sich Variablennamen geändert.
Schlagen Sie den Pfad deshalb im Variablenbaum der jeweiligen Vorlage bzw. des Workflow-Objekts nach, statt ihn aus einem Beispiel zu übernehmen.
Stolperfalle 6: Reihenfolge bei der Datumsrechnung
In E-Mail-Vorlagen lässt sich mit Datumswerten rechnen. Wichtig ist die Reihenfolge der Filter: erst AddDays, dann FormatDate. FormatDate macht aus dem Datum einen Text – damit kann AddDays danach nicht mehr rechnen.
{{ Report.DunningInvoice.CreationDate | AddDays: Report.SalesOrder.TermOfPayment | FormatDate: 'dd.MM.yyyy', 'de-DE' }}
Wie Sie damit ein Fälligkeitsdatum in die Mahnung bringen, zeigt unser Artikel Mahnung: Fälligkeitsdatum in der Liquid-Vorlage.
Rezept 1: Hausnummer doppelt im Adresszusatz erkennen
Ein häufiges Problem bei Marktplatz- und Shop-Bestellungen: Der Kunde trägt die Hausnummer zusätzlich in den Adresszusatz ein. Auf dem Versandlabel steht dann „Waldstr. 21 b“ und darunter noch einmal „21 b“. Dieses Liquid erkennt solche Fälle und gibt JA oder NEIN aus:
{% assign strasse = Vorgang.Lieferung.Lieferadresse.Strasse | Strip | Downcase %}\
{% assign zusatz = Vorgang.Lieferung.Lieferadresse.Adresszusatz | Strip | Downcase %}\
{% capture hay %}{{ strasse }}#ENDE#{% endcapture %}\
{% capture probe %} {{ zusatz }}#ENDE#{% endcapture %}\
{% assign hasDigit = false %}\
{% for d in (0..9) %}\
{% capture ds %}{{ d }}{% endcapture %}\
{% if zusatz contains ds %}{% assign hasDigit = true %}{% endif %}\
{% endfor %}\
{% if zusatz != "" and zusatz == strasse %}\
JA
{% elsif zusatz != "" and hasDigit and hay contains probe %}\
JA
{% else %}\
NEIN
{% endif %}
Ergebnis JA in zwei Fällen:
- Der Adresszusatz entspricht der kompletten Straße (Groß-/Kleinschreibung egal).
- Die Straße endet auf Leerzeichen + Adresszusatz, und der Zusatz enthält mindestens eine Ziffer – etwa „Waldstr. 21 b“ / „21 b“ oder „Heidering 28/2“ / „28/2“.
Ergebnis NEIN unter anderem bei reinen Text-Zusätzen ohne Ziffer („Hinterhaus“) und beim umgekehrten Fall: Steht der komplette Straßenname im Zusatz und nur die Nummer im Feld Straße, darf der Zusatz auf keinen Fall gelöscht werden – sonst ist die Adresse zerstört.
Achten Sie darauf, dass hinter JA und NEIN kein Backslash steht. Genau diese Werte vergleicht der Workflow.
Einbau: Bedingung „Liquid-Ergebnis ist gleich JA“, Aktion: Adresszusatz der Lieferadresse auf leer setzen. Weil das Liquid nur exakte Treffer meldet und keine Teilstrings, eignet es sich für eine automatische Korrektur.
Rezept 2: Lieferung in die EU oder in ein Drittland?
Für Zoll-Hinweise, Versandart-Regeln oder Historieneinträge muss ein Workflow oft wissen, ob die Lieferadresse in der EU liegt. Geprüft wird der ISO-Code des Lieferlandes gegen eine Liste der 27 EU-Staaten:
{% assign euCountries = ",DE,AT,BE,BG,HR,CY,CZ,DK,EE,FI,FR,EL,GR,HU,IE,IT,LV,LT,LU,MT,NL,PL,PT,RO,SK,SI,ES,SE," %}\
{% capture countryKey %},{{ Vorgang.Lieferung.Lieferadresse.LandISO }},{% endcapture %}\
{% if euCountries contains countryKey %}\
EU-Lieferung
{% else %}\
Nicht-EU-Lieferung (Drittland)
{% endif %}
Drei Details, auf die es ankommt:
- Kommas um jeden Code und um den Suchbegriff verhindern Teiltreffer.
- Griechenland steht doppelt in der Liste – als
ELund alsGR–, weil beide Kürzel vorkommen. - Der Pfad gilt für Workflows auf Lieferungsebene. Auf anderen Ebenen prüfen Sie den Pfad zum Lieferland im Variablenbaum.
Hinter den beiden Ergebnissen steht bewusst kein Backslash – wie bei Rezept 1. So kommt der Wert exakt als EU-Lieferung bzw. Nicht-EU-Lieferung (Drittland) an und lässt sich in einer Bedingung vergleichen.
Die Stolperfallen auf einen Blick
| Symptom | Ursache | Lösung |
|---|---|---|
| Filter scheint nichts zu tun, keine Fehlermeldung | Filter kleingeschrieben (strip, downcase) |
C#-Schreibweise: Strip, Downcase |
Ends-with-Prüfung mit slice liefert nichts |
slice mit negativem Index und .size gehen nicht |
Marker-Trick mit capture und contains |
contains meldet falsche Treffer |
Teilstring-Treffer | Liste und Suchwert mit Kommas einrahmen |
| Bedingung greift nie, obwohl das Ergebnis stimmt | Leerzeilen vor dem Ergebnis | \ am Ende jeder Tag-Zeile |
Ergebnis lautet JA\ statt JA |
Backslash hinter dem Ergebniswert | Hinter dem verglichenen Wert kein \ |
| Ausdruck bleibt leer | Variablenpfad passt nicht zur Ebene oder zum Vorlagenformat | Pfad im Variablenbaum nachschlagen |
| Datumsrechnung liefert Unsinn oder nichts | FormatDate vor AddDays |
Erst AddDays, dann FormatDate |
Liquid in der JTL-Wawi ist mächtig, verzeiht aber wenig – vor allem, weil viele Fehler keine Meldung erzeugen. Wenn ein Workflow nicht tut, was er soll, oder eine Vorlage angepasst werden muss, unterstützen wir Sie als JTL-Servicepartner gern dabei.
Häufige Fragen
Warum wirkt mein Filter wie strip oder downcase in JTL-Wawi nicht?
JTL-Wawi verwendet DotLiquid mit C#-Schreibweise. Filter müssen großgeschrieben werden, also Strip und Downcase. Kleingeschriebene Filter werden ohne Fehlermeldung ignoriert.
Wie verhindere ich Leerzeilen in der Ausgabe eines Workflow-Liquids?
Setzen Sie einen Backslash ans Ende jeder Zeile mit einem Liquid-Tag. Er unterdrückt den Zeilenumbruch. Hinter dem eigentlichen Ergebnis, das der Workflow vergleicht, sollte er nicht stehen.
Gibt es slice oder .size in JTL-Liquid?
In unseren Tests haben slice mit negativem Index und .size nicht funktioniert. Prüfungen wie „endet auf …“ lassen sich stattdessen mit capture, einem Marker-Text und contains nachbauen.
Kann ich Liquid-Beispiele aus dem Netz direkt übernehmen?
Meist nicht ohne Anpassung. Viele Beispiele sind für Shopify-Liquid mit kleingeschriebenen Filtern geschrieben, und die Variablennamen hängen von Vorlagenformat und Wawi-Version ab.