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
| Parameter | Standard | Beschreibung |
|---|---|---|
minsize | Anzahl aller | Minimale Anzahl zu wählender Elemente |
maxsize | Anzahl aller | Maximale Anzahl zu wählender Elemente |
sep | " " (Leerzeichen) | Trennzeichen zwischen nicht-letzten Elementen |
lastsep | wie sep | Trennzeichen 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
sepverbindet alles vor dem letzten Paar,lastsepdas Paar selbst: bei zwei ausgewählten Elementen erscheint nurlastsep, 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
#setund#defmü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)
#setist 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#deflö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#defmacht 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-namegemeldet, das Rendering läuft trotzdem weiter: zwischen zwei gleichen Direktiven gewinnt die spätere, und teilen sich#setund#defeinen 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:
- Laufzeitvariablen (am stärksten) — das, was der Host an den Render-Aufruf übergibt:
contextin@spintax/core, Shortcode-Attribute im WordPress-Plugin:[spintax slug="greeting" name="Alice"] - Lokale Variablen — mit
#setoder#defim Template definiert - 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 deklariert | falsy |
| leerer String | falsy |
| nur Leerraum | falsy |
"0", "false" | truthy (nicht leer) |
| jeder andere Text oder HTML | truthy |
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 trenntthenvonelse; weitere bleiben literal imelse-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:
| Locale | Formen | Auswahl nach |
|---|---|---|
ru, uk, be, sr, hr, bs | 3 | 1 · 2–4 · ab 5 |
alle anderen, inkl. en | 2 | genau 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;
0bekommt die Form „alles andere" - Eine Zählervariable muss
#defsein, nicht#set—#setist 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 alsplural.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/#defdes Elterntemplates, und ihre eigenen dringen nicht nach oben - Ein Include kann nicht der Wert einer Definition sein:
#def %x% = #include "y"wird alsdef.include-in-valueabgelehnt - 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:
- Schützt URLs, E-Mails, Domains, Dezimalzahlen und Abkürzungen vor Großschreibung
- Eliminiert doppelte Leerzeichen und Tabulatoren
- Entfernt Leerzeichen vor Satzzeichen (
,.!?) - Fügt Leerzeichen nach Satzzeichen ein, wo sie fehlen
- Schreibt den ersten Buchstaben der Ausgabe groß (HTML-Tags überspringend)
- Großschreibung nach satzbeendenden Satzzeichen
- Großschreibung nach Block-Level-HTML-Tags
- Großschreibung nach Zeilenumbrüchen
- Stellt geschützte Platzhalter wieder her
Syntaxübersicht
| Funktion | Syntax | Verhalten |
|---|---|---|
| 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.