• Директивы
  • Создание шаблона

namespace

Директива декларирует пространство имён для файла в котором оно используется, т. е. все декларируемые в этом файле шаблоны будут частью заданного пространства имён.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области, только одна декларация на файл Отсутствует Строковая, логическая Не требуется

Описание

Пространства имён Snakeskin служат для экспорта шаблонов из файла, поэтому перед тем как начать создавать сами шаблоны нужно предварительно объявить пространство имён, а уже после они будут экспортироваться по схеме exports.namespace.template. В рамках одного файла может быть только одно пространство имён.

Например:

- namespace demo

/// Шаблон экспортируется как exports.demo.index
- template index()
	Hello world!
{namespace demo}

/// Шаблон экспортируется как exports.demo.index
{template index()}
	Hello world!
{/template}

Пространство имён может состоять из множества частей (свойств объекта), причём Snakeskin проверяет существование заданного пути и создаёт только те части, которые отсутствуют.

- namespace demo.helloWorld

/// exports.demo.helloWorld.index
- template index()
	Hello world!

/// exports.demo.helloWorld.bar
- template bar()
	Hello people!
{namespace demo.helloWorld}

/// exports.demo.helloWorld.index
{template index()}
	Hello world!
{/template}

/// exports.demo.helloWorld.bar
{template bar()}
	Hello people!
{/template}

Т.к. пространство имён превращается в JS объект, то на декларируемое имя накладываются те же ограничения, что и на свойство объекта, однако можно использовать декларацию через квадратные скобки ([ ... ]), которая позволяет применять любые символы и сложные выражения, например:

- namespace ['@demo']['hello' + 'World']

/// exports['@demo']['helloWorld'].index
- template index()
	Hello world!
{namespace ['@demo']['hello' + 'World']}

/// exports['@demo']['helloWorld'].index
{template index()}
	Hello world!
{/template}

Если первая часть имени использует синтаксис без квадратных скобок, то будет создана глобальная (для Snakeskin) переменная с таким же именем:

/// var demo = exports.demo['helloWorld']
- namespace demo['hello' + 'World']

- template index()
	Hello world!
/// var demo = exports.demo['helloWorld']
{namespace ['@demo']['hello' + 'World']}

{template index()}
	Hello world!
{/template}

Пространство имён создаёт with биндинг, который можно использовать для удобного вызова шаблонов в рамках файла.

- namespace demo
- template parent()
	Hello world!

/// Тоже самое, что и extends exports.demo.parent
- template child() extends @parent
{namespace demo}
{template parent()}
	Hello world!
{/template}

/// Тоже самое, что и extends exports.demo.parent
{template child() extends @parent}
{/template}

Директива может использоваться только в глобальной области.

Плейсхолдеры имени

При декларации пространства имён можно использовать специальные плейсхолдеры, которые заменяются при трансляции на некоторое статическое значение в рамках своего контекста.

%dirName%

Плейсхолдер %dirName% заменяется на имя директории, в которой лежит исходный файл Snakeskin, например:

foo/index.ss

- namespace %dirName%.bar

/// exports.foo.bar.index
- template index()
	Hello world!
{namespace %dirName%.bar}

/// exports.foo.bar.index
{template index()}
	Hello world!
{/template}

Т.к. в названии директории могут встречаться «запрещённые» символы, то лучше использовать синтаксис с квадратными скобками:

- namespace [%dirName%].bar
- template index()
	Hello world!
{namespace [%dirName%].bar}
{template index()}
	Hello world!
{/template}

%fileName%

Плейсхолдер %fileName% заменяется на имя исходного файла-шаблона (без расширения), например:

foo/index.ss

- namespace %fileName%.bar

/// exports.index.bar.index
- template index()
	Hello world!
{namespace %fileName%.bar}

/// exports.index.bar.index
{template index()}
	Hello world!
{/template}

Т.к. в названии файла могут встречаться «запрещённые» символы, то лучше использовать синтаксис с квадратными скобками:

- namespace [%fileName%].bar
- template index()
	Hello world!
{namespace [%fileName%].bar}
{template index()}
	Hello world!
{/template}
  • Директивы
  • Создание шаблона

template

Директива декларирует шаблон c заданным именем и входными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области, необходима предварительная декларация namespace Отсутствует Блочная, логическая, функциональная Не требуется

Описание

Шаблон Snakeskin — это синоним функции в JavaScript, т. е. после трансляции все шаблоны будут представлены как JS функции, которые можно использовать вместе с любым другим JS кодом. По умолчанию шаблоны возвращают строки, однако это поведение можно поменять задав специальный renderMode или явно вернув значение через директиву return.

Название шаблона соответствует названию функции в JavaScript, поэтому оно подчиняется тем же правилам. Начать декларацию шаблона можно только после декларации пространства имён, причём в рамках одного пространства имён не может быть 2-х шаблонов с одинаковым именем, а размещаться шаблон может только в глобальной области декларации, т. е. шаблон не может включать в себя другой шаблон — для этого есть подшаблоны, например, блоки.

Декларация шаблона очень похожа на декларацию функции в JavaScript, только вместо ключевого слова function используется template, например:

- namespace demo
- template index(name = 'world')
	Hello {name}!
{namespace demo}
{template index(name = 'world')}
	Hello {name}!
{/template}

Параметров у шаблона может быть неограниченное количество, а т. к. директива template является функциональной, то она реализует стандартный механизм декларации параметров.

Вложенные пространства имён

При декларации шаблона можно использовать пространства имён, подобно тому, как это делается в namespace, например:

foo/index.ss

- namespace demo
- template %fileName%.index(name = 'world')
	Hello {name}!
{namespace demo}
{template %fileName%.index(name = 'world')}
	Hello {name}!
{/template}

Механика здесь точно такая же, как и у namespace, поэтому рассматриваться отдельно не будет, однако, есть небольшой дополнительный нюанс: если последняя часть имени декларируется без квадратных скобок, то она будет установлена как свойство name полученной функции JavaScript, т. е.

- namespace demo
- template index(name = 'world')
	Hello {name}!
{namespace demo}
{template index(name = 'world')}
	Hello {name}!
{/template}

Превратится в:

exports.demo.index = function index(name) {
	name = name != null ? name : 'world';
	return 'Hello ' + name + '!';
};

Стандартные переменные шаблона

Каждый шаблон определяет ряд констант и функций, которые можно использовать в нём:

TPL_NAME — строка, которая содержит полное имя шаблона вместе с пространством имён, причём именно в том виде, как оно было задано при декларации шаблона;

PARENT_TPL_NAME — строка, которая содержит полное имя родительского шаблона вместе с пространством имён, причём именно в том виде, как оно было задано при декларации шаблона;

callee — ссылка на исходную функцию-шаблон;

self — ссылка на объект callee.Blocks, в котором хранятся вызываемые блоки (методы) исходного шаблона;

$0 — ссылка на активный DOM узел (если renderMode == 'dom');

$tagName — имя созданного через директиву тега (.getVar('$tagName'));

$attrKey — ключ атрибута тега созданного через директиву;

$attrs — объект атрибутов тега созданного через директиву (.getVar('$attrs'));

$class — значение липкой ссылки;

getTplResult — функция, которая возвращает результат работы шаблона, также может принимать один логический входной параметр, при задании которого после вызова функции результат работы шаблона будет обнуляться;

clearTplResult — функция, которая обнуляет результат работы шаблона.

Модификаторы шаблона

Шаблоны Snakeskin поддерживают специальные модификаторы декларации.

Шаблон-генератор

Шаблон будет транслироваться в JS как функция-генератор (для поддержки в старых браузерах необходимо использовать полифил).

- namespace demo
- template *hello()
	- yield
		Hello world!
{namespace demo}
{template *hello()}
	{yield}
		Hello world!
	{/}
{/template}

Асинхронный шаблон

Шаблон будет транслироваться в JS как async функция (для поддержки в браузерах необходимо использовать полифил).

- namespace demo
- async template hello()
	- var data = await db.getData()
	Hello {data.name}!
{namespace demo}
{async template hello()}
	{var data = await db.getData() /}
	Hello {data.name}!
{/template}

Декораторы

К любому шаблону может быть добавлено неограниченное количество функций-декораторов (которые также могу быть шаблонами). Функция-декоратор принимает на вход ссылку на исходную функцию и обязана вернуть в качестве ответа функцию.

- namespace demo
- import Typograf from 'typograf'

- template typograf(params)
	- return
		() => target
			- return
				() =>
					- return new Typograf(params).execute(target.apply(this, arguments))

- @typograf({locale: 'ru'})
- template index()
	Спорт - это правильно!
{namespace demo}
{import Typograf from 'typograf'}

{template typograf(params)}
	{return}
		{() => target}
			{return}
				{() =>}
					{return new Typograf(params).execute(target.apply(this, arguments)) /}
				{/}
			{/}
		{/}
	{/}
{/template}

{@typograf({locale: 'ru'})}
{template index()}
	Спорт - это правильно!
{/template}

Локальные параметры трансляции

При декларации шаблона ему можно задать определённые параметры трансляции, для этого используется специальный оператор @=, например:

- namespace demo
- template index() @= literalBounds ['<?php', '?>']
	{{ Hello }}
{namespace demo}
{template index() @= literalBounds ['<?php', '?>']}
	{{ Hello }}
{/template}

Наследование шаблонов

Шаблоны Snakeskin подобны классам в других языках программирования, т. е. у них могут быть методы и свойства, и они могут наследоваться от других шаблонов. Чтобы указать, что шаблон наследуется от другого, необходимо использовать ключевое слово extends, например:

- namespace demo
- template index() extends anotherTemplate
	...
{namespace demo}
{template index() extends anotherTemplate
	...
{/template}

Подробнее про наследование.

Явный вызов шаблонов внутри других шаблонов

Т.к. шаблоны Snakeskin являются простыми функциями, то их можно вызывать внутри других шаблонов и для этого удобно использовать директиву call.

- namespace demo

- template hello()
	Hello world!

- template index()
	/// Т.к. hello находится в одном namespace с index,
	/// то мы можем использовать короткий вызов,
	/// но можем написать и полную форму += demo.hello()
	+= @hello()
{namespace demo}

{template hello()}
	Hello world!
{/template}

{template index()}
	/// Т.к. hello находится в одном namespace с index,
	/// то мы можем использовать короткий вызов,
	/// но можем написать и полную форму {+= demo.hello() /}
	{+= @hello() /}
{/template}
  • Директивы
  • Создание шаблона

interface

Директива декларирует шаблон-интерфейс c заданным именем и входными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области, необходима предварительная декларация namespace Отсутствует Блочная, логическая, функциональная Не требуется

Описание

Шаблон-интерфейс отличается от простого шаблона тем, что после трансляции в JS будет получена пустая функция с входными параметрами, например:

- namespace demo
- interface index(name = 'world')
	Hello {name}!
{namespace demo}
{interface index(name = 'world')}
	Hello {name}!
{/interface}

Превратится в:

exports.demo.index = function index(name) {};

В остальном механика таких шаблонов полностью идентичная template.

  • Директивы
  • Создание шаблона

placeholder

Директива декларирует шаблон-плейсхолдер c заданным именем и входными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области, необходима предварительная декларация namespace Отсутствует Блочная, логическая, функциональная Не требуется

Описание

Шаблон-плейсхолдер отличается от простого шаблона тем, что он существует только на этапе трансляции и не будет включён в конечный JS, например:

- namespace demo
- placeholder index(name = 'world')
	Hello {name}!
{namespace demo}
{placeholder index(name = 'world')}
	Hello {name}!
{/placeholder}

Превратится в:

В остальном механика таких шаблонов полностью идентичная template.

  • Директивы
  • Создание шаблона

block

Директива декларирует статичный блок или подшаблон c заданным именем и входными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая, функциональная Не требуется

Описание

Директива block несёт двойную функциональность: с одной стороны она позволяет создавать статичные блоки, а с другой — вызываемые. Блоки являются фундаментальной ячейкой Snakeskin, т. к. играют ключевую роль при наследовании, но если статичный блок — это просто выделение фрагмента текста, чтобы в дальнейшем иметь возможность его переопределить в дочернем шаблоне, то вызываемый блок — это по сути вложенная функция-шаблон, т. е. после декларации его можно неоднократно вызывать и передавать различные параметры.

Разница в декларации статичного блока от динамического заключается в наличии скобок для параметров, например:

- namespace demo
- template index()
	/// Статичный блок
	- block hello
		Hello world!

	/// Вызываемый блок
	- block helloWithName(name)
		Hello {name}!
{namespace demo}
{template index()}
	/// Статичный блок
	{block hello}
		Hello world!
	{/}

	/// Вызываемый блок
	{block helloWithName(name)}
		Hello {name}!
	{/}
{/template}

Параметров у блока может быть неограниченное количество, а т. к. директива block является функциональной, то она реализует стандартный механизм декларации параметров. По умолчанию вызываемые блоки возвращают строки, однако это поведение можно поменять задав специальный renderMode или явно вернув значение через директиву return.

Название блока соответствует названию функции в JavaScript, поэтому оно подчиняется тем же правилам, причём статичные блоки и вызываемые лежат в одном пространстве имён. В рамках шаблона не может быть 2-х блоков с одинаковым названием.

Блок как метод шаблона

Вызываемые блоки — это методы шаблона, т. е. они наследуются в дочерних шаблонах, могут переопределяться и т. д., а сама механика наследования практически идентична со статичными блоками и шаблонами, и описана в отдельной главе.

При создании вызываемого блока он ставиться как свойство .Blocks.названиеБлока исходного шаблона, и, как правило, вызывается с помощью директивы call и указателя self, например:

- namespace demo
- template index()
	- block hello(name)
		Hello {name}!

	+= self.hello('kobezzza')
{namespace demo}
{template index()}
	{block hello(name)}
		Hello {name}!
	{/}

	{+= self.hello('kobezzza') /}
{/template}

Примечание: this внутри блока ссылается на this шаблона.

Стандартные переменные блока

Каждый вызываемый блок определяет ряд функций, которые можно использовать в нём:

getTplResult — функция, которая возвращает результат работы блока, также может принимать один логический входной параметр, при задании которого после вызова функции результат работы блока будет обнуляться;

clearTplResult — функция, которая обнуляет результат работы блока.

Внешние блоки

Любые блоки могут декларироваться как внутри шаблона или другого блока, так и в глобальной области, но при такой декларации есть ряд дополнительных правил: блок должен декларироваться до шаблона, методом которого он является; блок должен явно указывать к какому шаблону он принадлежит (для этого используется оператор ->), например:

- namespace demo

- block index->hello(name)
	Hello {name}!

- template index()
	+= self.hello('kobezzza')
{namespace demo}

{block index->hello(name)}
	Hello {name}!
{/block}

{template index()}
	{+= self.hello('kobezzza') /}
{/template}

Такие блоки могут даже находиться в разных файлах и подключаться через include, но должны обязательно подключаться до декларации шаблона.

Самовызываемые блоки

Вызываемый блок можно вызвать немедленно после декларации: для этого используется специальный оператор =>, например:

- namespace demo

- template index()
	- block hello(name) => 'kobezzza'
		Hello {name}!
{namespace demo}

{template index()}
	{block hello(name) => 'kobezzza'}
		Hello {name}!
	{/}
{/template}

Такой же синтаксис можно использовать и для внешних блоков:

- namespace demo

- block index->hello(name) => 'kobezzza'
	Hello {name}!

- template index()
{namespace demo}

{block index->hello(name) => 'kobezzza'}
	Hello {name}!
{/block}

{template index()}
{/template}

Ссылка & для удобного рекурсивного вызова блока

При использовании call для вызова блока можно использовать специальный указать &, который ссылается на блок внутри которого он используется — это удобно для организации рекурсий, например:

- namespace demo

- template index()
	- block iterate(i)
		{i}

		- if i
			+= &(--i)

	+= self.iterate(5)
{namespace demo}

{template index()}
	{block iterate(i)}
		{i}

		{if i}
			{+= &(--i) /}
		{/}
	{/}

	{+= self.iterate(5) /}
{/template}
  • Директивы
  • Создание шаблона

set

Директива задаёт значение указанному параметру трансляции.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области @= Строковая, логическая Не требуется

Поддерживаемые параметры

  • Директивы
  • Создание шаблона

end

Директива декларирует завершение блочной директивы.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений / Строковая, логическая Не требуется

Описание

Директива используется для завершения блочной директивы в классическом синтаксисе Snakeskinjade-like) она ставиться автоматически). У директивы есть 4-ре формы использования:

/// Полная форма
{if 1 > 2}
	...
{end if}

/// Сокращённая форма
{if 1 > 2}
	...
{end}

/// Альтернативная полная форма
{if 1 > 2}
	...
{/if}

/// Альтернативная сокращённая форма
{if 1 > 2}
	...
{/}

Какую форму использовать решает сам разработчик, но следует отметить, что при использовании форм с указанием имени закрываемой директивы Snakeskin будет проверять правильность, т. е.:

{if 1 > 2}
	...
{/else} /// Ошибка
  • Директивы
  • Выполнение / вывод

output

Директива выполняет заданное выражение и выводит результат в шаблон (на выводимое выражение по умолчанию накладываются фильтры html и undef).

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Не требуется Строковая, текстовая Не требуется

Описание

Директива output используется когда нам нужно вывести в текст шаблона значение переменной или выражения.

Директива не требует специального ключевого слова (хотя допускается), поэтому достаточно просто взять выводимое выражение в фигурные скобки, например:

- namespace demo
- template calc(a, b)
	a + b = {a + b}
{namespace demo}
{template calc(a, b)}
	a + b = {a + b}
{/template}

Однако нужно следить, чтобы первое слово выводимого выражения не было равно имени другой директивы Snakeskin, иначе возникнет ошибка:

- namespace demo
- template index(link)
	{link} /// Ошибка
{namespace demo}
{template index(link)}
	{link} /// Ошибка
{/template}

Для того чтобы пример выше отработал корректно достаточно просто взять наше выражение в круглые скобки:

- namespace demo
- template index(link)
	{(link)}
{namespace demo}
{template index(link)}
	{(link)}
{/template}

Внутри output можно использовать вызовы функций, тернарные операторы и т. д.

- namespace demo
- template calc(a, b)
	{a > 1 ? --a * b : Math.random() * b}
{namespace demo}
{template calc(a, b)}
	{a > 1 ? --a * b : Math.random() * b}
{/template}

На всё выводимое выражение по умолчанию накладывается специальный фильтр html, который экранирует html сущности, а также фильтр undef на каждый отдельный чанк выражения, который преобразует значение undefined в ''. Чтобы отменить это поведение нужно использовать фильтры !html и !undef или задать глобальное через параметр трансляции filters.

- namespace demo
- template index(val1, val2)
	{(val1|!undef) + (val2|!undef) |!html}
{namespace demo}
{template index(val1, val2)}
	{(val1|!undef) + (val2|!undef) |!html}
{/template}

Директива может использоваться только внутри шаблонов или внешних блоков.

  • Директивы
  • Выполнение / вывод

call

Директива выполняет заданное выражение и выводит результат в шаблон (на выводимое выражение по умолчанию накладываются фильтр undef).

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков += Блочная, текстовая Не требуется

Описание

Директива call похожа на output, т. е. она тоже вставляет результат выражения в шаблон, однако, она не накладывает по умолчанию на выводимые данные фильтр html, т. е. выводимое выражение не экранируется и это является аналогом использования фильтра !html.

Директива начинается с ключевого слова call (или символов +=), которое должно сопровождаться ссылкой на выводимое значение или выражение (заключать выражение в скобки не обязательно), например:

- namespace demo
- template index()
	+= 1 + 2
{namespace demo}
{template index()}
	{+= 1 + 2 /}
{/template}

Для удобства использования call в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{+= 1 + 2}{/}

/// Короткая форма закрытия
{+= 1 + 2 /}

Главным кейзом использования call является вызов блоков и других шаблонов внутри шаблона, поэтому выводимые данные не экранируются, т. к. они уже и так экранированы, например:

- namespace demo

- template helper()
	< .foo
		Hello world!

- template index()
	/// <div class="foo">Hello world!</div>
	+= @helper()

	/// &lt;div class=&quot;foo&quot;&gt;Hello world!&lt;/div&gt;
	{@helper()}
{namespace demo}

{template helper()}
	{< .foo}
		Hello world!
	{/}
{/template}

{template index()}
	/// <div class="foo">Hello world!</div>
	{+= @helper() /}

	/// &lt;div class=&quot;foo&quot;&gt;Hello world!&lt;/div&gt;
	{@helper()}
{/template}

Директива может использоваться только внутри шаблонов или внешних блоков.

Расширенная декларация

Директива поддерживает специальную расширенную форму для передачи параметров-шаблонов в вызываемую функцию, например:

- namespace demo

- template helper(text)
	< .output
		{text}

- template index()
	/// <div class="output"><div class="foo">Hello world!</div></div>
	+= @helper()
		< .hello
			Hello world!
{namespace demo}

{template helper(text)}
	{< .output}
		{text}
	{/}
{/template}

{template index()}
	/// <div class="output"><div class="foo">Hello world!</div></div>
	{+= @helper()}
		{< .hello}
			Hello world!
		{/}
	{/}
{/template}

Внутри такой декларации можно использовать любые допустимые директивы, например, if, forEach и т. д. Если необходимо передать несколько параметров, то нужно использовать директиву putIn:

- namespace demo

- template helper(text1, text2)
	< .output1
		{text1}

	< .output2
		{text2}

- template index()
	+= @helper()
		*
			< .hello
				Hello world!
		*
			< .goodbye
				Goodbye cruel world!
{namespace demo}

{template helper(text1, text2)}
	{< .output1}
		{text1}
	{/}

	{< .output2}
		{text2}
	{/}
{/template}

{template index()
	{+= @helper()}
		{*}
			{< .hello}
				Hello world!
			{/}
		{/}
		{*}
			{< .goodbye}
				Goodbye cruel world!
			{/}
		{/}
	{/}
{/template}

Первый вызов putIn можно опустить:

- namespace demo

- template helper(text1, text2)
	< .output1
		{text1}

	< .output2
		{text2}

- template index()
	+= @helper()
			< .hello
				Hello world!
		*
			< .goodbye
				Goodbye cruel world!
{namespace demo}

{template helper(text1, text2)}
	{< .output1}
		{text1}
	{/}

	{< .output2}
		{text2}
	{/}
{/template}

{template index()
	{+= @helper()}
		{< .hello}
			Hello world!
		{/}
		{*}
			{< .goodbye}
				Goodbye cruel world!
			{/}
		{/}
	{/}
{/template}

Допускается совмещать передачу параметров в обычной и расширенной форме.

- namespace demo

- template helper(a, b, text1, text2)
	{a + b}

	< .output1
		{text1}

	< .output2
		{text2}

- template index()
	+= @helper(1, 2)
			< .hello
				Hello world!
		*
			< .goodbye
				Goodbye cruel world!
{namespace demo}

{template helper(a, b, text1, text2)}
	{a + b}

	{< .output1}
		{text1}
	{/}

	{< .output2}
		{text2}
	{/}
{/template}

{template index()
	{+= @helper(1, 2)}
		{< .hello}
			Hello world!
		{/}
		{*}
			{< .goodbye}
				Goodbye cruel world!
			{/}
		{/}
	{/}
{/template}

Примеры

Передача функции-параметра с помощью func

- namespace demo

- template helper(fn)
	+= fn(1, 2)

- template index()
	+= @helper()
		() => a, b
			{a + b}
{namespace demo}

{template helper(fn)}
	{+= fn(1, 2) /}
{/template}

{template index()
	{+= @helper()}
		{() => a, b}
			{a + b}
		{/}
	{/}
{/template}

Передача объекта-параметра с помощью target

- namespace demo

- template helper(@params)
	{@data}

- template index()
	+= @helper()
		- target {}
			* data
				< .hello
					Hello world!
{namespace demo}

{template helper(@params)}
	{@data}
{/template}

{template index()
	{+= @helper()}
		{target {}}
			{* data}
				{< .hello}
					Hello world!
				{/}
			{/}
		{/}
	{/}
{/template}
  • Директивы
  • Выполнение / вывод

void

Директива выполняет заданное выражение, но ничего не выводит в шаблон.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений ? Строковая, логическая Не требуется

Описание

Директива void используется когда нам нужно выполнить некоторую логику, но чтобы она никак не отобразилась в шаблоне, например, сделать инкремент переменной или вывести текст в консоль разработчика.

Директива начинается с ключевого слова void (или символа ?), которое должно сопровождаться выражением (заключать выражение в скобки не обязательно). Самая простая форма выглядит так:

- void console.log('hello')
{void console.log('hello')}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

Примеры

- namespace demo
? console.log('hello world')
- template index()
	: a = 0
	- void a++
	{a} /// 1
{namespace demo}
{? console.log('hello world')}
{template index()}
	{: a = 0}
	{void a++}
	{a} /// 1
{/template}
  • Директивы
  • Выполнение / вывод

return

Директива return является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри функциональных директив Отсутствует Блочная, логическая Не требуется

Описание

Большинство функциональных директив Snakeskin возвращают свой результат автоматически, но иногда бывает нужно вернуть определённый ответ в зависимости от условия, или если возвращаемое значение отлично от стандартного ответа Snakeskin.

Директива начинается с ключевого слова return, которое может сопровождаться ссылкой на возвращаемое значение или выражение, например:

- namespace demo
- template index()
	- return 1 + 2
{namespace demo}
{template index()}
	{return 1 + 2 /}
{/template}

Для удобства использования return в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{return 1 + 2}{/}

/// Короткая форма закрытия
{return 1 + 2 /}

Директива может использоваться только внутри функциональных директив.

Расширенная декларация

Директива может включать возвращаемое значение в своё тело — это удобно, когда возвращаемое значение является подшаблоном, например:

- namespace demo
- template index()
	/// Шаблон вернёт ссылку на функцию,
	/// которая складывает два числа
	- return
		() => a, b
			- return a + b
{namespace demo}
{template index()}
	/// Шаблон вернёт ссылку на функцию,
	/// которая складывает два числа
	{return}
		{() => a, b}
			{return a + b /}
		{/}
	{/}
{/template}

Внутри такой декларации можно использовать любые допустимые директивы, например, if, forEach и т. д.

  • Директивы
  • Глобальный контекст

eval

Директива создаёт блок, который выполнится на этапе трансляции, но не войдёт в конечный JS.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области Отсутствует Блочная, логическая Не требуется

Описание

Т.к. любой код, размещённый вне тела шаблона будет выполняться как на этапе трансляции, так и войдёт в конечный JS код, то директива eval позволяет создать блок, содержимое которого будет исключаться из результирующего кода, но по прежнему будет выполняться на этапе трансляции.

- eval
	? console.log('Hello world!')
{eval}
	{? console.log('Hello world!')}
{/}

Директива может использоваться только в глобальной области.

  • Директивы
  • Глобальный контекст

head

Директива создаёт блок, который не выполнится на этапе трансляции, но войдёт в конечный JS.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области Отсутствует Блочная, логическая Не требуется

Описание

Т.к. любой код, размещённый вне тела шаблона будет выполняться как на этапе трансляции, так и войдёт в конечный JS код, то директива head позволяет создать блок, содержимое которого по прежнему не будет исключаться из результирующего кода, но не будет выполняться на этапе трансляции, а также переменные, которые были объявлены на корневом уровне директивы, будут считаться глобальными.

- namespace demo

- head
	/// Данный forEach не выполнится на этапе трансляции,
	/// но войдёт в конечный JS
	- forEach [1, 2, 3] => el
		? console.log(el)

	/// Данная переменная глобальная,
	/// хоть и объявлена внутри блочной директивы
	: foo = 'bar'

- template index()
	? console.log(foo) /// 'bar'
{namespace demo}

{head}
	/// Данный forEach не выполнится на этапе трансляции,
	/// но войдёт в конечный JS
	{forEach [1, 2, 3] => el}
		{? console.log(el)}
	{/}

	/// Данная переменная глобальная,
	/// хоть и объявлена внутри блочной директивы
	{var a = 1 /}
{/}

{template index()}
	{? console.log(foo)} /// 'bar'
{/template}

Директива может использоваться только в глобальной области.

  • Директивы
  • Область видимости

with

Директива задаёт область видимости для поиска свойств объекта.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива позволяет задать «виртуальную» область видимости для объекта, чтобы затем обращаться к его свойствам с помощью специального модификатора контекста @, например:

- var base = {child: {name: 'Moscow'}}

- with base.child
	? console.log(@name) /// Moscow
{var base = {child: {name: 'Moscow'}}}

{with base.child}
	{? console.log(@name)} /// Kobezzza
{/}

С помощью @ можно как получать, так и устанавливать свойства объекту.

- var base = {child: {name: 'Moscow'}}

- with base.child
	? @name = 'Washington'
	? @type = 'city'

? console.log(base.child.name) /// Washington
? console.log(base.child.type) /// city
{var base = {child: {name: 'Moscow'}}}

{with base.child}
	{? console.log(@name)} /// Kobezzza
	{? @name = 'Washington'}
{/}

{console.log(base.child.name)} /// Washington

Любые входные параметры функциональных директив Snakeskin (template, forEach и т. д.) поддерживают короткую запись декларации with.

- namespace demo
- template index(@params)
	{@name} /// params.name
{namespace demo}
{template index(@params)}
	{@name} /// params.name
{/template}

Такая запись эквивалентна:

- namespace demo
- template index(params)
	- with params
		{@name}
{namespace demo}
{template index(params)}
	{with params}
		{@name}
	{/}
{/template}

Можно вкладывать with-блоки друг в друга, например:

- namespace demo
- template index()
	- with params
		{@name} /// params.name
		- with @data
			{@type} /// params.data.type
{namespace demo}
{template index(params)}
	{with params}
		{@name} /// params.name
		{with params}
			{@type} /// params.data.type
		{/}
	{/}
{/template}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

  • Директивы
  • Переменные

var

Директива создаёт переменную/ые с указанным именем и значением.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений : Блочная, логическая Не требуется

Описание

Переменные в Snakeskin имеют блочную область видимости и по своей семантике напоминают let из JS ES2015.

Директива var позволяет декларировать сразу несколько переменных через запятую (аналогично как это делается в JS).

Директива начинается с ключевого слова var (или символа :), которое должно сопровождаться списком имён создаваемых переменных (через запятую). Для присвоения значений созданной переменной необходимо поставить символ = после имени.

Самая простая форма выглядит так:

- var a = 1
{var a = 1 /}

Для удобства использования var в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{var a = 1}{/}

/// Короткая форма закрытия
{var b = 2 /}

В отличии от JS переменные в Snakeskin декларируются только после места декларации.

: a = 2
- if true
	? console.log(a) /// 2
	: a = 1
	? console.log(a) /// 1
{: a = 2 /}
{if true}
	{? console.log(a)} /// 2
	{: a = 1 /}
	{? console.log(a)} /// 1
{/}

Допускается в рамках одного блока создавать переменные с одинаковым именем.

: a = 2
? console.log(a) /// 2
: a = 1
? console.log(a) /// 1
{: a = 2 /}
{? console.log(a)} /// 2
{: a = 1 /}
{? console.log(a)} /// 1

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

putIn декларация

С помощью ключевого слова putIn можно присвоить переменной подшаблон Snakeskin, однако при такой декларации допускается создавать только одну переменную за раз, например:

- namespace demo
- template index(value)
	: putIn tpl
		- if value !== 404
			< .hello
				Hello world!

		- else
			< .error
				404
{namespace demo}
{template index(value)}
	{: putIn tpl}
		{if value !== 404}
			{< .hello}
				Hello world!

		{else}
			{< .error}
				404
			{/}
		{/}
	{/}
{/template}

Внутри такой декларации можно использовать любые допустимые директивы, например, if, forEach и т. д.

Примеры

- namespace demo
- template index(value)
	- if true
		: a = 1
		{a}

	{a} /// Error, a is not defined

	: b = 1, c = 2
	- if true
		{b} /// 1
		{c} /// 2

	{b} /// 1
{namespace demo}
{template index(value)}
	{if true}
		{: a = 1 /}
		{a}
	{/}

	{a} /// Error, a is not defined

	{: b = 1, c = 2 /}
	{if true}
		{b} /// 1
		{c} /// 2
	{/}

	{b} /// 1
{/template}
  • Директивы
  • Переменные

const

Директива создаёт константу с указанным именем и значением.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Не требуется Строковая, текстовая / логическая Не требуется

Описание

Константы Snakeskin не имеют ничего общего с константами из JS ES2015 и служат для других целей. Константы глобальны в рамках своего шаблона, поэтому не может быть 2-х констант с одинаковым именем. Значение константы может меняться по ходу выполнения шаблона.

При декларации константы не требуется специального ключевого слова (хотя допускается), например:

- namespace demo
- template index()
	- val = 'hello'
	{val}
{namespace demo}
{template calc(a, b)}
	{val = 'hello'}
	{val}
{/template}

С логической точки зрения константы Snakeskin — это свойства класса (шаблона), т. е. они доступны в любом месте шаблона и их можно переопределять в дочернем шаблоне. Константа может быть свойством объекта (включая свойство другой константы), например:

- namespace demo
- template index()
	- val = {}
	- val.name = 'Kobezzza'
{namespace demo}
{template calc(a, b)}
	{val = {}}
	{val.name = 'Kobezzza'}
{/template}

После декларации константы станет невозможным в рамках шаблона объявление переменной с таким же именем.

- namespace demo
- template index()
	- val = {}
	- var val = 1 /// Ошибка
{namespace demo}
{template calc(a, b)}
	{val = {}}
	{var val = 1 /} /// Ошибка
{/template}

Константы могут создаваться только внутри шаблонов или внешних блоков.

Распад константы

Если любая функциональная директива содержит параметр с именем равным константе, то он «замещает» константу в рамках своей блочной области видимости, например:

- namespace demo
- template index()
	- val = {}
	- forEach [1, 2] => val
		{val} /// 1, 2
{namespace demo}
{template calc(a, b)}
	{val = {}}
	{forEach [1, 2] => val}
		{val} /// 1, 2
	{/}
{/template}

Вызываемые константы

Если в конце декларации константы поставить символ ?, то её значение сразу же выведется в шаблон.

- namespace demo
- template index()
	< title
		- title = 'Главная страница' ?
{namespace demo}
{template calc(a, b)}
	{< title}
		{title = 'Главная страница' ?}
	{/}
{/template}
  • Директивы
  • Переменные

global

Директива создаёт супер-глобальную переменную с указанным именем и значением.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Не требуется Строковая, текстовая / логическая Не требуется

Описание

Супер-глобальная переменная Snakeskin — это свойство объекта Snakeskin.Vars, т. е. такая переменная доступна как из JavaScript, так и во всех файлах шаблонов. Устанавливать такие переменные можно из JS (причём можно до трансляции) или из шаблонов. Основной use-case супер-глобальных переменных — это прокидывание конфига, т. е. некоторый аналог переменных среды в операционной системе.

Задание из JS

Чтобы задать значение супер-глобальной переменной перед непосредственной трансляцией можно использовать параметр vars, а также в любой момент времени допускается вносить изменения напрямую в объект Snakeskin.Vars, например:

Snakeskin.Vars.server = 'localhost';
Snakeskin.Vars.port = '1989';

Задание и чтение из SS

Для задания супер-глобальной переменной из SS можно использовать несколько способов:

  1. Использование директивы global, например:
- global server = 'localhost'
- global port = '1989'
{global server = 'localhost'}
{global port = '1989'}

Вне тела шаблонов можно опустить ключевое слово global:

- server = 'localhost'
- port = '1989'
{server = 'localhost'}
{port = '1989'}

При задании имение допускается использовать скобочную нотацию:

- ['server'] = 'localhost'
- ['port'] = '1989'
{['server'] = 'localhost'}
{['port'] = '1989'}
  1. Использование литеральной формы через модификатор @@, например:
- @@server = 'localhost'
- @@port = '1989'
{@@server = 'localhost'}
{@@port = '1989'}

Такой вариант можно использовать как вне шаблонов, так и внутри их. Литеральная форма также поддерживает скобочную нотацию:

- @@['server'] = 'localhost'
- @@['port'] = '1989'
{@@['server'] = 'localhost'}
{@@['port'] = '1989'}

Чтение

Для чтения супер-глобальных переменных используется модификатор @@, например:

- @@server = 'localhost'
? console.log(@@server)
{@@server = 'localhost'}
{? console.log(@@server)}

Вызываемые переменные

Если в конце декларации супер-глобальной переменной поставить символ ?, то её значение сразу же выведется в шаблон.

- namespace demo
- template index()
	< title
		- @@title = 'Главная страница' ?
{namespace demo}
{template calc(a, b)}
	{< title}
		{@@title = 'Главная страница' ?}
	{/}
{/template}
  • Директивы
  • Логические директивы

if

Директива if является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива позволяет вашему шаблону в зависимости от условий выполнить некоторую логику или сгенерировать фрагмент шаблона, основываясь на значении переменной или выражения.

Директива начинается с ключевого слова if, которое должно сопровождаться выражением (заключать выражение в скобки не обязательно).

Самая простая форма выглядит так:

- if true
	Hello world!
{if true}
	Hello world!
{/if}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Вместе с основной директивой можно использовать дополнительные:

  1. else — аналог else в JS;
  2. else if — аналог else if в JS;
  3. else unless — аналог else if (!(...)) в JS.

Примеры

- namespace demo
- template index(value)
	< .result
		- if val > 3
			< .success
				Значение больше чем 3.

		- else if val < 3
			< .fail
				Значение меньше чем 3.

		- else
			< .error
				Значение рано 3.
{namespace demo}
{template index(value)}
	{< .result}
		{if val > 3}
			{< .success}
				Значение больше чем 3.
			{/}

		{else if val < 3}
			{< .fail}
				Значение меньше чем 3.
			{/}

		{else}
			{< .error}
				Значение рано 3.
			{/}
		{/}
	{/}
{/template}
  • Директивы
  • Логические директивы

unless

Директива unless является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в CoffeeScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива является инвертной формой if, т. е. если if блок выполнится только в том случае когда условное выражение будет приведено к true, то unless выполнится в случае false.

Директива позволяет вашему шаблону в зависимости от условий выполнить некоторую логику или сгенерировать фрагмент шаблона, основываясь на значении переменной или выражения.

Директива начинается с ключевого слова unless, которое должно сопровождаться выражением (заключать выражение в скобки не обязательно).

Самая простая форма выглядит так:

- unless false
	Hello world!
{unless false}
	Hello world!
{/}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Вместе с основной директивой можно использовать дополнительные:

  1. else — аналог else в JS;
  2. else if — аналог else if в JS;
  3. else unless — аналог else if (!(...)) в JS.

Примеры

- namespace demo
- template index(value)
	< .result
		- unless val >= 3
			< .success
				Значение меньше чем 3.

		- else unless val <= 3
			< .fail
				Значение больше чем 3.

		- else
			< .error
				Значение рано 3.
{namespace demo}
{template index(value)}
	{< .result}
		{unless val >= 3}
			{< .success}
				Значение меньше чем 3.

		{else unless val <= 3}
			{< .fail}
				Значение больше чем 3.

		{else}
			{< .error}
				Значение рано 3.
		{/}
	{/}
{/template}
  • Директивы
  • Логические директивы

switch

Директива switch является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript (break ставится автоматически после каждого блока case).

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений > (для case) Блочная, логическая Не требуется

Описание

Подобно if или unless директива позволяет вашему шаблону в зависимости от условий выполнить некоторую логику или сгенерировать фрагмент шаблона, основываясь на значении переменной или выражения, но предоставляет более удобный синтаксис когда нужно сравнить выражение сразу с несколькими вариантами.

Директива начинается с ключевого слова switch, которое должно сопровождаться выражением (заключать выражение в скобки не обязательно), а внутри директивы должны использоваться вспомогательные директивы case и/или default. Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

Директива case начинается с ключевого слова case (или символа >), а после должно следовать выражение выражение для сравнения со switch. В отличии от реализации case в JS — оператор break ставиться автоматически после каждого блока.

Декларация default полностью идентичная аналогичной в JS.

Примеры

- namespace demo
- template index(value)
	< .result
		- switch value
			- case 1
				< .value-1
					value == 1

			- case 2
				< .value-2
					value == 2

			> 3
				< .value-3
					value == 3

			- default
				Условие, которое выполнится по умолчанию.
{namespace demo}
{template index(value)}
	{< .result}
		{switch value}
			{case 1}
				{< .value-1}
					value == 1
				{/}
			{/}

			{case 2}
				{< .value-2}
					value == 2
				{/}
			{/}

			{> 3}
				{< .value-3}
					value == 3
				{/}
			{/}

			{default}
				Условие, которое выполнится по умолчанию.
			{/}
		{/}
	{/}
{/template}
  • Директивы
  • Циклы

for

Директива for является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива создаёт цикл, т. е. блок цикла будет выполняется до тех пор, пока управляющее логическое выражение не станет ложным или пока цикл не будет сброшен вручную. Директива проводит инициализацию перед первым шагом цикла. Затем выполняется проверка условия цикла, и в конце каждой итерации происходит изменение управляющей переменной.

for инициализация; логическое выражение (условие); шаг (итерация)
	команда

Самая простая форма выглядит так:

- for var i = 0; i < 3; i++
	Итерация - {i}
{for var i = 0; i < 3; i++}
	Итерация - {i}
{/for}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Для управления циклом внутри блока можно использовать директивы:

  1. break — полностью прерывает выполнение цикла;
  2. continue — прерывает текущую итерацию и переходит к следующей.

Примеры

Простой перебор массива

- namespace demo
- template index()
	- var arr = [1, 2, 3]

	/// Т.к. переменные Snakeskin имеют блочную область видимости,
	/// то i будет доступен только внутри for
	- for var i = 0; i < arr.length; i++
		{arr[i]}
{namespace demo}
{template index()}
	{var arr = [1, 2, 3] /}

	/// Т.к. переменные Snakeskin имеют блочную область видимости,
	/// то i будет доступен только внутри for
	{for var i = 0; i < arr.length; i++}
		{arr[i]}
	{/}
{/template}

Простой перебор объекта

- namespace demo
- template index()
	- var obj = {a: 1, b: 2}

	/// Т.к. переменные Snakeskin имеют блочную область видимости,
	/// то key будет доступен только внутри for
	- for var key in obj
		{key}
{namespace demo}
{template index()}
	{var obj = {a: 1, b: 2} /}

	/// Т.к. переменные Snakeskin имеют блочную область видимости,
	/// то key будет доступен только внутри for
	{for var key in obj}
		{key}
	{/}
{/template}

Сброс итераций

- namespace demo
- template index()
	- var obj = {a: 1, b: 2}
	- for var key in obj
		- if !obj.hasOwnProperty(key)
			- continue

		{key}
		- break
{namespace demo}
{template index()}
	{var obj = {a: 1, b: 2} /}
	{for var key in obj}
		{if !obj.hasOwnProperty(key)}
			{continue}
		{/}

		{key}
		{break}
	{/}
{/template}
  • Директивы
  • Циклы

while

Директива while является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива создаёт цикл, т. е. блок цикла будет выполняется до тех пор, пока управляющее логическое выражение не станет ложным или пока цикл не будет сброшен вручную.

Директива начинается с ключевого слова while, которое должно сопровождаться выражением (заключать выражение в скобки не обязательно).

Самая простая форма выглядит так:

- var i = 3
- while i--
	{i}
{var i = 3 /}
{while i--}
	{i}
{/while}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Для управления циклом внутри блока можно использовать директивы:

  1. break — полностью прерывает выполнение цикла;
  2. continue — прерывает текущую итерацию и переходит к следующей.

Примеры

Перебор массива

- namespace demo
- template index()
	- var arr = [1, 2, 3]
	- while arr.length
		{arr[0]}
		? arr.shift()
{namespace demo}
{template index()}
	{var arr = [1, 2, 3] /}
	{while arr.length}
		{arr[0]}
		{? arr.shift()}
	{/}
{/template}

Сброс итераций

- namespace demo
- template index()
	- var i = 3
	- while i--
		{i}
		- break
{namespace demo}
{template index()}
	{var i = 3 /}
	{while i--}
		{i}
		{break}
	{/}
{/template}
  • Директивы
  • Циклы

do

Директива do является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива создаёт цикл, т. е. блок цикла будет выполняется до тех пор, пока управляющее логическое выражение не станет ложным или пока цикл не будет сброшен вручную. Отличие do от while состоит в том, что цикл do-while выполняется по крайней мере один раз, даже если условие изначально ложно.

Директива начинается с ключевого слова do, а выражение для проверки идёт после вложенного блока цикла вместе с директивой while (заключать выражение в скобки не обязательно).

Самая простая форма выглядит так:

- var i = 3
- do
	{i}
- while i--
{var i = 3 /}
{do}
	{i}
{while i--}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Для управления циклом внутри блока можно использовать директивы:

  1. break — полностью прерывает выполнение цикла;
  2. continue — прерывает текущую итерацию и переходит к следующей.

Примеры

Перебор массива

- namespace demo
- template index()
	- var arr = [1, 2, 3]
	- do
		{arr[0]}
		? arr.shift()
	- while arr.length
{namespace demo}
{template index()}
	{var arr = [1, 2, 3] /}
	{do}
		{arr[0]}
		{? arr.shift()}
	{while arr.length}
{/template}

Бесконечный цикл

- namespace demo
- template index()
	- var i = 0
	- do
		{i}
		? i++
{namespace demo}
{template index()}
	{var i = 0 /}
	{do}
		{i}
		{? i++}
	{/}
{/template}

Сброс итераций

- namespace demo
- template index()
	- var i = 3
	- do
		{i}
		- break
	- while i--
{namespace demo}
{template index()}
	{var i = 3 /}
	{do}
		{i}
		{break}
	{while i--}
{/template}
  • Директивы
  • Итераторы

forEach

Директива итерирует заданный объект (с учётом hasOwnProperty) или массив.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая, функциональная Не требуется

Описание

Директива итерирует заданное значение с помощью функции Snakeskin.forEach и может работать как с объектами, так и с массивами.

Общая форма директивы следующая:

forEach ссылка на объект или сам объект => параметры функции через запятую
	команда

Например:

- forEach [1, 2, 3] => el
	{el}
{forEach [1, 2, 3] => el}
	{el}
{/forEach}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области, а т. к. forEach является функциональной директивой, то он реализует стандартный механизм декларации параметров.

Для управления обходом внутри итератора можно использовать директивы:

  1. break — полностью прерывает выполнение итератора;
  2. continue — прерывает текущую итерацию и переходит к следующей.

Параметры для массива

  1. Значение элемента;
  2. Номер итерации;
  3. Ссылка на итерируемый массив;
  4. Объект:
    • isFirst — является ли элемент первым;
    • isLast — является ли элемент последним;
    • length — длина массива.

Параметры для таблицы

  1. Значение элемента;
  2. Ключ;
  3. Ссылка на итерируемый объект;
  4. Объект:
    • i — номер итерации;
    • isFirst — является ли элемент первым;
    • isLast — является ли элемент последним;
    • length — длина массива.

forEach и return

Несмотря на то что forEach использует функцию при обходе объекта, поведение директивы приближено к поведению цикла, т. е. внутри можно использовать директивы break, continue и return, принцип работы которых не будет отличаться, например:

- namespace demo

/// Шаблон вернёт 1
- template index()
	- forEach [1, 2, 3] => el
		- return el
	Hello world
{namespace demo

/// Шаблон вернёт 1
{template index()}
	{forEach [1, 2, 3] => el}
		{return el /}
	Hello world

Примеры

Простой перебор массива

- namespace demo
- template index()
	- var arr = [1, 2, 3]
	- forEach arr => el
		{el}
{namespace demo}
{template index()}
	{var arr = [1, 2, 3] /}
	{forEach arr => el}
		{el}
	{/}
{/template}

Перебор массива с заданием with в списке входных параметров

- namespace demo
- template index()
	- var arr = [{name: 'Koba'}, {name: 'Over'}]
	- forEach arr => @el
		{@name}
{namespace demo}
{template index()}
	{var arr = [{name: 'Koba'}, {name: 'Over'}] /}
	{forEach arr => @el}
		{@name}
	{/}
{/template}

Простой перебор объекта

- namespace demo
- template index()
	- var obj = {a: 1, b: 2}
	- forEach obj => el, key
		{el} {key}
{namespace demo}
{template index()}
	{var obj = {a: 1, b: 2} /}
	{forEach obj => el, key}
		{el} {key}
	{/}
{/template}

Сброс итераций

- namespace demo
- template index()
	- forEach [1, 2, 3] => el
		{el}
		- break
{namespace demo}
{template index()}
	{forEach [1, 2, 3] => el}
		{el}
		{break}
	{/}
{/template}
  • Директивы
  • Итераторы

forIn

Директива итерирует заданный объект (без учёта hasOwnProperty).

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая, функциональная Не требуется

Описание

Директива итерирует заданный объект с помощью функции Snakeskin.forIn.

Общая форма директивы следующая:

forIn ссылка на объект или сам объект => параметры функции через запятую
	команда

Например:

- forIn {a: 1, b: 2} => el
	{el}
{forIn {a: 1, b: 2} => el}
	{el}
{/forIn}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области, а т. к. forIn является функциональной директивой, то он реализует стандартный механизм декларации параметров.

Для управления обходом внутри итератора можно использовать директивы:

  1. break — полностью прерывает выполнение итератора;
  2. continue — прерывает текущую итерацию и переходит к следующей.

Параметры функции итератора

  1. Значение элемента;
  2. Ключ;
  3. Ссылка на итерируемый объект;
  4. Объект:
    • i — номер итерации;
    • isFirst — является ли элемент первым;
    • isLast — является ли элемент последним;
    • length — длина массива.

forIn и return

Несмотря на то что forIn использует функцию при обходе объекта, поведение директивы приближено к поведению цикла, т. е. внутри можно использовать директивы break, continue и return, принцип работы которых не будет отличаться, например:

- namespace demo

/// Шаблон вернёт 1
- template index()
	- forIn {a: 1, b: 2} => el
		- return el
	Hello world
{namespace demo

/// Шаблон вернёт 1
{template index()}
	{forIn {a: 1, b: 2} => el}
		{return el /}
	Hello world

Примеры

Простой перебор

- namespace demo
- template index()
	- var obj = {a: 1, b: 2}
	- forIn obj => el, key
		{el} {key}
{namespace demo}
{template index()}
	{var obj = {a: 1, b: 2} /}
	{forIn obj => el, key}
		{el} {key}
	{/}
{/template}

Перебор с заданием with в списке входных параметров

- namespace demo
- template index()
	- var obj = {a: {name: 'Koba'}, b: {name: 'Over'}}
	- forIn obj => @el
		{@name}
{namespace demo}
{template index()}
	{var obj = {a: {name: 'Koba'}, b: {name: 'Over'}} /}
	{forEach obj => @el}
		{@name}
	{/}
{/template}

Сброс итераций

- namespace demo
- template index()
	- forEach {a: 1, b: 2, c: 3} => el
		{el}
		- break
{namespace demo}
{template index()}
	{forEach {a: 1, b: 2, c: 3} => el}
		{el}
		{break}
	{/}
{/template}
  • Директивы
  • Работа с исключениями

try

Директива try является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива позволяет вашему шаблону отлавливать и обрабатывать исключения, которые могут возникать по ходу выполнения программы на Snakeskin.

Самая простая форма выглядит так:

- try
	? 1 2
{try}
	{1 2}
{/try}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Вместе с основной директивой можно использовать дополнительные:

  1. catch — аналог catch в JS (функциональная директива);
  2. finally — аналог finally в JS.

Примеры

- namespace demo
- template index(value)
	< .result
		- try
			? value = JSON.parse(value)

		- catch err
			? console.error(err)

		- finally
			Hello world!
{namespace demo}
{template index(value)}
	{< .result}
		{try}
			{? value = JSON.parse(value)}

		{catch err}
			{? console.error(err)}

		{finally}
			Hello world!
		{/}
	{/}
{/template}
  • Директивы
  • Работа с исключениями

throw

Директива throw является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Строковая, логическая Не требуется

Описание

Директива генерирует заданное исключение и начинается с ключевого слова throw, которое должно сопровождаться выражением. Самая простая форма выглядит так:

- throw new Error('Ошибка')
{throw new Error('Ошибка')}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

Примеры

- namespace demo
- template index(value)
	< .result
		- if value > 1
			- throw new Error('Invalid value')
{namespace demo}
{template index(value)}
	{< .result}
		{if value > 1}
			{throw new Error('Invalid value')}
		{/}
	{/}
{/template}
  • Директивы
  • Работа с пробельными символами

ignoreWhitespaces

Директива декларирует, что все последующие пробельные символы до первого не пробельного должны игнорироваться.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков & Строковая, логическая Не требуется

Примеры

- namespace demo
- template index(value, area)
	Hello{&}             World Bar
{namespace demo}
{template index(value, area)}
	Hello{&}             World Bar
{/template}

Отрендерится как:

HelloWorld Bar
  • Директивы
  • Работа с пробельными символами

ignoreAllWhitespaces

Директива декларирует, что все вложенные в директиву пробельные символы должны игнорироваться.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков &+ Блочная, логическая Не требуется

Примеры

- namespace demo
- template index(value, area)
	&+
		Hello             World Bar
{namespace demo}
{template index(value, area)}
	{&+}
		Hello             World Bar
	{/}
{/template}

Отрендерится как:

HelloWorldBar
  • Директивы
  • Работа с пробельными символами

unIgnoreAllWhitespaces

Директива декларирует, что все вложенные в директиву пробельные символы не должны игнорироваться (обычно используется вместе с ignoreAllWhitespaces).

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков &- Блочная, логическая Не требуется

Примеры

- namespace demo
- template index(value, area)
	&+
		Hello             World Bar
		&-
			Hello             World Bar
{namespace demo}
{template index(value, area)}
	{&+}
		Hello             World Bar
		{&-}
			Hello             World Bar
		{/}
	{/}
{/template}

Отрендерится как:

HelloWorldBarHello World Bar
  • Директивы
  • Работа с пробельными символами

sp

Директива вставляет в шаблон пробельный символ (актуально только для Jade-Like).

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков \ Строковая, текстовая Не требуется

Примеры

- namespace demo
- template index(value, area)
	< .foo
	\
	< .bar

Отрендерится как:

<div class="foo"></div> <div class="bar"></div>
  • Директивы
  • Работа с HTML/XML

doctype

Директива вставляет в шаблон код декларации заданного doctype, а также определяет правила форматирования для тегов и атрибутов.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Отсутствует Строковая, текстовая Не поддерживается

Описание

Директива предназначена для указания типа текущего документа — DTD (document type definition, описание типа документа). Это необходимо, чтобы клиент/парсер понимал, как следует интерпретировать текущую страницу, а также указывает Snakeskin какие правила он должен применять при генерации кода тегов и атрибутов.

Директива может использоваться только внутри шаблонов или внешних блоков.

Таблица обозначений

html

<!DOCTYPE html>

xml

<?xml version="1.0" encoding="utf-8" ?>

transitional

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

strict

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

frameset

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

1.1

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

basic

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">

mobile

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">

mathml 1.0

<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">

mathml 2.0

<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">

svg 1.0

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">

svg 1.1 full

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

svg 1.1 basic

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">

svg 1.1 tiny

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">

Примеры

Использование значения по умолчанию (html5)

- namespace demo
- template index(value)
	- doctype
{namespace demo}
{template index(value)}
	{doctype}
{/template}

Явное указание типа

- namespace demo
- template index(value)
	- doctype xml
{namespace demo}
{template index(value)}
	{doctype xml}
{/template}
  • Директивы
  • Работа с HTML/XML

attr

Директива вставляет в шаблон код декларации HTML/XML атрибута по заданным параметрам.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Отсутствует Строковая, текстовая Поддерживается

Описание

Директива attr обычно используется для задания атрибутов вместе с директивой tag. Общая форма директивы следующая:

attr название атрибута = значение атрибута

Например:

- attr foo = bar
{attr foo = bar}

Обратите внимание, что крайние пробелы у символа = важны, иначе он трактуется как простой текст. Директива может использоваться только внутри шаблонов или внешних блоков.

Множественное задание атрибутов

Если необходимо задать несколько атрибутов, то нужно использовать специальный разделитель |, например:

- attr foo = bar | baz = bla
{attr foo = bar | baz = bla}

Обратите внимание, что крайние пробелы у символа | важны, иначе он трактуется как простой текст.

- attr foo = bar|baz=bla
{attr foo = bar|baz=bla}

Атрибуты с пустым значением

Если нужно задать атрибут с пустым значением, то достаточно просто ничего не писать после знака присвоения, например:

- attr alt =
{attr alt =}

Отрендерится как:

alt=""

Инлайновые атрибуты

Для задания «инлайновых» HTML атрибутов, например, <input disabled> нужно просто опустить знак присвоения.

- attr disabled
{attr disabled}

Задание data- атрибутов

Для декларации data- атрибутов поддерживается короткий синтаксис:

- attr -title = bla | -desc-field = bar
{attr -title = bla | -desc-field = bar}

Однако можно писать и полную форму:

- attr data-title = bla
{attr data-title = bla}

Группы атрибутов

В Snakeskin есть универсальный синтаксис для создания групп атрибутов с автоматическим добавлением указанного префикса, общая форма следующая:

attr опциональный префикс(( название атрибута = значение атрибута ))

Например:

- attr ng-(( repeat = el in data | bind = bla ))
{attr ng-(( repeat = el in data | bind = bla ))}

Отрендерится как:

ng-repeat="el in data" ng-bind="bla"

Обратите внимание, что крайние пробелы у символов (( и )) важны, иначе они трактуется как простой текст. Также следует отметить, что при комбинировании групп атрибутов с другими группами не нужно ставить специальный разделитель, например:

- attr ng-(( repeat = foo of bla )) (( baz = bar )) hello = world | foo = bar
{attr ng-(( repeat = foo of bla )) (( baz = bar )) hello = world | foo = bar}

Интерполяция

Для передачи значений Snakeskin внутрь директивы используется стандартный механизм интерполяции, например:

- var name = 'foo'
- attr ${name} = ${1 + 2}
{var name = 'foo' /}
{attr ${name} = ${1 + 2}}

Допускается смешивать интерполяцию с обычной декларацией:

- var name = 'foo'
- attr ${name}-bar = ${1 + 2} hello
{var name = 'foo' /}
{attr ${name}-bar = ${1 + 2} hello}

Интерполяция объекта

Snakeskin позволяет используя механизм интерполяции задать атрибуты с помощью объекта, где ключом является название атрибута или группы.

- var attrs = {foo: 'bar', 'ng-': {repeat: 'el in data'}}
- attr ${attrs}
{var attrs = {foo: 'bar', 'ng-': {repeat: 'el in data'}} /}
{attr ${attrs}}

Чтобы сделать атрибут «инлайновым» нужно использовать специальную константу TRUE:

- var attrs = {disabled: TRUE}
- attr ${attrs}
{var attrs = {disabled: TRUE} /}
{attr ${attrs}}

Отрендерится как:

disabled

А чтобы исключить, то нужно использовать константу FALSE:

- var attrs = {disabled: FALSE}
- attr ${attrs}
{var attrs = {disabled: FALSE} /}
{attr ${attrs}}

Значение ключа автоматически переводится из camelCase в dash-style, например:

- attr ${{fooBarBla: 'baz'}}
{attr ${{fooBarBla: 'baz'}}}

Отрендерится как:

foo-bar-bla="baz"

Экранирование

Для экранирования спецсимволов директивы используется символ \, например:

- attr foo = bar \= bla
{attr foo = bar \= bla}
  • Директивы
  • Работа с HTML/XML

tag

Директива вставляет в шаблон код декларации HTML/XML тега по заданным параметрам.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков < Блочная, текстовая Поддерживается

Описание

Директива tag является универсальным инструментом для генерации XML подобных структур. Общая форма директивы следующая:

tag название директивы

Например:

- tag span
< span
{tag span}{/tag}
{< span}{/}

При использовании tag в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{tag input type = text}{/}

/// Короткая форма закрытия
{tag input type = text /}

Директива может использоваться только внутри шаблонов или внешних блоков.

Создание элемента с заданием классов и ИД

Для удобного задания классов и ИД-а в tag используется синтаксис селекторов CSS, например:

< span#baz.foo.bar
/// Если не указать имя создаваемого тега,
/// то будет использоваться div
< .bla
{< span#baz.foo.bar}{/}
/// Если не указать имя создаваемого тега,
/// то будет использоваться div
{< .bla}{/}

Задание произвольных атрибутов

Директива tag поддерживает задание атрибутов с помощью attr, например:

< input value = foo | disabled
{< input value = foo | disabled /}

Отрендерится как:

<input value="foo" disabled>

Ссылки на родительский класс

В Snakeskin существует специальный механизм получения значения родительского класса в дочернем теге, который называется «липкая ссылка». Принцип работы следующий: если при декларации тега задать имя класса, которое начинается с символа &, то он будет заменён на ближайший родительский класс, который декларировался без этого символа, например:

< .foo
	< .&__bar
	< .&__bla
{< .foo}
	{< .&__bar}{/}
	{< .&__bla}{/}
{/}

Отрендерится как:

<div class="foo">
	<div class="foo__bar"></div>
	<div class="foo__bla"></div>
</div>

Ссылка на родительский класс в произвольном атрибуте

Альтернативным способом получения липкой ссылки является вызов внутренней переменной шаблона $class, например:

< .foo value = ${$class}
{< .foo value = ${$class}}{/}

Отрендерится как:

<div class="foo" value="foo"></div>

Локальные ссылки

Если поместить декларацию класса в специальную конструкцию [...], то классы заданные внутри такого блока не будут запоминаться как липкая ссылка, а также плейсхолдер & будет ссылаться на ближайший по иерархии вложенности класс слева.

< .b-button[.g-helper]
	< button.&__elem[.&_focused_true]
{< .b-button[.g-helper]}
	{< button.&__elem[.&_focused_true]}{/}
{/}

Отрендерится как:

<div class="b-button g-helper">
	<button class="b-button__elem b-button__elem_focused_true"></button>
</div>

Тег-плейсходер

Специальный тег ? существует только на этапе трансляции и не включается в конечный код, например:

< ?.b-button
	< button.&__elem
{< ?.b-button}
	{< button.&__elem}{/}
{/}

Отрендерится как:

<button class="b-button__elem"></button>

Интерполяция

Для передачи значений Snakeskin внутрь директивы используется стандартный механизм интерполяции, например:

- var name = 'span'
< ${name}
{var name = 'foo' /}
{< ${name}}{/}

Допускается смешивать интерполяцию с обычной декларацией:

- var name = 'foo'
< .${name}-bla.bar
{var name = 'foo' /}
{< .${name}-bla.bar}{/}

Для интерполяции в атрибутах используется механизмы attr.

Интерполяция и тег-плейсхолдер

< ${'?'}.b-button
	< button.&__elem
{< ${'?'}.b-button}
	{< button.&__elem}{/}
{/}

Отрендерится как:

<button class="b-button__elem"></button>

«Инлайновые» теги

В HTML ряд тегов не требуют закрывающей части (</tag>), например, input или meta, причём если в XHTML такие теги закрываются явно, например:

<input type="text" />

То в HTML это можно опустить:

<input type="text">

Snakeskin знает про такие теги, а способ их закрытия зависит от выбранного doctype. Правила декларации заданы в объекте Snakeskin.inlineTags, структура следующая:

Snakeskin.inlineTags = {
	// Название используемого doctype
	'html': {
		// Тег br ставится инлайновым
		'br': true,

		// Тег input ставится инлайновым,
		// причём если вставить содержимое в такой тег, например,
		//
		// < input
		//   Hello world!
		//
		// то оно поставится как значение атрибута value
		'input': 'value'
	}
}

Если для заданного doctype нет своей схемы тегов, то используется html.

Локальная декларация инлайновых тегов

С помощью модификатора !inline любой тег можно сделать принудительно инлайновым, например:

< textarea!inline
{< textarea!inline /}

Отрендерится как:

<textarea>

Также можно задать локальную схему тегов, которая будет распространяться на все вложенные теги:

- var val = {textarea: true}
< div!inline=val
	< textarea
{var val = {textarea: true} /}
{< div!inline=val}
	{< textarea /}
{/}

Отрендерится как:

<div><textarea></div>

Полиморфизм тегов

При разработке шаблонов часто бывает такая ситуация, когда имя создаваемого тега зависит от различных параметров, и для решения такой задачи удобно использовать интерполяцию, например:

- namespace demo
- template index(value, area)
	< ${area ? 'textarea' : 'input'}.input
		{value}
{namespace demo}
{template index(value, area)}
	{< ${area ? 'textarea' : 'input'}.input}
		{value}
	{/}
{/template}

Snakeskin поймёт такую конструкцию и в случае textarea создаст код вида:

<textarea class="input">значение</textarea>

А в случае input:

<input class="input" value="значение">

Экранирование

Для экранирования спецсимволов директивы используется символ \, например:

< .bla foo = bar \= bla
{< .bla foo = bar \= bla}{/}
  • Директивы
  • Работа с HTML/XML

script

Директива вставляет в шаблон код декларации тега <script> с заданными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Отсутствует Блочная, текстовая Поддерживается

Описание

Директива предназначена для более удобного задания тегов <script> и может использоваться только внутри шаблонов или внешних блоков.

При использовании script в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{script js src = foo.js}{/}

/// Короткая форма закрытия
{script js src = foo.js /}

Таблица обозначений

js

text/javascript

dart

application/dart

coffee

application/coffeescript

ts

application/typescript

cljs

application/clojurescript

ls

application/livescript

json

application/json

html

text/html

ss

text/x-snakeskin-template

Примеры

Использование значения по умолчанию (js)

- namespace demo
- template index()
	# script
		var a = {};
{namespace demo}
{template index()}
	#{script}
		var a = {};
	#{/}
{/template}

Явное указание типа

- namespace demo
- template index()
	# script ts
		var a = {};
{namespace demo}
{template index()}
	#{script ts}
		var a = {};
	#{/}
{/template}

Указание собственного типа

- namespace demo
- template index()
	# script application/myscript
		var a = {};
{namespace demo}
{template index()}
	#{script application/myscript}
		var a = {};
	#{/}
{/template}

Задание произвольных атрибутов

(используется синтаксис attr)

- namespace demo
- template index()
	# script js class = foo
		var a = {};
{namespace demo}
{template index()}
	#{script js class = foo}
		var a = {};
	#{/}
{/template}
  • Директивы
  • Работа с HTML/XML

style

Директива вставляет в шаблон код декларации тега <style> с заданными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Отсутствует Блочная, текстовая Поддерживается

Описание

Директива предназначена для более удобного задания тегов <style> и может использоваться только внутри шаблонов или внешних блоков.

Таблица обозначений

css

text/css

Примеры

Использование значения по умолчанию (css)

- namespace demo
- template index()
	# style
		.foo {
			color: red;
		}
{namespace demo}
{template index()}
	#{style}
		.foo {
			color: red;
		}
	#{/}
{/template}

Явное указание типа

- namespace demo
- template index()
	# style css
		.foo {
			color: red;
		}
{namespace demo}
{template index()}
	#{style css}
		.foo {
			color: red;
		}
	#{/}
{/template}

Указание собственного типа

- namespace demo
- template index()
	# style text/stylus
		.foo
			color red
{namespace demo}
{template index()}
	#{style text/stylus}
		.foo
			color red
	#{/}
{/template}

Задание произвольных атрибутов

(используется синтаксис attr)

- namespace demo
- template index()
	# style css class = foo
		.foo {
			color: red;
		}
{namespace demo}
{template index()}
	#{style css class = foo}
		.foo {
			color: red;
		}
	#{/}
{/template}
  • Директивы
  • Работа с HTML/XML

link

Директива вставляет в шаблон код декларации тега <link> с заданными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Отсутствует Блочная, текстовая Поддерживается

Описание

Директива предназначена для более удобного задания тегов <link> и может использоваться только внутри шаблонов или внешних блоков.

При использовании link в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{link css href = foo.css}{/}

/// Короткая форма закрытия
{link css href = foo.css /}

Таблица обозначений

css

type="text/css" rel="stylesheet"

acss

type="text/css" rel="alternate stylesheet"

icon

type="image/x-icon" rel="icon"

Примеры

Использование значения по умолчанию css

- namespace demo
- template index()
	- link
		http://bar.com/foo.css
{namespace demo}
{template index()}
	{link}http://bar.com/foo.css{/}
{/template}

Явное указание типа

- namespace demo
- template index()
	- link acss
		http://bar.com/foo.css
{namespace demo}
{template index()}
	{link acss}http://bar.com/foo.css{/}
{/template}

Указание собственного типа

- namespace demo
- template index()
	- link (( type = text/stylus | rel = stylesheet ))
		http://bar.com/foo.styl
{namespace demo}
{template index()}
	{link (( type = text/stylus | rel = stylesheet ))}http://bar.com/foo.styl{/}
{/template}

Задание произвольных атрибутов

(используется синтаксис attr)

- namespace demo
- template index()
	- link css rel = alternate stylesheet
		http://bar.com/foo.css
{namespace demo}
{template index()}
	{link css rel = alternate stylesheet}http://bar.com/foo.css{/}
{/template}
  • Директивы
  • Работа с HTML/XML

comment

Директива вставляет в шаблон код декларации XML комментария с заданными параметрами.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков <! Блочная, текстовая Поддерживается

Описание

Директива предназначена для более удобного задания тегов XML комментариев и может использоваться только внутри шаблонов или внешних блоков.

Примеры

Простое использование

- namespace demo
- template index()
	<!
		Hello world!
{namespace demo}
{template index()}
	{<!}Hello world!{/}
{/template}

Задание условного комментария

- namespace demo
- template index()
	<! IE 7
		Hello world!
{namespace demo}
{template index()}
	{<! IE 7}Hello world!{/}
{/template}

Отрендерится как:

<!--[if IE 7]>Hello world!<![endif]-->

Интерполяция

- namespace demo
- template index()
	- var ie = 7
	<! IE ${ie}
		Hello world!
{namespace demo}
{template index()}
	{var ie = 7 /}
	{<! IE ${ie}}Hello world!{/}
{/template}
  • Директивы
  • Экранирование

cdata

Директива задаёт блок текста, который вырезается до трансляции, а затем вставляется без изменений в результирующую функцию (пробельные символы также остаются неизменны).

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Отсутствует Блочная, текстовая Не поддерживается

Описание

Директива используется для экранирования больших фрагментов текста, которые должны вставляться «как есть». Декларация директивы возможно только с помощью расширенного синтаксиса. Закрывающий end может быть либо #{end cdata}, либо #{/cdata}. Директива может использоваться только внутри шаблонов или внешних блоков.

Примеры

- namespace demo
- template index()
	#{cdata}
		- if true
			Hello world!
	#{/cdata}
{namespace demo}
{template index()}
	#{cdata}
		{if true}
			Hello world!
		{/}
	#{/cdata}
{/template}
  • Директивы
  • Экранирование

literal

Директива задаёт блок текста, который вставляется без изменений в результирующую функцию, а также будет врапиться специальными текстовыми символами согласно параметру literalBounds.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Не требуется Строковая, текстовая Поддерживается

Описание

Директива используется для интеграции шаблонов Snakeskin с другими шаблонами. Директива может использоваться только внутри шаблонов или внешних блоков.

Примеры

Простое использование

- namespace demo
- template index()
	{{ Hello }}
{namespace demo}
{template index()
	{{ Hello }}
{/template}

Отрендерится как:

{{ Hello }}

Интерполяция

Для передачи значений Snakeskin внутрь директивы используется стандартный механизм интерполяции.

- namespace demo
- template index()
	{{ Hello${1 + 2} }}
{namespace demo}
{template index()
	{{ Hello${1 + 2} }}
{/template}

Отрендерится как:

{{ Hello3 }}

Задание literalBounds

- namespace demo
- template index() @= literalBounds ['<?php', '?>']
	{{ Hello }}
{namespace demo}
{template index() @= literalBounds ['<?php', '?>']}
	{{ Hello }}
{/template}

Отрендерится как:

<?php Hello ?>
  • Директивы
  • Модули

include

Директива включает содержимое заданного файла-шаблона в текущий.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Вне шаблонов или внешних блоков Отсутствует Строковая, логическая Не требуется

Описание

Любой Snakeskin файл может включать в себя другие SS файлы, т. е. Snakeskin позволяет разбить код на логические части и создавать подключаемые библиотеки (подобно std.ss) и т. д. Чтобы подключить другой файл используется специальная директива include, которая начинается с одноименного ключевого слова и должна сопровождаться выражением, где задаётся путь к подключаемому файлу, например:

math.ss

- namespace math
- template calc(a, b)
	{a + b}
{namespace math}
{template calc(a, b)}
	{a + b}
{/template}

app.ss

- namespace app
- include './math'

- template index()
	/// При вызове шаблона из другого файла
	/// нужно обязательно указывать пространство имён
	+= math.calc(1, 2)
{namespace app}
{include './math'}

{template index()}
	/// При вызове шаблона из другого файла
	/// нужно обязательно указывать пространство имён
	{+= math.calc(1, 2) /}
{/template}

Snakeskin контролирует чтобы каждый подключаемый файл включался только один раз, т. е. гарантируется отсутствие дубликатов в конечном коде.

- namespace app
- include './math'

/// Этот include игнорируется
- include './math'

- template index()
	+= math.calc(1, 2)
{namespace app}
{include './math'}

/// Этот include игнорируется
{include './math'}

{template index()}
	{+= math.calc(1, 2) /}
{/template}

В любом Snakeskin файле каждый объявленный шаблон является публичным (экспортируемым), а все глобальные переменные будут инкапсулированы в рамках своего файла, т. е. нет явного способа получить значение такой переменной из другого файла, однако такая возможность есть при наследовании шаблонов.

base.ss

- namespace base
- var foo = 'bar'
{namespace math}
{var foo = 'bar' /}

app.ss

- namespace app
- include './base'

- template index()
	? console.log(foo) /// Error: foo is not defined
{namespace app}
{include './base'}

{template index()}
	{? console.log(foo)} /// Error: foo is not defined
{/template}

При указании пути можно использовать сложные выражения: вызовы функций, тернарные операторы и т. д.

- namespace app
- include './' + (@@base ? 'base' : 'default')

- template index()
	...
{namespace app}
{include './' + (@@base ? 'base' : 'default')}

{template index()}
	...
{/template}

Обратите внимание, что при подключении файла нужно обязательно указывать символы ./ или ../ для конкретизации поиска, т. к. если этого не сделать, то файл будет искаться в папке node_modules (как это делает require в node.js), а вот расширение файла можно не указывать — по умолчанию используется .ss. Директива может использоваться только вне шаблонов или внешних блоков.

Подключение файлов по маске

При указании пути к файлу можно использовать glob-шаблоны, например, чтобы подключить сразу множество файлов.

- namespace app
- include './modules/**/*'

- template index()
	...
{namespace app}
{include './modules/**/*'}

{template index()}
	...
{/template}

Динамическое подключение

Директиву include можно вызывать динамически, т. е. оборачивать её директивами типа if, forEach и т. д.

- namespace app

- eval
	- var fs = require('fs')
	- var path = require('path')

	/// В момент трансляции каждый файл имеет свои переменные
	/// __dirname и __filename
	- var url = path.join(__dirname, 'test')

	- forEach fs.readdirSync(url) => file
		- if path.extname(file) === '.ss'
			- include path.join(url, file)

- template index()
	...
{namespace app}

{eval}
	{var fs = require('fs') /}
	{var path = require('path') /}

	/// В момент трансляции каждый файл имеет свои переменные
	/// __dirname и __filename
	{var url = path.join(__dirname, 'test') /}

	{forEach fs.readdirSync(url) => file}
		{if path.extname(file) === '.ss'}
			{include path.join(url, file)}
		{/}
	{/}
{/eval}

{template index()}
	...
{/template}

Подключение папки

Если в пути к подключаемому файлу явно указать, что это папка (нужно добавить символ / в конце пути), то подключаться файл будет по правилу: (название папки|main|index).ss, например:

- namespace app

/// './base/base.ss' ИЛИ
/// './base/main.ss' ИЛИ
/// './base/index.ss'
- include './base/'

- template index()
	...
{namespace app}

/// './base/base.ss' ИЛИ
/// './base/main.ss' ИЛИ
/// './base/index.ss'
{include './base/'}

{template index()}
	...
{/template}

Обработка параметров трансляции при подключении

Если файл Snakeskin определяет параметры трансляции на глобальном уровне, то они также рекурсивно накладываются на все подключаемые файлы (если они не переопределяются явно в подключаемых файлах), например:

base.ss

- namespace base
@= tolerateWhitespaces true

- template index()
	...
{namespace math}
{@= tolerateWhitespaces true}

{template index()}
	...
{/template}

app.ss

- namespace app
@= tolerateWhitespaces false
@= renderMode 'dom'

- include './base'
- template index()
	...
{namespace app}
{@= tolerateWhitespaces false}
{@= renderMode 'dom'}

{include './base'}
{template index()}
	...
{/template}

Здесь файл base.ss наследует параметр renderMode = 'dom', но tolerateWhitespaces он переопределяет явно.

Подключение с заданием renderAs

Snakeskin позволяет явно задать параметр renderAs при подключении файла с помощью ключевого слова as, например:

- namespace app
- include './base' as placeholder
- template index()
	...
{namespace app}
{include './base' as placeholder}
{template index()}
	...
{/template}

Таким образом мы исключили подключаемые шаблоны из финального файла JS.

Доступ к глобальным переменным шаблона другого файла при наследовании

При наследовании дочерний шаблон автоматически получает доступ к замыканию родительского шаблона, например:

base.ss

- namespace base
- var hello = 'world'

- template index()
	Hello {hello}!
{namespace base}
{var hello = 'world' /}

{template index()}
	Hello {hello}!
{/template}

app.ss

- namespace app
- include './base'

- template index() extends base.index
	- block info
		hello = '{hello}'
{namespace app}
{include './base'}

{template index() extends base.index}
	{block info}
		hello = '{hello}'
	{/}
{/template}

Шаблон app.index отрендерится как:

Hello world!
hello = 'world'

Если в файле дочернего шаблона существует одноимённая глобальная переменная, то она будет переопределять родительскую:

app.ss

- namespace app
- include './base'

/// var может быть до include - это никак не влияет
- var hello = 'people'

- template index() extends base.index
	- block info
		hello = '{hello}'
{namespace app}
{include './base'}

/// var может быть до include - это никак не влияет
{var hello = 'people' /}

{template index() extends base.index}
	{block info}
		hello = '{hello}'
	{/}
{/template}

Шаблон app.index отрендерится как:

Hello people!
hello = 'people'
  • Директивы
  • Модули

import

Директива импортирует в заданный файл ссылки из указанного JavaScript модуля и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только в глобальной области или на глобальном уровне head Отсутствует Строковая, логическая Не требуется

Описание

Директива используется для импортирования JavaScript модулей в шаблон Snakeskin, а тип используемого импортирования зависит от параметра трансляции module (по умолчанию используется UMD). Синтаксис директивы идентичен аналогичной конструкции в JS ES2015. Директива может использоваться только в глобальной области или на глобальном уровне директивы head.

Примеры

- namespace demo

- import path from 'path'
- import * as os from 'os'
- import { readdirSync } from 'fs'

- template index()
	...
{namespace demo}

{import path from 'path'}
{import * as os from 'os'}
{import { readdirSync } from 'fs'}

{template index()}
	...
{/template}
  • Директивы
  • Создание литералов

func

Директива декларирует анонимную функцию.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений () или () => Блочная, логическая, функциональная Не требуется

Описание

Директива func декларирует анонимную функцию-литерал и обычно используется в связи с другими директивами, которые требуют аргумент-функцию, например, series или parallel.

Директива начинается с ключевого слова func (или символов () или () =>), которое может сопровождаться списком аргументов функции через запятую, например:

- namespace demo
- template index()
	() => db
		? db.ping()
{namespace demo}
{template index()}
	{() => db}
		{? db.ping()}
	{/}
{/template}

Параметров у такой функции может быть неограниченное количество, а т. к. директива func является функциональной, то она реализует стандартный механизм декларации параметров. По умолчанию такие функции возвращают строки, однако это поведение можно поменять задав специальный renderMode или явно вернув значение через директиву return. Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

Стандартные переменные функции

Каждая директива func (за исключением тех, что используется совместно с асинхронными директивами) определяет ряд функций, которые можно использовать в ней:

getTplResult — функция, которая возвращает результат работы директивы, также может принимать один логический входной параметр, при задании которого после вызова функции результат работы директивы будет обнуляться;

clearTplResult — функция, которая обнуляет результат работы директивы.

func и var

Чтобы создать переменную с функциональным значением необходимо использовать конструкцию var putIn:

- namespace demo
- template index()
	/// Мы создали функцию,
	/// а затем присвоили её переменной calc
	- var putIn calc
		() => a, b
			- return a + b
{namespace demo}
{template index()}
	/// Мы создали функцию,
	/// а затем присвоили её переменной calc
	{var putIn calc}
		{() => a, b}
			{return a + b /}
		{/}
	{/}
{/template}

func и call, target, putIn

Функцию можно передавать как аргумент при вызове другой функции с помощью директивы call:

- namespace demo
- template index()
	+= [1, 2, 3].map()
		() => el
			el = {el}
{namespace demo}
{template index()}
	{+= [1, 2, 3].map()}
		{() => el}
			el = {el}
		{/}
	{/}
{/template}

Также функцию можно ставить как свойство объекта или массива через target, например:

- namespace demo
- template index()
	- target {} as map
		* calc
			() => a, b
				- return a + b
{namespace demo}
{template index()}
	{target {} as map}
		{* calc}
			{() => a, b}
				{return a + b /}
			{/}
		{/}
	{/}
{/template}

И можно установить/изменить значение свойства объекта или переменной на функцию с помощью putIn:

- namespace demo
- template index()
	- target {} as map
	- putIn map.calc
		() => a, b
			- return a + b
{namespace demo}
{template index()}
	{target {} as map /}
	{putIn map.calc}
		{() => a, b}
			{return a + b /}
		{/}
	{/}
{/template}
  • Директивы
  • Создание литералов

target

Директива возвращает ссылку на заданный объект и позволяет задавать ему свойства со значениями в виде подшаблонов Snakeskin.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива target несёт двойную функциональность: с одной стороны она возвращает ссылку на указанный объект, а с другой может задавать ему свойства-подшаблоны Snakeskin — т. е. представляет из себя литеральную форму для создания массивов и объектов со значениями в виде шаблонов, например:

- namespace demo
- template index(val)
	- target {}
		* prop1
			< .hello
				Hello world!

		* prop 2
			- if val > 1
				Success!
{namespace demo}
{template index()}
	{target {}}
		{* prop1}
			{< .hello}
				Hello world!
			{/}
		{/}

		{* prop 2}
			{if val > 1}
				Success!
			{/}
		{/}
	{/}
{/template}

Внутри такой декларации можно использовать любые допустимые директивы, например, if, forEach и т. д. Свойства объекту ставятся с помощью директивы putIn. Чтобы получить явную ссылку на созданный объект, то его нужно присвоить переменной: самый простой способ — это использовать оператор as, например:

- namespace demo
- template index(val)
	- target {} as myObj
		* prop1
			< .hello
				Hello world!

		* prop 2
			- if val > 1
				Success!

	? console.log(myObj)
{namespace demo}
{template index()}
	{target {} as myObj}
		{* prop1}
			{< .hello}
				Hello world!
			{/}
		{/}

		{* prop 2}
			{if val > 1}
				Success!
			{/}
		{/}
	{/}

	{? console.log(myObj)}
{/template}

А также можно использовать директиву var в режиме putIn:

- namespace demo
- template index(val)
	- var putIn myObj
		- target {}
			* prop1
				< .hello
					Hello world!

			* prop 2
				- if val > 1
					Success!

	? console.log(myObj)
{namespace demo}
{template index()}
	{var putIn myObj}
		{target {}}
			{* prop1}
				{< .hello}
					Hello world!
				{/}
			{/}

			{* prop 2}
				{if val > 1}
					Success!
				{/}
			{/}
		{/}
	{/}

	{? console.log(myObj)}
{/template}

Общая форма директивы следующая:

target ссылка на объект или сам объект [as опциональный идентификатор]
	[* опциональные свойства]

При использовании target в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{target {a: 1, b: 2}}{/}

/// Короткая форма закрытия
{target {a: 1, b: 2} /}

Можно использовать директиву для уже созданных объектов, например:

- namespace demo
- template index(val)
	- var myObj = {}
	- target myObj
		* prop1
			< .hello
				Hello world!

		* prop 2
			- if val > 1
				Success!

	? console.log(myObj)
{namespace demo}
{template index()}
	{var myObj = {} /}
	{target myObj}
		{* prop1}
			{< .hello}
				Hello world!
			{/}
		{/}

		{* prop 2}
			{if val > 1}
				Success!
			{/}
		{/}
	{/}

	{? console.log(myObj)}
{/template}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

Значение ключа putIn для объекта

Значение переданное в директиву putIn при задании свойства объекта трактуется как простая строка, а для прокидывания значений Snakeskin внутрь директивы используется стандартный механизм интерполяции, например:

- namespace demo
- template index(val)
	- target {} as myObj
		* some prop name ${1 + 2}
			< .hello
				Hello world!

	? console.log(myObj['some prop name 3'])
{namespace demo}
{template index()}
	{target {} as myObj}
		{* some prop name ${1 + 2}}
			{< .hello}
				Hello world!
			{/}
		{/}
	{/}

	{? console.log(myObj['some prop name 3'])}
{/template}

target для массивов

Создание и редактирование массивов через target почти не отличается от объектов — просто не нужно указывать название ключа и первый вызов putIn можно опустить, например:

- namespace demo
- template index(val)
	- target [] as myArray
			< .hello
				Hello world!
		*
			< .hello
				Hello people!

	? console.log(myArray)
{namespace demo}
{template index()}
	{target [] as myArray}
		{*}
			{< .hello}
				Hello world!
			{/}
		{/}
		{*}
			{< .hello}
				Hello people!
			{/}
		{/}
	{/}

	{? console.log(myArray)}
{/template}

Вложенный target

Директива может ставить как свойство объекта другой target, который может устанавливать любое значение.

- namespace demo
- template index(val)
	- target [] as myArray
			- target {a: 1, b: 2}
		*
			- target 1 + 2

	? console.log(myArray)
{namespace demo}
{template index()}
	{target [] as myArray}
		{*}
			{target {a: 1, b: 2} /}
		{/}
		{*}
			{target 1 + 2 /}
		{/}
	{/}

	{? console.log(myArray)}
{/template}

target и call, putIn, func

Директиву можно передавать как аргумент при вызове функции с помощью директивы call:

- namespace demo
- template index()
	+= someFunction()
		- target []
			Hello world!
{namespace demo}
{template index()}
	{+= someFunction()}
		{target []}
			Hello world!
		{/}
	{/}
{/template}

Также target можно ставить как свойство объекта или массива через putIn, например:

- namespace demo
- template index()
	- var myObj = {}
	- putIn myObj.foo
		- target []
			Hello world!
{namespace demo}
{template index()}
	{var myObj = {} /}
	{putIn myObj.foo}
		{target []}
			Hello world!
		{/}
	{/}
{/template}

И можно установить функцию как значение свойства объекта или элемент массива:

- namespace demo
- template index()
	- target []
		() => a, b
			- return a + b
{namespace demo}
{template index()}
	{target []}
		{() => a, b}
			{return a + b /}
		{/}
	{/}
{/template}
  • Директивы
  • Создание литералов

putIn

Директива задает значение переменной или свойству объекта в виде подшаблона Snakeskin.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений * Блочная, логическая Не требуется

Описание

Директива putIn несёт двойную функциональность: с одной стороны она позволяет присвоить подшаблон Snakeskin переменной или свойству объекта, а с другой — является частью директивы call и target. Совместное использование putIn подробно рассмотрено в других главах, поэтому здесь описываться не будет.

Для изменения переменной или свойства объекта через putIn используется общая форма:

putIn ссылка
	Шаблон

Например:

- namespace demo
- template index(val)
	- var myObj = {}

	- putIn myObj.foo
		< .hello
			Hello world!

	- putIn myObj.calc
		() => a, b
			- return a + b

	- putIn myObj.arr
		- target []
			Hello people!

	? console.log(myObj)
{namespace demo}
{template index()}
	{var myObj = {} /}

	{putIn myObj.foo}
		{< .hello}
			Hello world!
		{/}
	{/}

	{putIn myObj.calc}
		{() => a, b}
			{return a + b}
		{/}
	{/}

	{putIn myObj.arr}
		{target []}
			Hello people!
		{/}
	{/}

	{? console.log(myObj)}
{/template}

Внутри такой декларации можно использовать любые допустимые директивы, например, if, forEach и т. д. Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

  • Директивы
  • Директивы для асинхронной работы

series

Директива является фасадом для Async.series.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива является обёрткой над функцией series библиотеки Async и позволяет создавать удобные цепочки асинхронных вызовов. Вместе с директивой series должна использоваться директива func. Перед использованием директивы необходимо подключить через import саму библиотеку Async, например:

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index()
	- series
		() => cb
			fs.readFile('foo.txt', cb)

		() => cb
			fs.readFile('bar.txt', cb)
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index()}
	{series}
		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

		{() => cb}
			fs.readFile('bar.txt', cb)
		{/}
	{/}
{/template}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Вместе с основной директивой можно использовать дополнительные:

  1. final — второй параметр Async.series (функциональная директива).

Для управления переходами внутри блока можно использовать директивы:

  1. break — прерывает выполнение операции и переходит в final (если он задан), может принимать параметр;
  2. continue — прерывает выполнение текущей функции и переходит к следующей (если она есть) или к final (если он задан), может принимать параметр.

Примеры

Задание final

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index()
	- series
		() => cb
			fs.readFile('foo.txt', cb)

		() => cb
			fs.readFile('bar.txt', cb)

	- final err, files
		? console.log(err, files)
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index()}
	{series}
		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

		{() => cb}
			fs.readFile('bar.txt', cb)
		{/}

	{final err, res}
		{? console.log(err, files)}
	{/}
{/template}

Сброс операции

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index(brk)
	- series
		() => cb
			- if brk
				- break new Error('Skipped')

			? cb()

		() => cb
			fs.readFile('foo.txt', cb)

	- final err, res
		...
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index(brk)}
	{series}
		{() => cb}
			{if brk}
				{break new Error('Skipped')}
			{/}

			{? cb()}
		{/}

		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

	{final err, res}
		...
	{/}
{/template}
  • Директивы
  • Директивы для асинхронной работы

parallel

Директива является фасадом для Async.parallel.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива является обёрткой над функцией parallel библиотеки Async и позволяет создавать удобные цепочки асинхронных вызовов. Вместе с директивой parallel должна использоваться директива func. Перед использованием директивы необходимо подключить через import саму библиотеку Async, например:

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index()
	- parallel
		() => cb
			fs.readFile('foo.txt', cb)

		() => cb
			fs.readFile('bar.txt', cb)
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index()}
	{parallel}
		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

		{() => cb}
			fs.readFile('bar.txt', cb)
		{/}
	{/}
{/template}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Вместе с основной директивой можно использовать дополнительные:

  1. final — второй параметр Async.parallel (функциональная директива).

Для управления переходами внутри блока можно использовать директивы:

  1. break — прерывает выполнение операции и переходит в final (если он задан), может принимать параметр;
  2. continue — прерывает выполнение текущей функции и переходит к следующей (если она есть) или к final (если он задан), может принимать параметр.

Примеры

Задание parallel

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index()
	- parallel
		() => cb
			fs.readFile('foo.txt', cb)

		() => cb
			fs.readFile('bar.txt', cb)

	- final err, files
		? console.log(err, files)
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index()}
	{parallel}
		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

		{() => cb}
			fs.readFile('bar.txt', cb)
		{/}

	{final err, res}
		{? console.log(err, files)}
	{/}
{/template}

Сброс операции

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index(brk)
	- parallel
		() => cb
			- if brk
				- break new Error('Skipped')

			? cb()

		() => cb
			fs.readFile('foo.txt', cb)

	- final err, res
		...
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index(brk)}
	{parallel}
		{() => cb}
			{if brk}
				{break new Error('Skipped')}
			{/}

			{? cb()}
		{/}

		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

	{final err, res}
		...
	{/}
{/template}
  • Директивы
  • Директивы для асинхронной работы

waterfall

Директива является фасадом для Async.waterfall.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива является обёрткой над функцией waterfall библиотеки Async и позволяет создавать удобные цепочки асинхронных вызовов. Вместе с директивой waterfall должна использоваться директива func. Перед использованием директивы необходимо подключить через import саму библиотеку Async, например:

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index()
	- waterfall
		() => cb
			fs.readFile('foo.txt', cb)

		() => file1, cb
			fs.readFile('bar.txt', cb)
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index()}
	{waterfall}
		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

		{() => file1, cb}
			fs.readFile('bar.txt', cb)
		{/}
	{/}
{/template}

Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области. Вместе с основной директивой можно использовать дополнительные:

  1. final — второй параметр Async.waterfall (функциональная директива).

Для управления переходами внутри блока можно использовать директивы:

  1. break — прерывает выполнение операции и переходит в final (если он задан), может принимать параметр;
  2. continue — прерывает выполнение текущей функции и переходит к следующей (если она есть) или к final (если он задан), может принимать параметр.

Примеры

Задание final

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index()
	- waterfall
		() => cb
			fs.readFile('foo.txt', cb)

	- final err, files
		? console.log(err, files)
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index()}
	{waterfall}
		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

	{final err, res}
		{? console.log(err, files)}
	{/}
{/template}

Сброс операции

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index(brk)
	- waterfall
		() => cb
			- if brk
				- break new Error('Skipped')

			? cb()

		() => cb
			fs.readFile('foo.txt', cb)

	- final err, res
		...
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index(brk)}
	{waterfall}
		{() => cb}
			{if brk}
				{break new Error('Skipped')}
			{/}

			{? cb()}
		{/}

		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

	{final err, res}
		...
	{/}
{/template}
  • Директивы
  • Директивы для асинхронной работы

yield

Директива yield является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблона-генератора Отсутствует Блочная, логическая Не требуется

Описание

Директива используется вместе с шаблонами-генераторами для организации «прерывания», однако, Snakeskin не создаёт полифил, а генерирует «чистый» JavaScript код, поэтому для поддержки старых браузеров используйте Regenerator или Babel.

Директива начинается с ключевого слова yield, которое может сопровождаться ссылкой на возвращаемое значение или выражение, например:

- namespace demo
- template *index()
	- yield 1 + 2
{namespace demo}
{template index()}
	{yield *1 + 2 /}
{/template}

Для удобства использования yield в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{yield 1 + 2}{/}

/// Короткая форма закрытия
{yield 1 + 2 /}

Директива может использоваться только внутри шаблона-генератора.

Расширенная декларация

Директива может включать возвращаемое значение в своё тело — это удобно, когда возвращаемое значение является подшаблоном, например:

- namespace demo
- template *index()
	/// Шаблон вернёт ссылку на функцию,
	/// которая складывает два числа
	- yield
		() => a, b
			- return a + b
{namespace demo}
{template *index()}
	/// Шаблон вернёт ссылку на функцию,
	/// которая складывает два числа
	{yield}
		{() => a, b}
			{return a + b /}
		{/}
	{/}
{/template}

Внутри такой декларации можно использовать любые допустимые директивы, например, if, forEach и т. д.

  • Директивы
  • Директивы для асинхронной работы

await

Директива await является эквивалентом одноименного оператора в различных языках программирования и по своей семантике близка к реализации в JavaScript.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблона-генератора Отсутствует Блочная, логическая Не требуется

Описание

Директива используется вместе с async-шаблонами для организации «прерывания», однако, Snakeskin не создаёт полифил, а генерирует «чистый» JavaScript код, поэтому для поддержки старых браузеров используйте Babel.

Директива начинается с ключевого слова await, которое может сопровождаться ссылкой на ожидаемое значение или выражение, например:

- namespace demo
- async template index(db)
	- await db.getData()
{namespace demo}
{async template index(db)}
	{await db.getData() /}
{/template}

Для удобства использования await в классическом синтаксисе существует короткая форма закрытия директивы, например:

/// Обычное закрытие
{await db.getData()}{/}

/// Короткая форма закрытия
{await db.getData() /}

Директива может использоваться только внутри async-шаблона.

Расширенная декларация

Директива может включать выражение в своё тело — это удобно, когда ожидаемое значение является подшаблоном, например:

- namespace demo
- async template index(db)
	- await
		- block getData() =>
			- return db.getData()
{namespace demo}
{async template index()}
	{await}
		{block getData() =>}
			{return db.getData() /}
		{/}
	{/}
{/template}

Внутри такой декларации можно использовать любые допустимые директивы, например, if, forEach и т. д.

  • Директивы
  • Наследование

super

Директива вставляет в шаблон тело родительского блока.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри шаблонов или внешних блоков Отсутствует Строковая, логическая Не требуется

Описание

Директива работает по схеме: всплывает по дереву шаблона до тех пор, пока не найдётся блок, который имеет родителя, и вставляет родительское тело в указанное место, а если такого родителя нет, то просто ничего не делает. Директива может использоваться только внутри шаблонов или внешних блоков.

Примеры

- namespace demo

- template base()
	- block base
		Какой хороший день!

- template child() extends @base
	- block base
		- super
		Трудиться мне не лень!
{namespace demo}

{template base()}
	{block base}
		Какой хороший день!
	{/}
{/template}

{template child() extends @base}
	{block base}
		{super}
		Трудиться мне не лень!
	{/}
{/template}
  • Директивы
  • Разное

op

Директива создаёт логический блок Snakeskin без «побочного эффекта».

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Без ограничений Отсутствует Блочная, логическая Не требуется

Описание

Директива используется для перехода в расширенный синтаксис без «побочных эффектов» других директив, т. е. сама директива ничего не делает. Директива может использоваться как внутри шаблонов или других директив, так и в глобальной области.

Примеры

- namespace demo
- template index()
	# op
		{name: 'world'}
{namespace demo}
{template index()}
	#{op}
		{name: 'world'}
	#{/}
{/template}
  • Директивы
  • Разное

break

Директивы прерывает выполнение другой директивы, с которой она находится в связи.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри специальных директив Отсутствует Строковая, логическая Не требуется

Описание

Поведение директивы break зависит от контекста, например, если использовать её внутри циклов или итераторов, то она будет немедленно прерывать итерации, а если использовать совместно с асинхронными директивами, то break будет осуществлять немедленный переход к результирующей функции.

Директива может использоваться только внутри директив:

Примеры

Сброс for

- namespace demo
- template index()
	- var obj = {a: 1, b: 2}
	- for var key in obj
		{key}
		- break
{namespace demo}
{template index()}
	{var obj = {a: 1, b: 2} /}
	{for var key in obj}
		{key}
		{break}
	{/}
{/template}

Сброс series

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index(brk)
	- series
		() => cb
			- if brk
				/// Управление перейдёт в final c ошибкой
				- break new Error('Skipped')

			? cb()

		() => cb
			fs.readFile('foo.txt', cb)

	- final err, res
		...
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index(brk)}
	{series}
		{() => cb}
			{if brk}
				/// Управление перейдёт в final c ошибкой
				{break new Error('Skipped')}
			{/}

			{? cb()}
		{/}

		{() => cb}
			fs.readFile('foo.txt', cb)
		{/}

	{final err, res}
		...
	{/}
{/template}
  • Директивы
  • Разное

continue

Директивы пропускает такт выполнения другой директивы, с которой она находится в связи.

Паспорт

Декларация Короткий синтаксис Тип директивы Интерполяция
Только внутри специальных директив Отсутствует Строковая, логическая Не требуется

Описание

Поведение директивы continue зависит от контекста, например, если использовать её внутри циклов или итераторов, то она будет немедленно прерывать текущую итерацию и переходить к следующей, а если использовать совместно с асинхронными директивами, то continue будет осуществлять немедленный переход к следующей функции в цепи.

Директива может использоваться только внутри директив:

Примеры

Использование с for

- namespace demo
- template index()
	- var obj = {a: 1, b: 2}
	- for var key in obj
		- if !obj.hasOwnProperty(key)
			- continue

		{key}
{namespace demo}
{template index()}
	{var obj = {a: 1, b: 2} /}
	{for var key in obj}
		{if !obj.hasOwnProperty(key)}
			{continue}
		{/}
		{key}
	{/}
{/template}

Использование с waterfall

- namespace demo

- import async from 'async'
- import fs from 'fs'

- template index(brk)
	- waterfall
		() => cb
			- if brk
				- continue 'foo.txt'

			...
			? cb('bar.txt')

		() => path, cb
			fs.readFile(path, cb)

	- final err, res
		...
{namespace demo}

{import async from 'async'}
{import fs from 'fs'}

{template index(brk)}
	{waterfall}
		{() => cb}
			{if brk}
				{continue 'foo.txt'}
			{/}

			...
			{? cb()}
		{/}

		{() => path, cb}
			fs.readFile(path, cb)
		{/}

	{final err, res}
		...
	{/}
{/template}
  • JS API
  • Общее

compile

Метод компилирует заданный текст шаблона или содержимое DOM узла.

Интерфейс

Snakeskin.compile(src, opt_params, opt_info) {
	return string || false || null;
}

Аргументы

  1. (!Element|string) src — ссылка на DOM узел, где декларированы шаблоны или исходный текст шаблонов;
  2. Object= opt_params — дополнительные параметры запуска;
  3. Object= opt_info — дополнительная информация для отладчика.

opt_params

opt_info

Параметры

cache

/**
 * @type {?boolean=}
 * @default true
 */

Если параметр равен false, то наличие шаблона в кеше не будет проверятся, а сам шаблон не будет кешироваться.

vars

/**
 * @type {Object=}
 */

Параметр задаёт суперглобальные переменные Snakeskin.

Snakeskin.compile('<шаблон>', {
	vars: {
		foo: 'bar'
	}
});

context

/**
 * @type {Object=}
 */

Параметр задаёт объект для экспорта свойств при компиляции в стиле CommonJS.

- namespace demo
- template index()
	Hello world!
{namespace demo}
{template index()
	Hello world!
{/template}
var tpls = {};

Snakeskin.compile('<шаблон>', {
	context: tpls
});

tpls.demo.foo() // Hello world

babel

/**
 * @type {Object=}
 */

Параметр задаёт объект настроек для Babel для обработки после основной трансляции.

onError

/**
 * @type {?function(!Error)=}
 */

Параметр задаёт функцию обратного вызова для обработки ошибок.

throws

/**
 * @type {?boolean=}
 * @default false
 */

Если параметр равен true, то в случае ошибки и отсутствия обработчика ошибок — будет возбуждено исключение.

По умолчанию просто выводится сообщение в stderr и прерывается операция.

debug

/**
 * @type {Object=}
 */

Объект, который будет содержать в себе некоторую отладочную информацию.

var info = {};
Snakeskin.compile('<шаблон>', {debug: info});
info.code // Исходный текст полученного JS файла

resolveModuleSource

/**
 * @type {(?function(string, string): string)=}
 */

Функция для резолвинга путей в import: первым параметром принимает строку запроса, а вторым полный путь к файлу, в котором вызывается директива. Функция должна возвращать строку, которая будет новым путём к подключаемому файлу.

pack

/**
 * @type {?boolean=}
 * @default false
 */

Если параметр равен true, то модель импорта/экспорта модулей будет оптимизирована для использования вместе с WebPack.

module

/**
 * @type {?string=}
 * @default 'umd'
 */

Тип импорта/экспорта модулей, доступны варианты:

  • umd;
  • global (сохранение напрямую в глобальный объект);
  • cjs;
  • amd;
  • native.

moduleId

/**
 * @type {?string=}
 * @default 'tpls'
 */

ИД модуля для umd/amd декларации: первый параметр функции define.

moduleName

/**
 * @type {?string=}
 */

Название модуля для umd/global декларации: если задан, то в глобальном объекте (window и т. д.) будет создано свойство с указанным именем, куда будут сохраняться полученные шаблоны, иначе, всё будет сохранено напрямую в глобальный объект.

useStrict

/**
 * @type {?boolean=}
 * @default true
 */

Если параметр равен false, то шаблоны компилируются без 'use strict';.

prettyPrint

/**
 * @type {?boolean=}
 * @default false
 */

Если параметр равен true, то полученный JS после трансляции будет отформатирован.

literalBounds

/**
 * @type {Array<string>=}
 * @default ['{{', '}}']
 */

Параметр задаёт «врапперы» для директивы literal, например:

- namespace demo
- template index() @= literalBounds ['<?php', '?>']
	{{ Hello }}
{namespace demo}
{template index() @= literalBounds ['<?php', '?>']}
	{{ Hello }}
{/template}

Отрендерится как:

<?php Hello ?>

attrLiteralBounds

/**
 * @type {Array<string>=}
 */

Параметр задаёт «врапперы» для директивы literal при декларации значения атрибута, например:

- namespace demo
- template index() @= attrLiteralBounds ['{', '}']
	< .foo title = {{ val }}
{namespace demo}
{template index() @= attrLiteralBounds ['{', '}']}
	{< .foo title = {{ val }} /}
{/template}

Отрендерится как:

<div class="foo" title={ val }></div>

tagFilter

/**
 * @type {?string=}
 */

Параметр задаёт название фильтра для обработки тега при создании через tag.

tagNameFilter

/**
 * @type {?string=}
 */

Параметр задаёт название фильтра для обработки имени тега при создании через tag.

attrKeyFilter

/**
 * @type {?string=}
 */

Параметр задаёт название фильтра для обработки ключа атрибута тега при создании через tag.

attrValueFilter

/**
 * @type {?string=}
 */

Параметр задаёт название фильтра для обработки значения атрибута тега при создании через tag.

bemFilter

/**
 * @type {?string=}
 */

Параметр задаёт название фильтра для обработки липких ссылок.

filters

/**
 * @type {Object<Array<string>>=}
 * @default {global: ['html', 'undef'], local: ['undef']}
 */

Объект фильтров по умолчанию для директивы output: фильтры бывают 2-х видов — глобальные (применяются ко всему полученному выражению, ключ global) и локальные (применяются к каждой части выражения по отдельности, ключ local).

localization

/**
 * @type {?boolean=}
 * @default true
 */

Если параметр равен false, то строки локализации будут отключены, т. е. сохраняются «как есть».

i18nFn

/**
 * @type {?string=}
 * @default 'i18n'
 */

Название используемой глобальной функции локализации: данная функция будет оборачивать строки локализации.

- namespace demo
- template index()
	`Hello world!`
{namespace demo}
{template index()}
	`Hello world!`
{/template}

Строка `Hello world!` скомпилируется как

i18n("hello world!")

i18nFnOptions

/**
 * @type {?string=}
 */

Передаваемые параметры для глобальной функции локализации в строковом виде, например, '{lang: "en"}, true'.

language

/**
 * @type {Object=}
 */

Если задан данный параметр, то строки локализации будут заменятся на этапе трансляции.

- namespace demo
- template index()
	`Hello world!`
{namespace demo}
{template index()}
	`Hello world!`
{/template}
Snakeskin.compile('<шаблон>', {
	'Hello world!': 'Привет мир!'
});

words

/**
 * @type {Object=}
 */

Если задан данный параметр, то найденные в шаблонах строки локализации будут добавляться в него в виде свойств.

- namespace demo
- template index()
	`Hello world!`
{namespace demo}
{template index()}
	`Hello world!`
{/template}
var words = {};

Snakeskin.compile('<шаблон>', {
	words: words
});

// {'Hello world!': 'Hello world!'}
console.log(words);

ignore

/**
 * @type {RegExp=}
 */

Параметр задаёт пробельные символы, которые будут игнорироваться в шаблонах.

tolerateWhitespaces

/**
 * @type {?boolean=}
 * @default false
 */

Если параметр равен true, то все пробельные символы в шаблоне обрабатываются «как есть».

eol

/**
 * @type {?string=}
 * @default '\n'
 */

Параметр задаёт символ перевода строки, который будет использоваться в сгенерированном файле, можно использовать \n, \r или \r\n.

doctype

/**
 * @type {?string=}
 * @default 'html'
 */

Параметр задаёт тип документа: это влияет на код, который генерируют некоторые директивы, например, tag. Доступные варианты.

renderAs

/**
 * @type {?string=}
 */

Параметр задаёт тип шаблонов для рендеринга, доступны варианты:

  • interface — все директивы template рендерятся как interface;
  • placeholder — все директивы template и interface рендерятся placeholder.

renderMode

/**
 * @type {?string=}
 * @default 'stringConcat'
 */

Параметр задаёт режим рендеринга шаблонов, доступны варианты:

  • stringConcat — шаблон генерируется в виде строки, для конкатенаций используется оператор +;
  • stringBuffer — шаблон генерируется в виде строки, для конкатенаций используется оператор StringBuffer;
  • dom — шаблон генерируется в виде DocumentFragment с помощью DOM API.

file

/**
 * @type {?string=}
 */

Параметр задаёт адрес компилируемого файла.

  • JS API
  • Общее

importFilters

Метод импортирует заданный объект в пространство имён фильтров Snakeskin.

Интерфейс

Snakeskin.importFilters(filters, opt_namespace) { return undefined; }

Аргументы

  1. !Object filters — импортируемый объект;
  2. ?string= opt_params — пространство имён для сохранения, например, foo.bar.
  • JS API
  • Общее

setFilterParams

Метод задаёт заданному фильтру дополнительные параметры.

Интерфейс

Snakeskin.setFilterParams(filter, params) { return Function; }

Аргументы

  1. (string|!Function) filter — название фильтра или функция-фильтр;
  2. !Object params — параметры фильтра.
  • JS API
  • node.js

check

Метод вернёт true, если заданный файл шаблонов соответствует скомпилированному по временной метке.

Интерфейс

Snakeskin.check(source, result) { return boolean; }

Аргументы

  1. string source — путь к исходному файлу;
  2. string result — путь к скомпилированному файлу.
  • JS API
  • node.js

compileFile

Метод скомпилирует заданный файл и вернёт ссылку на объект полученных шаблонов.

Интерфейс

Snakeskin.compileFile(src, opt_params) { return !Object || false; }

Аргументы

  1. string src — путь к файлу шаблонов;
  2. Object= opt_params — дополнительные параметры запуска.
  • JS API
  • node.js

exec

Метод скомпилирует заданный текст и вернёт ссылку на главный шаблон.

Главный шаблон определяется по правилу: название файла без расширения или main или index или Object.keys().sort()[0].

Интерфейс

Snakeskin.exec(txt, opt_params, opt_tplName) { return Function; }

Аргументы

  1. string txt — исходный текст;
  2. Object= opt_params — дополнительные параметры запуска;
  3. ?string= opt_tplName — имя главного шаблона.
  • JS API
  • node.js

execFile

Метод скомпилирует заданный файл и вернёт ссылку на главный шаблон.

Главный шаблон определяется по правилу: название файла без расширения или main или index или Object.keys().sort()[0].

Интерфейс

Snakeskin.execFile(src, opt_params, opt_tplName) { return Function; }

Аргументы

  1. string src — путь к файлу шаблонов;
  2. Object= opt_params — дополнительные параметры запуска;
  3. ?string= opt_tplName — имя главного шаблона.