Даведнік сінтаксісу 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 2, 2 3 4 1, 3 2 4 1

З падзяляльнікам

Адзіны падзяляльнік указваецца ў < > у пачатку:

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

Прыклады выніку: 2, 1, 4, 3 · 4, 3, 2, 1

Важна: Паміж [ і <падзяляльнік> няма прабелу.

Падзяляльнікі для кожнага элемента

У кожнага варыянта можа быць свой падзяляльнік, зададзены праз <sep> перад папярэднім |. Падзяляльнік перамяшчаецца разам са сваім элементам пры перамешванні.

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

Прыклады выніку: 1, 3, 2 and 4 · 3, 1, 2 and 4

Аўта-прабелы: Слоўныя падзяляльнікі кшталту <і> ці <або> аўтаматычна дапаўняюцца прабеламі: <і> дае  і . Знакі прыпынку (<,>) не дапаўняюцца.

Перастаноўкі з камбінацыямі

Наладжвальная мін./макс. колькасць элементаў і падзяляльнікі:

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

Прыклады выніку: apple, plum and orange · apple and apricot · orange

Параметры канфігурацыі

ПараметрТыповаАпісанне
minsizeколькасць усіхМінімальная колькасць выбіраных элементаў
maxsizeколькасць усіхМаксімальная колькасць выбіраных элементаў
sep" " (прабел)Падзяляльнік паміж элементамі (акрамя апошняга)
lastsepяк sepПадзяляльнік перад апошнім элементам

Правілы перастановак

  • Абмежавальнікі: [ і ]
  • Блок канфігурацыі <...> павінен ісці адразу за [
  • Параметры канфігурацыі падзяляюцца кропкай з коскай
  • Радковыя значэнні ў канфігурацыі бяруцца ў двукоссі: sep=", "
  • Пералікі і перастаноўкі могуць быць укладзены ў варыянты
  • HTML-элементы могуць быць варыянтамі
  • sep злучае ўсё да апошняй пары, lastsep — саму пару: пры двух абраных элементах з'яўляецца толькі lastsep, пры адным — ніводны

Зменныя %var%

Вызначае зменную для шматразовага выкарыстання, якая падстаўляецца ўсюды, дзе сустракаецца. Абвясціць яе можна дзвюма дырэктывамі, і выбар не касметычны: #set — макрас, яго значэнне падстаўляецца нанава пры кожнай спасылцы, і spintax унутры перакідваецца; #def разгортвае значэнне адзін раз за рэндэр і аддае гэты адзіны вынік усім спасылкам. (Адзін рэндэр — гэта адзін вывад; той самы seed узнаўляе яго.) Пакуль значэнне — просты тэкст, розніцы няма; яна з’яўляецца ў той момант, калі ўнутры з’яўляецца выбар.

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

Правілы зменных

  • #set і #def павінны пачынацца з пачатку радка
  • Імёны зменных бяруцца ў %: %name%
  • Імёны складаюцца з літар, лічбаў і падкрэсленняў, а спасылкі неадчувальныя да рэгістра: %Tone% і %tone% — адна зменная
  • Значэнні могуць змяшчаць любы сінтаксіс spintax (пералікі, перастаноўкі, іншыя зменныя)
  • #set — макрас: разгортваецца пры спасылцы, а не пры вызначэнні, і яго значэнне — разам са spintax унутры — падстаўляецца нанава і перакідваецца пры кожнай спасылцы
  • #def разгортвае значэнне адзін раз за рэндэр і трымае вынік усюды. Менавіта гэтым трымаюцца паўторы: назоўнік і пабудаваныя ад яго склонавыя формы, лік для блока {plural}, любая фраза, якая мусіць паўтарацца слова ў слова
  • #def робіць зменную ўзгодненай з самой сабой, але не звязвае дзве зменныя. #def %Noun% і #def %NounGen% — два незалежныя раскаты, яны могуць выпасці на розныя словы: формы, якія мусяць узгадняцца, павінны ісці з аднаго раскату — адна аснова ў #def, на якую спасылаецца кожная склонавая форма, або сінонімы, што скланяюцца аднолькава, з канчаткам па-за вызначэннем
  • Імя вызначаецца адзін раз. Другое вызначэнне таго ж імя пазначаецца як definition.duplicate-name, але рэндэр усё роўна ідзе: паміж дзвюма аднолькавымі дырэктывамі перамагае апошняя, а калі імя дзеляць #set і #def, перамагае #def — усё роўна, якая была першай
  • Спасылка без вызначэння друкуе саму сябе: %missing% застаецца ў вывадзе, а не знікае
  • Ніводная з дырэктыў не пераходзіць праз #include: уключаны шаблон не бачыць лакальных зменных бацькі, а яго ўласныя не выцякаюць угору. Раскатаная форма трапляе ўнутр толькі як зменная часу выканання
  • Радкі #set і #def выдаляюцца з выніку
  • Падрабязна: гл. даведнік па зменных — абсягі бачнасці і падвох з перакідам, і граматычна бяспечную сінанімізацыю — склонавыя сем’і

Абсягі бачнасці зменных

Хост можа падаваць зменныя з некалькіх месцаў. Калі тое самае імя ёсць у некалькіх, перамагае наймацнейшае:

  1. Зменныя часу выканання (наймацнейшыя) — тое, што хост перадае ў выклік рэндэру: context у @spintax/core, атрыбуты шорткоду ў плагіне WordPress: [spintax slug="greeting" name="Alice"]
  2. Лакальныя зменныя — аб’яўленыя праз #set ці #def унутры шаблона
  3. Глабальныя зменныя (найслабейшыя) — значэнні па змаўчанні на ўзроўні хоста, напрыклад старонка налад плагіна

Умовы {?VAR?then|else}

Умоўны сінтаксіс — уласная канструкцыя мовы: у прататыпе GTW нічога падобнага не было. Калі {a|b} — гэта раўнамерны выпадковы выбар, які не глядзіць на зменныя, то {?VAR?then|else} выбірае паводле таго, ці мае %VAR% значэнне.

Выкарыстоўвайце для рашэнняў паводле значэння: паказваць радок пра бясплатны тарыф толькі калі тарыф ёсць, рэндэрыць блок пра-магчымасцяў толькі калі карыстальнік на платным тарыфе, хаваць 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

Правілы ўмоў

  • Імёны зменных адпавядаюць таму ж regex, што і %var% (без уліку рэгістра)
  • Прэфікс ! інвертуе праверку: {?!VAR?няма даных}
  • Першы | на нулявой глыбіні падзяляе then і else; наступныя | застаюцца літараламі ў else
  • Укладзеныя ўмовы разгортваюцца outer-first — falsy-галіны короткозамыкаюцца
  • Састаўная логіка (&&, ||, параўнанні) не падтрымліваецца — вылічыце guard-зменную ў асэмблеры
  • Крывыя формы ({??yes}, {?VAR}) не падаюць — пясочніца пазначае іх папярэджаннямі
  • Падрабязна: гл. гайд па ўмоўным spintax з прыкладамі і анты-патэрнамі

Плюралы {plural %n%: мова|мовы|моў}

Падбірае граматычна правільную форму слова пад лік. Лічыльнік ідзе да двукроп’я, формы — пасля, праз |.

Форму выбірае лакаль рэндэра, а не шаблон, таму колькасць формаў залежыць ад лакалі: беларускай патрэбныя тры, англійскай — дзве.

{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

Формы па лакалях

Лакаль супастаўляецца па моўным субтэгу, так што be-BY і be паводзяць сябе аднолькава:

ЛакальФормаўВыбар па ліку
ru, uk, be, sr, hr, bs31 · 2–4 · 5 і больш
усе астатнія, уключна з en2роўна 1 · усё астатняе

Калі формаў не столькі, колькі трэба лакалі, рухавік аддае plural.arity і пакідае блок бачным у поўнашырынных дужках — моўчкі няправільная форма ў прадакшн не паедзе.

Правілы плюралаў

  • Адкрывальная частка літаральная, разам з прабелам: {plural . {plural: x} і {pluralN: x} плюраламі не з’яўляюцца
  • Двукроп’е абавязковае — яно аддзяляе лічыльнік ад формаў
  • Лічыльнік — гэта спасылка %Var% ці цэлалікавы літарал; зменныя ў лічыльніку падстаўляюцца да выбару формы
  • Адмоўныя лікі бяруцца па модулі; 0 атрымлівае форму «усё астатняе» (па-беларуску — «моў»)
  • Зменная-лічыльнік мусіць быць #def, а не #set#set гэта макрас, таму значэнне кшталту {1|4|9} на момант выбару формы ўсё яшчэ неразгорнуты spintax, і блок адрэндэрыцца пустым. У пясочніцы гэта plural.count-macro
  • Нелікавы ці нявызначаны лічыльнік сцірае блок, а не адгадвае форму
  • Падрабязна: гл. гайд па плюралах — правілы трох формаў і разборы прыкладаў

Уключэнні #include

Убудоўвае іншы шаблон у пазіцыю дырэктывы. #include — адзіная канструкцыя, якую рухавік не можа забяспечыць сам: сховішча шаблонаў у яго няма, таму рэзалвер, што ператварае спасылку ў тэкст шаблона, дае хост. Там, дзе рэзалвер не ўстаноўлены — у пясочніцы і на MCP-серверы гэтага сайта, і тое і другое наўмысна, — дырэктыва інертная і застаецца ў вывадзе звычайным тэкстам.

#include "hero-text"

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

Правілы ўключэнняў

  • Дырэктыва мусіць займаць увесь радок. Водступ злева дапушчальны, тэкст пасля спасылкі — не: Тэкст #include "hero" застаецца літаралам
  • Спасылка бярэцца ў двайныя двукоссі; адзінарныя ці іх адсутнасць — гэта ўжо не дырэктыва
  • Разрашэнне спасылкі — справа хоста: плагін WordPress шукае па slug або лікавым ID, JavaScript-хост перадае includeResolver
  • Без рэзалвера радок застаецца ў вывадзе літаралам; калі ў рэзалвера такога шаблона няма, радок замест гэтага выдаляецца — невядомая мэта моўчкі каштуе вам цэлага блока
  • Уключаныя шаблоны могуць змяшчаць свае зменныя і spintax, а таксама свае #include
  • Уключэнні разрашаюцца пасля таго, як у бацьку разыграны пералікі і перастаноўкі: include у галіне, што выйграла, убудоўваецца, а ў адкінутай не адбываецца зусім
  • Ланцужкі працуюць (шаблон уключае шаблон, які ўключае наступны); шаблон, што ўключае сам сябе — напрамую ці па цыкле, — абрываецца на першым паўторы, без памылкі і без дыягностыкі
  • Даччыныя шаблоны атрымліваюць глабальныя зменныя і зменныя часу выканання, але не лакальныя #set / #def бацькі, і сваіх угору не аддаюць
  • Уключэнне не можа быць значэннем вызначэння: #def %x% = #include "y" адхіляецца як def.include-in-value
  • Да рэндэру validate() паведамляе пра невядомую мэту, толькі калі хост перадаў спіс вядомых спасылак; extract() вяртае спасылкі, патрэбныя шаблону, — так хост іх пераднагружае
  • Падрабязна: гл. даведнік па кампазіцыі шаблонаў — патэрн асемблера, якім карыстаецца большасць канвеераў

Каментары /#...#/

Тэкст паміж маркерамі каментароў выдаляецца з выніку да любой іншай апрацоўкі.

/#
  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, email-адрасоў, даменаў, дзесятковых лікаў і абрэвіятур ад змены рэгістра
  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% = {a|b}Падстаўляецца нанава пры кожнай спасылцы — spintax унутры перакідваецца
Зменная (раз за рэндэр)#def %var% = {a|b}Адзін раскат за рэндэр, вынік трымаецца ўсюды — так узгадняюцца формы і канчаткі
Умова{?VAR?then|else}then, калі truthy; інакш else
Плюрал{plural %n%: мова|мовы|моў}Дапасоўвае форму слова да ліку па лакалі
Уключэнне#include "slug"Убудоўванне іншага шаблона — спасылку разрашае хост
Каментар/#...#/Выдаляецца з выніку

Мова вырасла са свайго прататыпа — Generating The Web (GTW); шаблоны, напісаныя для GTW, па-ранейшаму працуюць без зменаў.