Bedingtes Spintax: {?VAR?then|else}
Manchmal ist die Wahl zwischen zwei Formulierungen kein Münzwurf — sie hängt an einem Fakt. Das Produkt hat einen kostenlosen Tarif, oder eben nicht. Der Händler nimmt Kryptowährung, oder nur klassisches Geld. Bedingtes Spintax ist das wertgesteuerte Gegenstück zum Aufzählungszweig {a|b}: Statt zufällig zu wählen, entscheidet es danach, ob eine Variable truthy ist.
Die drei Formen
Die bedingte Syntax ergänzt die GTW-Spintax-Familie um drei Tokens. Alle drei werden ausgewertet, bevor Aufzählungen und Permutationen auflösen — sie sind ein Vorlauf, keine Verzweigung zur Laufzeit.
| Form | Bedeutung |
|---|---|
{?VAR?then} |
Rendert then, wenn %VAR% truthy ist; sonst nichts. |
{?VAR?then|else} |
Rendert then bei truthy und else bei falsy. |
{?!VAR?then[|else]} |
Umgekehrt: rendert then, wenn %VAR% falsy ist. |
Das Präfix ! dreht die Prüfung um. Eine eigene Form {?VAR??else} gibt es nicht — wollen Sie nur den Falsy-Zweig, schreiben Sie {?!VAR?else}.
Truthy und falsy
Die Truthy-Regel ist bewusst einfacher als die von JavaScript. Sie sollen sich keine Sonderfälle der Typumwandlung merken müssen.
Wert von %VAR% | Truthy? |
|---|---|
| gar nicht deklariert | falsy |
leerer String "" | falsy |
| nur Leerraum (Leerzeichen, Tabs, Zeilenumbrüche) | falsy |
"0" | truthy (die String-Null ist nicht leer) |
"false" | truthy (immer noch ein nicht leerer String) |
"x", "<p>…</p>", rohes Spintax | truthy |
Das ist die ganze Regel. Truthy = mindestens ein Zeichen, das kein Leerraum ist. Brauchen Sie einmal eine Truthiness im JavaScript-Sinn, machen Sie diese Prüfung im Assembler, bevor Sie die Variable übergeben.
Die Truthiness liest den rohen Wert
Nachgeschlagen wird der roh gespeicherte Wert der Variablen. Verschachtelte %var%-Referenzen in diesem Wert werden für die Truthy-Prüfung nicht aufgelöst — das passiert erst später, wenn expandVariables als eigene Stufe läuft.
#set %X% = %Other%
{?X?yes|no} → "yes"
Selbst wenn %Other% zu einem leeren String aufliefe: Der rohe Wert von %X% ist der wörtliche String %Other% — nicht leer, also truthy. Für eine wertbewusste Truthiness schreiben Sie %X% direkt als sauberes '1' oder ''. Berechnen Sie den Wächter im Assembler, bevor Sie ihn übergeben.
Die Zwei-Durchgang-Pipeline
Die Engine verarbeitet ein Template in Stufen. Bedingungen bekommen zwei Auswertungsdurchgänge:
1. strip comments
2. extract #set / #def directives
3. merge variables
4. apply conditionals ← pass 1
5. expand %var% references
6. apply conditionals ← pass 2
7. resolve enumerations
8. resolve permutations
9. post-process
Durchgang 1 übernimmt die Bedingungen, die direkt im Template-Rumpf stehen. Er läuft vor der Variablenexpansion, damit ein Falsy-Zweig verworfen wird, ohne dass Rechenzeit für seine %var% draufgeht.
Durchgang 2 übernimmt den Fall, dass der Wert einer Variablen selbst eine Bedingung enthält:
#set %CTA% = {?HasBonus?Claim bonus|Deposit now}
%CTA% /# pass 2 sees the conditional after expansion #/
Eine Klarstellung: Durchgang 2 schleift nicht. Enthält der gewählte Zweig eine frische %var%-Referenz, bleibt diese wörtlich stehen — einen dritten Expansionsdurchgang gibt es nicht. Für die meisten echten Templates ist das in Ordnung; die Wächter in bedingten Zweigen (%HasCrypto%, %HasFiat%) sind üblicherweise dieselben, die schon in Durchgang 1 aufgelöst wurden.
Durchgespielt: der Abschnitt „Zahlungsmethoden"
Das ist der Fall, für den die Syntax entworfen wurde. Eine Produktseite rendert einen Abschnitt „Zahlungsmethoden". Manche Händler nehmen Krypto, manche nur klassisches Geld, manche beides, einige haben noch gar keine Zahlungsanbindung.
Der Variablen-Assembler berechnet zwei Wächter und drei vorgerenderte HTML-Blöcke:
%HasCrypto% "1" or ""
%HasFiat% "1" or ""
%CryptoSection% /# already-rendered <h3> + <ul> #/
%FiatSection%
%LimitsSection%
Das Orchestrator-Template schaltet mit Bedingungen die Ersatzzeile für Einträge ohne Zahlungsdaten frei:
%FiatSection%%CryptoSection%%LimitsSection%
{?!HasCrypto?{?!HasFiat?<p>Payment details will be published shortly.</p>}}
Lesen Sie die letzte Zeile so: wenn kein Krypto und kein klassisches Geld, dann rendere den Ersatzabsatz. Verschachtelte Bedingungen brechen von außen nach innen ab, also schlägt bei %HasCrypto% = "1" die äußere Falsy-Prüfung sofort fehl und die innere Bedingung wird nie ausgewertet.
Vergleichen Sie das mit dem alten Behelf — einer Wächtervariablen, die per Spintax mit gewichteter Wahrscheinlichkeit zufällig zwischen leerem String und Ersatzabsatz wählt. Das funktionierte, aber die Ausgabe war nicht deterministisch und das Template musste eine zusätzliche Variable mitschleppen. Die bedingte Syntax sagt genau das, was sie meint.
Auswahl oder Bedingung — nicht verwechseln
Anti-Patterns
1. Boolesche Operatoren
In bedingtem Spintax gibt es kein &&, ||, != und kein ==. Die Syntax ist bewusst minimal. Brauchen Sie zusammengesetzte Logik, berechnen Sie den Booleschen Wert im Variablen-Assembler:
/# wrong: not supported #/
{?HasCrypto && HasLicense?…}
/# right: compose in the assembler #/
#set %ShowCryptoBlock% = {?HasCrypto?{?HasLicense?1}}
{?ShowCryptoBlock?…}
Der Assembler darf jede Hostsprache und jede Logik verwenden. Spintax bleibt ein Template-Werkzeug, keine Programmiersprache.
2. #set innerhalb eines Zweigs
#set-Direktiven werden vor jedem Bedingungsdurchgang herausgezogen — das ist Schritt 2 der Pipeline. Eine #set-Zeile in einem {?…?…}-Zweig feuert bedingungslos; die Bedingung steuert nur, ob der leere Rest der Zeile im Text des gewählten Zweigs stehen bleibt.
/# wrong: both #set lines fire — the second wins #/
{?A?
#set %x% = first
|}{?A?
#set %x% = second
|}%x%
→ always "second", regardless of A
Brauchen Sie bedingte Zuweisung, machen Sie sie im Assembler.
3. Ein | auf oberster Ebene als Literal im then
Das erste | auf Tiefe 0 im Rumpf trennt then von else. Jedes weitere | auf Tiefe 0 bleibt wörtlich — allerdings im else-Zweig, nicht im then-Zweig.
{?A?x|y|z} /# A truthy → "x"; A falsy → "y|z" #/
Braucht der then-Zweig ein wörtliches |, packen Sie es in verschachtelte Klammern oder nehmen die HTML-Entität |:
{?A?{x|y}} /# inner | is depth 1, not a separator #/
{?A?x | y} /# explicit entity, renders as "x | y" #/
4. Vorlauf und Laufzeit verwechseln
Bedingungen laufen als Vorlauf, bevor Aufzählungen und Permutationen auflösen. Das heißt: Ein Falsy-Zweig wird vollständig verworfen — keine Zufallsauswahl daraus feuert jemals. Steckt tief im Falsy-Zweig eine %RandomQuirk%-Permutation, wird sie bei falscher Bedingung nie ausgewertet. Gut so. Genau das ist der Sinn.
Nachsichtiges Parsing — fehlerhafte Formen sind nicht fatal
Ein einzelnes ? im Fließtext („Wie? So?") ist normal. Der Parser ist bewusst nachsichtig: Jedes {?…, das nicht auf die Grammatik passt, bleibt wörtlich stehen, statt einen Fehler zu werfen.
Der Validator dieser Website (und der Playground) meldet die ausgeglichen-fehlerhaften Formen dagegen als Warnung, damit Sie sie schon im Editor bemerken:
| Form | Behandlung |
|---|---|
{?VAR?then — keine schließende } | Warnung: unpaarige öffnende Klammer (wie bei jeder anderen {) |
{??yes} — leerer Name | Warnung: fehlerhafte Bedingung (leerer Name) |
{?VAR} — fehlender Trenner ? | Warnung: fehlerhafte Bedingung (Trenner fehlt) |
How? Like this? | gewöhnlicher Text, keine Warnung |
Zur Laufzeit wirft keine fehlerhafte Form. Die Engine läuft weiter in die normalen Aufzählungs- und Permutationsdurchgänge; ausgeglichene, aber fehlerhafte Tokens können dort verschluckt werden — verlassen Sie sich also nicht darauf, dass sie wörtlich erhalten bleiben.
Kurze Checkliste
- Nehmen Sie
{?VAR?…}, wenn die Wahl an einem Wert hängt, nie{a|b}. - Nehmen Sie
{?!VAR?…}, statt eine eigene „Nein"-Wächtervariable zu erfinden. - Zusammengesetzte Boolesche Werte berechnet der Assembler. Bedingungen im Spintax sind atomar.
- Nie
#setin einen Zweig setzen — es feuert bedingungslos. - Braucht
thenein wörtliches|, in{…}packen oder|nehmen. - Truthy = kein Leerraum, Punkt. Sondertruthiness im Assembler vorberechnen.
- HTML-Fragmente für Abschnitte, die pro Mandant die Form wechseln, in Variablen vorrendern. Die Bedingungen schalten sie frei.
Live ausprobieren
Der PlaygroundEN enthält im Standard-Template ein Beispiel {?HasFreeTier?…|…}. Schalten Sie %HasFreeTier% zwischen 1 und leer um, dann sehen Sie beide Zweige, ohne sonst etwas zu tippen.