Spintax 语法参考

Spintax 模板标记的完整参考。

枚举 { }

从列表中随机选择一个选项。

{option1|option2|option3}

示例

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

规则

  • 分隔符:{}
  • 分隔符:|
  • 支持任意深度嵌套
  • 空选项是有效的(产生空字符串)
  • 从最内层表达式向外解析

排列 [ ]

选择 N 个元素,打乱顺序,使用分隔符连接。

简单排列

包含所有元素,以空格分隔:

[1|2|3|4]

输出示例:1 4 3 22 3 4 13 2 4 1

带分隔符

在开头的 < > 中指定统一分隔符:

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

输出示例:2, 1, 4, 34, 3, 2, 1

重要:[<分隔符> 之间不能有空格。

每元素分隔符

每个选项可以有自己的分隔符,使用 <sep> 在前一个 | 之前定义。分隔符在打乱时随其元素一起移动。

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

输出示例:1, 3, 2 and 43, 1, 2 and 4

自动空格:单词分隔符如 <and><or> 会自动添加空格:<and> 产生  and 。标点分隔符(<,>)不会自动添加。

带组合的排列

可配置的最小/最大元素数量和分隔符:

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

输出示例:apple, plum and orangeapple and apricotorange

配置参数

参数默认值描述
minsize全部数量要选择的最少元素数
maxsize全部数量要选择的最多元素数
sep" "(空格)非最后元素之间的分隔符
lastsepsep 相同最后一个元素之前的分隔符

排列规则

  • 分隔符:[]
  • 配置块 <...> 必须紧跟在 [ 之后
  • 配置参数以分号分隔
  • 配置中的字符串值用引号括起:sep=", "
  • 枚举和排列可以嵌套在选项内
  • HTML 元素可以作为选项

变量 %var%

定义一个可重用变量,在出现的任何地方进行替换。

#set %VARIABLE_NAME% = value or spintax structure
#def %VARIABLE_NAME% = value or spintax structure

示例

#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%.

/# %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.

变量规则

  • #set#def 必须在行首开始
  • 变量名用 % 包围:%name%
  • 变量名由字母数字和下划线组成
  • 值可以包含任何 spintax 语法(枚举、排列、其他变量)
  • #set 变量在引用时展开,而非定义时(惰性求值)
  • #set 是宏:每次引用时其值都会重新替换,内部的 spintax 也会重新抽取。#def 每次渲染只解析一次,并在所有引用处保持该结果
  • #set#def 行从输出中移除

WordPress 插件中的变量作用域

插件支持三个变量作用域。当同一名称存在于多个作用域时,最强的作用域优先:

  1. 运行时变量(最强)— 通过短代码传递:[spintax slug="greeting" name="Alice"]
  2. 局部变量 — 在模板内用 #set#def 定义
  3. 全局变量(最弱)— 在设置页面定义

条件 {?VAR?then|else}

条件是 spintax.net 在 GTW 家族之上的独特扩展。当 {a|b} 是不看变量的均匀随机选择时,{?VAR?then|else} 会根据 %VAR% 是否有值来选择。

用于 value-driven 的选择:仅当存在免费层时显示免费层提示,仅当用户处于付费方案时才渲染高级功能块,隐藏不适用的 CTA。

预处理在 %var% 展开和随机分支选择器之前运行,因此 falsy 分支会被完全丢弃 — 其内部不会被求值。

形式

{?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 和 falsy

规则比 JavaScript 简单得多 — truthy = 至少一个非空白字符:

%VAR% 的值Truthy?
未声明falsy
空字符串falsy
仅空白falsy
"0""false"truthy (非空)
任何其他文本或 HTMLtruthy

条件规则

  • 变量名遵循与 %var% 相同的 regex(不区分大小写)
  • ! 前缀反转检查:{?!VAR?缺失}
  • 0 层深度的第一个 | 分隔 thenelse;后续的保持字面量在 else
  • 嵌套条件由外向内求值 — falsy 分支短路
  • 不支持组合逻辑(&&||、比较) — 在汇编器中预先计算守卫变量
  • 畸形形式({??yes}{?VAR})永不抛出 — 演练场将其标记为警告
  • 深入了解:条件 spintax 指南 含示例与反模式

复数 {plural %n%: language|languages}

根据数字选择语法正确的词形。计数放在冒号前,词形放在冒号后,用 | 分隔。

词形由渲染语言环境决定,而非模板本身,因此需要提供几种词形取决于该语言环境:英语需要两种,俄语需要三种。

{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

各语言环境的词形数

语言环境按其语言子标签匹配,因此 ru-RUru 行为一致:

语言环境词形数选择依据
ruukbesrhrbs31 · 2–4 · 5 及以上
其余全部,含 en2恰为 1 · 其余情况

词形数量不符时,引擎报告 plural.arity,并以全角括号保留该块可见——错误的复数不会悄悄上线。

复数规则

  • 起始部分是字面量,包括那个空格:{plural {plural: x}{pluralN: x} 都不是复数块
  • 冒号是必需的——它分隔计数与词形
  • 计数可以是 %Var% 引用或整数字面量;计数中的变量会在选择词形之前完成替换
  • 负数取绝对值;0 取「其余情况」的词形
  • 计数变量必须用 #def,不能用 #set——#set 是宏,因此像 {1|4|9} 这样的值在决定复数时仍是未解析的 spintax,整块会渲染为空。演练场将其标记为 plural.count-macro
  • 非数字或未定义的计数会清除该块,而不是猜测
  • 深入了解:复数 spintax 指南,含俄语三词形规则与完整示例

包含 #include

在指令位置嵌入另一个模板。

#include "hero-text"

包含规则

  • 模板引用使用双引号
  • 通过模板别名或数字 ID 解析
  • 被包含的模板可以包含自己的变量和 spintax
  • 支持递归包含
  • 循环引用会被检测并阻止
  • 子模板继承全局和运行时变量,但继承父模板的 #set / #def 局部变量

注释 /#...#/

注释标记之间的文本在任何其他处理之前从输出中移除。

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

注释规则

  • 起始分隔符:/#
  • 结束分隔符:#/
  • 可以跨多行
  • 不能嵌套
  • 在任何其他处理之前移除

嵌套

所有语法元素可以在任意深度内相互嵌套:

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

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

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

后处理

引擎在生成后应用自动文本校正:

  1. 保护 URL、电子邮件、域名、小数和缩写不被大写化
  2. 消除重复空格和制表符
  3. 移除标点符号前的空格(, . ! ?
  4. 在缺少空格的标点符号后添加空格
  5. 将输出的第一个字母大写(跳过 HTML 标签)
  6. 在句末标点后大写
  7. 在块级 HTML 标签后大写
  8. 在换行后大写
  9. 恢复受保护的占位符

语法总结

功能语法行为
枚举{a|b|c}随机选择一个选项
排列[a|b|c]选择 N 个,打乱,连接
分隔符[<sep> a|b|c]带统一分隔符的排列
每元素分隔符[<,> a|b <x>|c]带自定义分隔符的排列
组合[<config> a|b|c]带最小/最大数量的排列
变量#set %var% = val可重用替换
变量(仅一次)#def %var% = val每次渲染只解析一次
条件{?VAR?then|else}truthy 时渲染 then,falsy 时渲染 else
复数{plural %n%: language|languages}按语言环境使词形与数字一致
包含#include "slug"嵌入另一个模板
注释/#...#/从输出中移除

语法兼容 Generating The Web (GTW) 标准。