Spintax-Syntaxreferenz

Vollständige Referenz für Spintax-Vorlagen-Markup.

Enumerationen { }

Wählt zufällig eine Option aus der Liste.

{option1|option2|option3}

Beispiele

{blue|grey|clear}
{|free|paid} plan                 ← empty option = sometimes nothing
{Acme {Pro|Lite}}                ← nested enumerations
{order {|#42-A} confirmed}       ← nesting with empty option

Regeln

  • Begrenzer: { und }
  • Trennzeichen: |
  • Unterstützt Verschachtelung in beliebiger Tiefe
  • Leere Optionen sind gültig (erzeugen leere Zeichenkette)
  • Auflösung erfolgt vom innersten Ausdruck nach außen

Permutationen [ ]

Wählt N Elemente, mischt sie und verbindet sie mit Trennzeichen.

Einfache Permutationen

Alle Elemente einbezogen, durch Leerzeichen getrennt:

[1|2|3|4]

Ausgabebeispiele: 1 4 3 2, 2 3 4 1, 3 2 4 1

Mit Trennzeichen

Einheitliches Trennzeichen angegeben in < > am Anfang:

[<, > 1|2|3|4]

Ausgabebeispiele: 2, 1, 4, 3 · 4, 3, 2, 1

Wichtig: Kein Leerzeichen zwischen [ und <Trennzeichen>.

Trennzeichen pro Element

Jede Option kann ein eigenes Trennzeichen haben, definiert mit <sep> vor dem vorhergehenden |. Das Trennzeichen wandert beim Mischen mit seinem Element mit.

[<, > 1|2|3 < and >|4]

Ausgabebeispiele: 1, 3, 2 and 4 · 3, 1, 2 and 4

Auto-Abstände: Wort-Trennzeichen wie <and> oder <or> werden automatisch mit Leerzeichen ergänzt: <and> wird zu  and . Satzzeichen-Trennzeichen (<,>) werden nicht ergänzt.

Permutationen mit Kombinationen

Konfigurierbare minimale/maximale Elementanzahl und Trennzeichen:

[<minsize=1;maxsize=3;sep=", ";lastsep=" and "> apple|plum|orange|apricot]

Ausgabebeispiele: apple, plum and orange · apple and apricot · orange

Konfigurationsparameter

ParameterStandardBeschreibung
minsizeAnzahl allerMinimale Anzahl zu wählender Elemente
maxsizeAnzahl allerMaximale Anzahl zu wählender Elemente
sep" " (Leerzeichen)Trennzeichen zwischen nicht-letzten Elementen
lastsepwie sepTrennzeichen vor dem letzten Element

Permutationsregeln

  • Begrenzer: [ und ]
  • Konfigurationsblock <...> muss unmittelbar nach [ folgen
  • Konfigurationsparameter werden durch Semikolon getrennt
  • Zeichenkettenwerte in der Konfiguration stehen in Anführungszeichen: sep=", "
  • Enumerationen und Permutationen können innerhalb von Optionen verschachtelt werden
  • HTML-Elemente können Optionen sein
  • sep verbindet alles vor dem letzten Paar, lastsep das Paar selbst: bei zwei ausgewählten Elementen erscheint nur lastsep, bei einem keines von beiden

Variablen %var%

Definiert eine wiederverwendbare Variable, die überall dort eingesetzt wird, wo sie auftaucht. Zwei Direktiven deklarieren eine, und die Wahl ist nicht kosmetisch: #set ist ein Makro — sein Wert wird bei jeder Referenz erneut eingesetzt, enthaltenes Spintax also neu ausgewürfelt; #def würfelt den Wert einmal pro Rendering und gibt dieses eine Ergebnis an jede Referenz. (Ein Rendering ist eine Ausgabe; derselbe Seed reproduziert sie.) Solange der Wert reiner Text ist, sind beide identisch; der Unterschied zeigt sich in dem Moment, in dem der Wert eine Auswahl enthält.

#set %VARIABLE_NAME% = value or spintax structure

#def %VARIABLE_NAME% = value or spintax structure

Beispiele

#set %name% = John
#set %greeting% = {Hello|Hi|Hey}
#set %items% = [<minsize=2;maxsize=3;sep=", ";lastsep=" and "> apples|oranges|bananas]
Some text with %name% and %greeting%, also %items%.
And once more, %greeting% — a second reference.

/# %greeting% above may differ between the two references — #set re-rolls.
   #def picks once and keeps it: #/
#def %tone% = {friendly|warm|upbeat}
A %tone% intro, and a %tone% outro — always the same word.

Variablenregeln

  • #set und #def müssen am Zeilenanfang stehen
  • Variablennamen stehen zwischen %: %name%
  • Namen bestehen aus Buchstaben, Ziffern und Unterstrich, und Referenzen sind case-insensitiv: %Tone% und %tone% sind eine Variable
  • Werte dürfen beliebige Spintax-Syntax enthalten (Aufzählungen, Permutationen, andere Variablen)
  • #set ist ein Makro: es wird bei der Referenz expandiert, nicht bei der Definition, und sein Wert — samt enthaltenem Spintax — wird bei jeder Referenz erneut eingesetzt und neu ausgewürfelt
  • #def löst seinen Wert einmal pro Rendering auf und behält dieses Ergebnis überall. Genau das hält Wiederholungen kongruent: ein Substantiv und die daraus gebildeten Formen, eine Zahl für einen {plural}-Block, jede Phrase, deren Wiederholungen Wort für Wort übereinstimmen müssen
  • #def macht eine Variable mit sich selbst konsistent; es korreliert nicht zwei Variablen. #def %Noun% und #def %NounGen% sind zwei unabhängige Würfe und können auf verschiedene Wörter fallen — Formen, die übereinstimmen müssen, müssen aus einem Wurf stammen: ein #def-Stamm, auf den jede Form verweist, oder Synonyme, die gleich flektieren, mit der Endung außerhalb der Definition
  • Ein Name wird einmal definiert. Eine zweite Definition desselben Namens wird als definition.duplicate-name gemeldet, das Rendering läuft trotzdem weiter: zwischen zwei gleichen Direktiven gewinnt die spätere, und teilen sich #set und #def einen Namen, gewinnt #def — gleich welche zuerst kam
  • Eine Referenz ohne Definition gibt sich selbst aus: %missing% bleibt in der Ausgabe stehen, statt zu verschwinden
  • Keine der beiden Direktiven überquert ein #include: das eingebundene Template sieht die lokalen Variablen des Elterntemplates nicht, und seine eigenen dringen nicht nach oben. Eine ausgewürfelte Form erreicht das Kind nur als Laufzeitvariable
  • #set- und #def-Zeilen werden aus der Ausgabe entfernt
  • Vertiefung: siehe den Variablen-Leitfaden (Gültigkeitsbereiche und die Reroll-Falle) und die grammatiksichere Synonymisierung (Kasusfamilien)

Gültigkeitsbereiche von Variablen

Ein Host kann Variablen aus mehreren Quellen liefern. Existiert derselbe Name in mehreren, gewinnt die stärkste:

  1. Laufzeitvariablen (am stärksten) — das, was der Host an den Render-Aufruf übergibt: context in @spintax/core, Shortcode-Attribute im WordPress-Plugin: [spintax slug="greeting" name="Alice"]
  2. Lokale Variablen — mit #set oder #def im Template definiert
  3. Globale Variablen (am schwächsten) — hostweite Vorgaben, etwa die Einstellungsseite des Plugins

Bedingungen {?VAR?then|else}

Bedingungen sind eine eigene Konstruktion der Sprache — im GTW-Prototyp gab es nichts Vergleichbares. Während {a|b} eine gleichverteilte Zufallsauswahl ohne Bezug zu Variablen ist, wählt {?VAR?then|else} danach aus, ob %VAR% einen Wert hat.

Nutzen Sie es für wertgesteuerte Entscheidungen: eine Free-Tier-Zeile nur anzeigen, wenn ein Free-Tier existiert, einen Pro-Features-Block nur rendern, wenn der Nutzer auf einem kostenpflichtigen Plan ist, einen CTA verbergen, der nicht zutrifft.

Der Pre-Pass läuft vor der %var%-Expansion und vor dem zufälligen Zweig-Picker, sodass ein falsy-Zweig vollständig verworfen wird — nichts darin wird ausgewertet.

Formen

{?VAR?then}                ← truthy ⇒ then; falsy ⇒ empty
{?VAR?then|else}           ← truthy ⇒ then; falsy ⇒ else
{?!VAR?then|else}          ← inverted
{?HasFreeTier? — free tier available since %founded%|, trusted since %founded%}

Truthy und falsy

Die Regel ist bewusst einfacher als in JavaScript — truthy = mindestens ein Nicht-Leerraum-Zeichen:

Wert von %VAR%Truthy?
nicht deklariertfalsy
leerer Stringfalsy
nur Leerraumfalsy
"0", "false"truthy (nicht leer)
jeder andere Text oder HTMLtruthy

Bedingungs-Regeln

  • Variablennamen folgen derselben Regex wie %var% (unabhängig von Groß-/Kleinschreibung)
  • Das !-Präfix invertiert die Prüfung: {?!VAR?fehlt}
  • Das erste | auf Tiefe 0 trennt then von else; weitere bleiben literal im else-Zweig
  • Verschachtelte Bedingungen werden außen-zuerst ausgewertet — falsy-Zweige kurzschließen
  • Zusammengesetzte Logik (&&, ||, Vergleiche) wird nicht unterstützt — berechnen Sie eine Wächter-Variable im Assembler
  • Fehlerhafte Formen ({??yes}, {?VAR}) werfen niemals — das Playground markiert sie als Warnungen
  • Vertiefung: siehe den Conditional-Spintax-Leitfaden mit Beispielen und Anti-Pattern

Plurale {plural %n%: Sprache|Sprachen}

Wählt die grammatisch korrekte Wortform zu einer Zahl. Der Zähler steht vor dem Doppelpunkt, die Formen dahinter, getrennt durch |.

Die Form bestimmt die Render-Locale, nicht die Vorlage — wie viele Formen du liefern musst, hängt also von dieser Locale ab. Englisch braucht zwei, Russisch drei.

{plural %n%: form1|form2}          ← 2-form locale (en, de, es…)

{plural %n%: form1|form2|form3}    ← 3-form locale (ru, uk, sr…)
#def %LangCount% = 5
supports %LangCount% {plural %LangCount%: language|languages}
← supports 5 languages

Formen je Locale

Die Locale wird über ihr Sprach-Subtag abgeglichen, ru-RU und ru verhalten sich also gleich:

LocaleFormenAuswahl nach
ru, uk, be, sr, hr, bs31 · 2–4 · ab 5
alle anderen, inkl. en2genau 1 · alles andere

Stimmt die Anzahl der Formen nicht, meldet die Engine plural.arity und lässt den Block mit Vollbreiten-Klammern sichtbar — ein falscher Plural geht nie stillschweigend live.

Plural-Regeln

  • Die Öffnung ist wörtlich, inklusive Leerzeichen: {plural . {plural: x} und {pluralN: x} sind keine Plural-Blöcke
  • Der Doppelpunkt ist Pflicht — er trennt Zähler und Formen
  • Der Zähler ist eine %Var%-Referenz oder eine ganzzahlige Konstante; Variablen im Zähler werden vor der Formwahl ersetzt
  • Negative Zahlen zählen im Betrag; 0 bekommt die Form „alles andere"
  • Eine Zählervariable muss #def sein, nicht #set#set ist ein Makro, ein Wert wie {1|4|9} ist bei der Formwahl also noch unaufgelöstes Spintax und der Block rendert leer. Das Playground meldet das als plural.count-macro
  • Ein nicht-numerischer oder undefinierter Zähler löscht den Block, statt zu raten
  • Vertiefung: siehe den Plural-Spintax-Leitfaden mit den russischen Dreiform-Regeln und ausgearbeiteten Beispielen

Includes #include

Bettet ein anderes Template an der Position der Direktive ein. #include ist die einzige Konstruktion, die die Engine nicht allein bedienen kann: sie hält keinen Template-Speicher, also liefert der Host einen Resolver, der eine Referenz in Template-Text verwandelt. Wo kein Resolver installiert ist — im Playground und im MCP-Server dieser Website, beides bewusst — ist die Direktive wirkungslos und bleibt als literaler Text in der Ausgabe.

#include "hero-text"

/# wrong: text before the directive on the same line leaves it literal #/
Intro: #include "hero-text"

Include-Regeln

  • Die Direktive muss die ganze Zeile einnehmen. Einrückung ist in Ordnung, Text nach der Referenz nicht — Text #include "hero" bleibt literal
  • Die Referenz steht in doppelten Anführungszeichen; mit einfachen oder ohne Anführungszeichen ist es keine Direktive mehr
  • Die Auflösung gehört dem Host: das WordPress-Plugin löst über Template-Slug oder numerische ID auf, ein JavaScript-Host übergibt einen includeResolver
  • Ohne Resolver bleibt die Zeile literal in der Ausgabe; kennt der Resolver das Template nicht, wird die Zeile stattdessen entfernt — ein unbekanntes Ziel kostet den Block lautlos
  • Eingebundene Templates können eigene Variablen und Spintax enthalten, und eigene #include
  • Includes werden aufgelöst, nachdem Aufzählungen und Permutationen des Elterntemplates gewürfelt wurden: ein Include im gewonnenen Zweig wird eingebettet — eines in einem verworfenen Zweig findet nie statt
  • Ketten funktionieren (ein Template bindet eines ein, das ein weiteres einbindet); ein Template, das sich selbst einbindet — direkt oder über einen Zyklus — wird bei der ersten Wiederholung abgeschnitten, ohne Fehler und ohne Diagnose
  • Kind-Templates erben globale und Laufzeitvariablen, aber nicht die lokalen #set / #def des Elterntemplates, und ihre eigenen dringen nicht nach oben
  • Ein Include kann nicht der Wert einer Definition sein: #def %x% = #include "y" wird als def.include-in-value abgelehnt
  • Vor dem Rendern meldet validate() ein unbekanntes Ziel nur, wenn der Host die Liste bekannter Referenzen übergibt; extract() liefert die Referenzen, die ein Template braucht — so lädt ein Host sie vorab
  • Vertiefung: siehe den Leitfaden zur Template-Komposition mit dem Assembler-Muster, das die meisten Pipelines stattdessen verwenden

Kommentare /#...#/

Text zwischen Kommentarmarkierungen wird vor jeder anderen Verarbeitung aus der Ausgabe entfernt.

/#
  This is a comment section.
  It can span multiple lines.
  It won't appear in output.
#/

Kommentarregeln

  • Start-Begrenzer: /#
  • End-Begrenzer: #/
  • Können sich über mehrere Zeilen erstrecken
  • Können nicht verschachtelt werden
  • Werden vor jeder anderen Verarbeitung entfernt

Verschachtelung

Alle Syntaxelemente können in beliebiger Tiefe ineinander verschachtelt werden:

{option1|[<, > sub1|sub2|sub3]|option3}

[<minsize=2;maxsize=3;sep=", ";lastsep=" and "> {red|blue} apples|{big|small} oranges|bananas]

#set %var% = {a|[b|c]}

Nachbearbeitung

Die Engine wendet nach der Generierung automatische Textkorrektur an:

  1. Schützt URLs, E-Mails, Domains, Dezimalzahlen und Abkürzungen vor Großschreibung
  2. Eliminiert doppelte Leerzeichen und Tabulatoren
  3. Entfernt Leerzeichen vor Satzzeichen (, . ! ?)
  4. Fügt Leerzeichen nach Satzzeichen ein, wo sie fehlen
  5. Schreibt den ersten Buchstaben der Ausgabe groß (HTML-Tags überspringend)
  6. Großschreibung nach satzbeendenden Satzzeichen
  7. Großschreibung nach Block-Level-HTML-Tags
  8. Großschreibung nach Zeilenumbrüchen
  9. Stellt geschützte Platzhalter wieder her

Syntaxübersicht

FunktionSyntaxVerhalten
Enumeration{a|b|c}Wählt eine zufällige Option
Permutation[a|b|c]Wählt N, mischt, verbindet
Trennzeichen[<sep> a|b|c]Permutation mit einheitlichem Trennzeichen
Sep pro Element[<, > a|b <x>|c]Permutation mit benutzerdefinierten Trennzeichen
Kombinationen[<config> a|b|c]Permutation mit Min/Max-Anzahl
Variable#set %var% = {a|b}Bei jeder Referenz erneut eingesetzt — enthaltenes Spintax wird neu ausgewürfelt
Variable (einmalig)#def %var% = {a|b}Ein Wurf pro Rendering, überall beibehalten — so bleiben Wortformen und Endungen kongruent
Bedingung{?VAR?then|else}then, wenn truthy; else, wenn falsy
Plural{plural %n%: Sprache|Sprachen}Gleicht die Wortform je nach Locale an die Zahl an
Include#include "slug"Bettet eine andere Vorlage ein — die Referenz löst der Host auf
Kommentar/#...#/Wird aus der Ausgabe entfernt

Die Sprache ist ihrem Prototyp Generating The Web (GTW) entwachsen — für GTW geschriebene Vorlagen laufen weiterhin unverändert.