Теги Latte

Сводка и описание всех встроенных тегов Latte.

Печать
{$var}, {...} или {=...} печатает экранированную переменную или выражение
{$var|filter} печатает с фильтрами
{l} или {r} печатает символ { or }
Условия
{if}{elseif}{else}{/if} условие if
{ifset}{elseifset}{/ifset} условие ifset
{ifchanged}{/ifchanged} проверка наличия изменений
{switch} {case} {default} {/switch} условие switch
n:else альтернативное содержание условий
Loops
{foreach}{/foreach} foreach
{for}{/for} for
{while}{/while} while
{continueIf $cond} перейти к следующей итерации
{skipIf $cond} пропустить текущую итерацию цикла
{breakIf $cond} прервать цикл
{exitIf $cond} ранний выход
{first}{/first} это первая итерация?
{last}{/last} Это последняя итерация?
{sep}{/sep} последует ли следующая итерация?
{iterateWhile}{/iterateWhile} структурированный foreach
$iterator специальная переменная внутри цикла foreach
Включение других шаблонов
{include 'file.latte'} включает шаблон из другого файла
{sandbox 'file.latte'} включает шаблон в режиме песочницы
Блоки, макеты, наследование шаблонов
{block} анонимный блок
{block blockname} определение блока
{define blockname} определение блока для будущего использования
{include blockname} печатает блок
{include blockname from 'file.latte'} печатает блок из файла
{import 'file.latte'} загружает блоки из другого шаблона
{layout 'file.latte'} / {extends} указание файла макета
{embed}{/embed} загружает шаблон или блок и позволяет перезаписывать блоки
{ifset blockname}{/ifset} условие, если блок определен
Обработка исключений
{try}{else}{/try} перехват исключений
{rollback} отбрасывает блок try
Переменные
{var $foo = value} создание переменных
{default $foo = value} значение по умолчанию, когда переменная не объявлена
{parameters} Объявление переменных, типы значений по умолчанию
{capture}{/capture} Захватывает секцию для переменной
Типы
{varType} объявляет тип переменной
{varPrint} предлагает типы переменных
{templateType} объявляет типы переменных с помощью класса
{templatePrint} генерирует класс со свойствами
Перевод
{_string} печатает перевод
{translate}{/translate} переводит содержимое
Другие
{contentType} переключает режим экранирования и отправляет HTTP-заголовок
{debugbreak} устанавливает точку останова в коде
{do} оценивает выражение, не выводя его на печать
{dump} сбрасывает переменные в Tracy Bar
{php} выполняет любой PHP-код
{spaceless}{/spaceless} удаляет ненужные пробельные символы
{syntax} переключает синтаксис во время выполнения программы
{trace} показывает трассировку стека
Помощники HTML тегов
n:class умный атрибут класса
n:attr интеллектуальные атрибуты HTML
n:tag динамическое имя элемента HTML
n:ifcontent Опустить пустой HTML-тег
Доступно только в Nette Framework
n:href ссылка в HTML-элементах <a>
{link} печатает ссылку
{plink} печатает ссылку на ведущего
{control} печатает компонент
{snippet}{/snippet} фрагмент шаблона, который может быть отправлен с помощью AJAX
{snippetArea} конверт сниппетов
{cache}{/cache} кэширует раздел шаблона
Доступно только в Nette Forms
{form}{/form} печатает элемент формы
{label}{/label} печатает метку ввода формы
{input} печатает элемент ввода формы
{inputError} печатает сообщение об ошибке для элемента ввода формы
n:name активирует элемент ввода HTML
{formContainer}{/formContainer} рендеринг контейнера формы

Печать

{$var} {...} {=...}

Latte использует тег {=...} для печати любого выражения на выходе. Если выражение начинается с переменной или вызова функции, то нет необходимости писать знак равенства. Что на практике означает, что его почти никогда не нужно писать:

Name: {$name} {$surname}<br>
Age: {date('Y') - $birth}<br>

Вы можете записать в виде выражения все, что знаете из PHP. Вам просто не нужно учить новый язык. Например:

{='0' . ($num ?? $num * 3) . ', ' . PHP_VERSION}

Пожалуйста, не ищите никакого смысла в предыдущем примере, но если вы его там найдете, напишите нам :-)

Эскейпинг-вывод

Какая самая важная задача системы шаблонов? Избегать дыр в безопасности. И именно это делает Latte, когда вы печатаете что-то на вывод. Он автоматически экранирует все:

<p>{='one < two'}</p>   {* prints: '<p>one &lt; two</p>' *}

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

А если вы печатаете HTML-кодированное содержимое из надежного источника? Тогда вы можете легко отключить экранирование:

{$trustedHtmlString|noescape}

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

Печать в JavaScript

Благодаря контекстно-зависимому экранированию, очень легко печатать переменные в JavaScript, и Latte будет правильно их экранировать.

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

{var $foo = ['hello', true, 1]}
<script>
	alert({$foo});
</script>

Генерирует:

<script>
	alert(["hello", true, 1]);
</script>

Это также причина, по которой не заключайте переменную в кавычки: Latte добавляет их вокруг строк. А если вы хотите поместить строковую переменную в другую строку, просто конкатенируйте их:

<script>
	alert('Hello ' + {$name} + '!');  // OK

	alert({="Hello $name!"});         // OK

	alert('Hello {$name} !');         // ERROR!
</script>

Фильтры

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

{$string|upper|truncate:30}

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

{$left . ($middle|upper) . $right}

Условия

{if} {elseif} {else}

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

{if $product->inStock > Stock::Minimum}
	In stock
{elseif $product->isOnWay()}
	On the way
{else}
	Not available
{/if}

Как и любой парный тег, пара {if} ... {/ if} может быть записана как n:attribute, например:

<p n:if="$count > 0">In stock {$count} items</p>

Знаете ли вы, что к n:attributes можно добавить префикс tag-? Тогда условие будет затрагивать только HTML-теги, а содержимое между ними всегда будет выводиться:

<a href="..." n:tag-if="$clickable">Hello</a>

{* prints 'Hello' when $clickable is falsey *}
{* prints '<a href="...">Hello</a>' when $clickable is truthy *}

Отлично.

n:else

Если условие {if} ... {/if} записано в виде атрибута n:attribute, то у вас есть возможность указать альтернативную ветвь с помощью n:else:

<strong n:if="$count > 0">In stock {$count} items</strong>

<em n:else>not available</em>

Атрибут n:else также может использоваться в сочетании с. n:ifset, n:foreach, n:try, n:ifcontent, и n:ifchanged.

{/if $cond}

Вас может удивить, что выражение в условии {if} также может быть указано в теге end. Это полезно в ситуациях, когда мы еще не знаем значение условия на момент открытия тега. Назовем это отложенным решением.

Например, мы начинаем выводить таблицу с записями из базы данных, и только после завершения отчета понимаем, что в базе данных не было ни одной записи. Поэтому мы помещаем условие в конечный тег {/if}, и если записи нет, то ничего из этого не будет напечатано:

{if}
	<h1>Printing rows from the database</h1>

	<table>
	{foreach $resultSet as $row}
		...
	{/foreach}
	</table>
{/if isset($row)}

Удобно, не правда ли?

Вы также можете использовать {else} в отложенном условии, но не {elseif}.

{ifset} {elseifset}

См. также {ifset block}

Используйте условие {ifset $var}, чтобы определить, существует ли переменная (или несколько переменных) и имеет ли она ненулевое значение. На самом деле это то же самое, что и if (isset($var)) в PHP. Как и любой парный тег, этот может быть записан в виде n:attribute, поэтому покажем его на примере:

<meta name="robots" content={$robots} n:ifset="$robots">

{ifchanged}

{ifchanged} проверяет, изменилось ли значение переменной с момента последней итерации в цикле (foreach, for или while).

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

{foreach ($names|sort) as $name}
	{ifchanged $name[0]} <h2>{$name[0]}</h2> {/ifchanged}

	<p>{$name}</p>
{/foreach}

Однако, если аргумент не указан, то будет проверено само содержимое рендеринга в соответствии с его предыдущим состоянием. Это означает, что в предыдущем примере мы можем смело опустить аргумент в теге. И, конечно, мы также можем использовать n:attribute:

{foreach ($names|sort) as $name}
	<h2 n:ifchanged>{$name[0]}</h2>

	<p>{$name}</p>
{/foreach}

Вы также можете включить клаузулу {else} внутрь {ifchanged}.

{switch} {case} {default}

Сравнивает значение с несколькими вариантами. Это похоже на структуру switch, известную вам из PHP. Однако Latte улучшает ее:

  • использует строгое сравнение (===)
  • не требует break

Таким образом, это точный эквивалент структуры match, с которой поставляется PHP 8.0.

{switch $transport}
	{case train}
		By train
	{case plane}
		By plane
	{default}
		Differently
{/switch}

Пункт {case} может содержать несколько значений, разделенных запятыми:

{switch $status}
{case $status::New}<b>new item</b>
{case $status::Sold, $status::Unknown}<i>not available</i>
{/switch}

Циклы

В Latte доступны все циклы, знакомые вам по PHP: foreach, for и while.

{foreach}

Вы пишете цикл точно так же, как и в PHP:

{foreach $langs as $code => $lang}
	<span>{$lang}</span>
{/foreach}

Кроме того, у него есть несколько удобных твиков, о которых мы сейчас поговорим.

Например, Latte проверяет, чтобы созданные переменные случайно не перезаписали одноименные глобальные переменные. Это спасет вас, когда вы предполагаете, что $lang – текущий язык страницы, и не понимаете, что foreach $langs as $lang перезаписал эту переменную.

Цикл foreach также может быть написан очень элегантно и экономично с помощью n:attribute:

<ul>
	<li n:foreach="$items as $item">{$item->name}</li>
</ul>

Знаете ли вы, что к n:attributes можно добавлять префикс inner-? Тогда в цикле будет повторяться только внутренняя часть элемента:

<div n:inner-foreach="$items as $item">
	<h4>{$item->title}</h4>
	<p>{$item->description}</p>
</div>

Таким образом, будет выведено что-то вроде:

<div>
	<h4>Foo</h4>
	<p>Lorem ipsum.</p>
	<h4>Bar</h4>
	<p>Sit dolor.</p>
</div>

{else}

Цикл foreach может принимать необязательное предложение {else}, текст которого выводится, если заданный массив пуст:

<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Sorry, no users in this list</em></li>
	{/foreach}
</ul>

$iterator

Внутри цикла foreach инициализируется переменная $iterator. В ней хранится важная информация о текущем цикле.

  • $iterator->first – это первая итерация?
  • $iterator->last – это последняя итерация?
  • $iterator->counter – счетчик итераций, начинается с 1
  • $iterator->counter0 – счетчик итераций, начинается с 0
  • $iterator->odd – эта итерация нечетная?
  • $iterator->even – эта итерация четная?
  • $iterator->parent – итератор, окружающий текущий итератор.
  • $iterator->nextValue – следующий элемент в цикле
  • $iterator->nextKey – ключ следующего элемента в цикле
{foreach $rows as $row}
	{if $iterator->first}<table>{/if}

	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>

	{if $iterator->last}</table>{/if}
{/foreach}

Лата умница и $iterator->last работает не только для массивов, но и когда цикл работает над общим итератором, где количество элементов заранее не известно.

{first} {last} {sep}

Эти теги можно использовать внутри цикла {foreach}. Содержимое {first} отображается при первом проходе. Содержимое {last} отображается … можете догадаться? Да, для последнего прохода. На самом деле это ярлыки для {if $iterator->first} и {if $iterator->last}.

Теги также могут быть записаны как n:attributes:

{foreach $rows as $row}
	{first}<h1>List of names</h1>{/first}

	<p>{$row->name}</p>

	<hr n:last>
{/foreach}

Содержимое {sep} выводится, если итерация не последняя, поэтому он подходит для печати разделителей, например, запятых между элементами списка:

{foreach $items as $item} {$item} {sep}, {/sep} {/foreach}

Это довольно практично, не так ли?

{iterateWhile}

Упрощает группировку линейных данных во время итерации в цикле foreach, выполняя итерацию во вложенном цикле до тех пор, пока не будет выполнено условие. Ознакомьтесь с подробными инструкциями.

Он также может элегантно заменить {first} и {last} в примере выше:

{foreach $rows as $row}
	<table>

	{iterateWhile}
	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>
	{/iterateWhile true}

	</table>
{/foreach}

См. также пакетные и групповые фильтры.

{for}

Мы пишем цикл точно так же, как и в PHP:

{for $i = 0; $i < 10; $i++}
	<span>Item #{$i}</span>
{/for}

Тег также может быть записан как n:attribute:

<h1 n:for="$i = 0; $i < 10; $i++">{$i}</h1>

{while}

Опять же, мы пишем цикл точно так же, как и в PHP:

{while $row = $result->fetch()}
	<span>{$row->title}</span>
{/while}

Или как n:attribute:

<span n:while="$row = $result->fetch()">
	{$row->title}
</span>

Вариант с условием в конце тега соответствует циклу do-while в PHP:

{while}
	<span>{$item->title}</span>
{/while $item = $item->getNext()}

{continueIf} {skipIf} {breakIf}

Существуют специальные теги, которые можно использовать для управления любым циклом – {continueIf ?} и {breakIf ?}, которые переходят к следующей итерации и завершают цикл, соответственно, при выполнении условий:

{foreach $rows as $row}
	{continueIf $row->date < $now}
	{breakIf $row->parent === null}
	...
{/foreach}

Тег {skipIf} очень похож на {continueIf}, но не увеличивает счетчик. Таким образом, при печати $iterator->counter и пропуске некоторых элементов в нумерации не будет дыр. Также предложение {else} будет выведено при пропуске всех элементов.

<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Sorry, no adult users in this list</em></li>
	{/foreach}
</ul>

{exitIf}

Завершает отрисовку шаблона или блока при выполнении условия.

{exitIf !$messages}

<h1>Messages</h1>
<div n:foreach="$messages as $message">
   {$message}
</div>

Включение шаблонов

{include 'file.latte'}

См. также {include block}

Тег {include} загружает и отображает указанный шаблон. На нашем любимом языке PHP это выглядит так:

<?php include 'header.phtml'; ?>

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

Вы можете передавать переменные вставленному шаблону следующим образом:

{include 'template.latte', foo: 'bar', id: 123}

Имя шаблона может быть любым выражением PHP:

{include $someVar}
{include $ajax ? 'ajax.latte' : 'not-ajax.latte'}

Вставленное содержимое может быть изменено с помощью фильтров. В следующем примере удаляется весь HTML и корректируется регистр:

<title>{include 'heading.latte' |stripHtml|capitalize}</title>

По умолчанию наследование шаблона не участвует в этом. Хотя вы можете добавлять теги блоков в включаемые шаблоны, они не будут заменять соответствующие блоки в шаблоне, в который они включены. Рассматривайте включаемые блоки как независимые и экранированные части страниц или модулей. Это поведение можно изменить с помощью модификатора with blocks:

{include 'template.latte' with blocks}

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

{sandbox}

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

{sandbox 'untrusted.latte', level: 3, data: $menu}

{block}

См. также {block name}

Блоки без названия служат для возможности применения фильтров к части шаблона. Например, можно применить фильтр полосы, чтобы удалить ненужные пробелы:

{block|strip}
<ul>
	<li>Hello World</li>
</ul>
{/block}

Обработка исключений

{try}

С помощью этих тегов очень легко создавать надежные шаблоны.

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

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
{/try}

Содержимое необязательного пункта {else} выводится только при возникновении исключения:

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Sorry, the tweets could not be loaded.</p>
{/try}

Тег также может быть записан как n:attribute:

<ul n:try>
	...
</ul>

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

{rollback}

Блок {try} также можно остановить и пропустить вручную с помощью {rollback}. Таким образом, вам не нужно проверять все входные данные заранее, и только во время рендеринга вы можете решить, имеет ли смысл рендерить объект.

{try}
<ul>
	{foreach $people as $person}
 		{skipIf $person->age < 18}
 		<li>{$person->name}</li>
	{else}
		{rollback}
	{/foreach}
</ul>
{/try}

Переменные

{var} {default}

Мы создадим новые переменные в шаблоне с помощью тега {var}:

{var $name = 'John Smith'}
{var $age = 27}

{* Multiple declaration *}
{var $name = 'John Smith', $age = 27}

Тег {default} работает аналогично, за исключением того, что он создает переменные только в том случае, если они не существуют. Если переменная уже существует и содержит null, она не будет перезаписана:

{default $lang = 'cs'}

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

{var string $name = $article->getTitle()}
{default int $id = 0}

{parameters}

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

{parameters
	$a,
	?int $b,
	int|string $c = 10
}

Переменные $a и $b без значения по умолчанию автоматически имеют значение по умолчанию null. Объявленные типы остаются информативными, и Latte не проверяет их.

В остальном объявленные переменные не передаются в шаблон. Это отличие от тега {default}.

{capture}

Используя тег {capture}, вы можете захватить вывод в переменную:

{capture $var}
<ul>
	<li>Hello World</li>
</ul>
{/capture}

<p>Captured: {$var}</p>

Метка также может быть записана как n:attribute, как и любая парная метка:

<ul n:capture="$var">
	<li>Hello World</li>
</ul>

Чтобы избежать нежелательного экранирования при печати, HTML-вывод хранится в переменной $var как объект Latte\Runtime\Html.

Другие

{contentType}

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

  • html (тип по умолчанию)
  • xml
  • javascript
  • css
  • calendar (iCal)
  • text

Его использование важно, поскольку он устанавливает контекстно-зависимую экранировку, и только после этого Latte может правильно экранировать. Например, {contentType xml} переключается в режим XML, {contentType text} полностью отключает экранирование.

Если параметр является полнофункциональным MIME-типом, например, application/xml, он также посылает браузеру HTTP-заголовок Content-Type:

{contentType application/xml}
<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>RSS feed</title>
		<item>
			...
		</item>
	</channel>
</rss>

{debugbreak}

Указывает место, где выполнение кода прервется. Используется в целях отладки, чтобы программист мог проверить среду выполнения и убедиться, что код выполняется так, как ожидалось. Поддерживается Xdebug. Кроме того, можно указать условие, при котором код должен прерваться.

{debugbreak}                {* breaks the program *}

{debugbreak $counter == 1}  {* breaks the program if the condition is met *}

{do}

Выполняет PHP-код и ничего не печатает. Как и все остальные теги, PHP-код представляет собой одно выражение, см. ограничения PHP.

{do $num++}

{dump}

Выгружает переменную или текущий контекст.

{dump $name} {* dumps the $name variable *}

{dump}       {* dumps all the defined variables *}

Требуется пакет Tracy.

{php}

Позволяет выполнить любой PHP-код. Тег должен быть активирован с помощью расширения RawPhpExtension.

{spaceless}

Удаляет ненужные пробельные символы. Аналогичен фильтру без пробелов.

{spaceless}
	<ul>
		<li>Hello</li>
	</ul>
{/spaceless}

Выходные данные:

<ul> <li>Hello</li> </ul>

Тег также может быть записан как n:attribute:

{syntax}

Теги Latte не обязательно должны быть заключены только в одинарные фигурные скобки. Вы можете выбрать другой разделитель, даже во время выполнения. Это делается с помощью {syntax…}, где параметр может быть:

  • double: {{...}}
  • off: полностью отключает теги Latte

Используя нотацию n:attribute, мы можем отключить Latte только для блока JavaScript:

<script n:syntax="off">
	var obj = {var: 123}; // this isn't a tag any more
</script>

Latte можно очень удобно использовать внутри JavaScript, только избегайте конструкций, как в этом примере, где буква сразу следует за {, см. Latte внутри JavaScript или CSS.

Если вы отключите Latte с помощью {syntax off} (т.е. тега, а не атрибута n:attribute), то он будет строго игнорировать все теги до {/syntax}.

{trace}

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

Помощники тегов HTML

n:класс

Благодаря n:class очень легко сгенерировать HTML-атрибут class именно так, как вам нужно.

Пример: Мне нужно, чтобы активный элемент имел класс active:

{foreach $items as $item}
	<a n:class="$item->isActive() ? active">...</a>
{/foreach}

И еще мне нужно, чтобы первый элемент имел классы first и main:

{foreach $items as $item}
	<a n:class="$item->isActive() ? active, $iterator->first ? 'first main'">...</a>
{/foreach}

А все элементы должны иметь класс list-item:

{foreach $items as $item}
	<a n:class="$item->isActive() ? active, $iterator->first ? 'first main', list-item">...</a>
{/foreach}

Удивительно просто, не правда ли?

n:attr

Атрибут n:attr может генерировать произвольные HTML-атрибуты с той же элегантностью, что и n:class.

{foreach $data as $item}
	<input type="checkbox" n:attr="value: $item->getValue(), checked: $item->isActive()">
{/foreach}

В зависимости от возвращаемых значений, он отображает, например:

<input type="checkbox">

<input type="checkbox" value="Hello">

<input type="checkbox" value="Hello" checked>

n:tag

Атрибут n:tag может динамически изменять имя элемента HTML.

<h1 n:tag="$heading" class="main">{$title}</h1>

Если $heading === null, то <h1> тег выводится без изменений. В противном случае имя элемента изменяется на значение переменной, так что для $heading === 'h3' записывается:

<h3 class="main">...</h3>

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

n:ifcontent

Предотвращает печать пустого HTML-элемента, т.е. элемента, не содержащего ничего, кроме пробелов.

<div>
	<div class="error" n:ifcontent>{$error}</div>
</div>

В зависимости от значений переменной $error будет выводиться:

{* $error = '' *}
<div>
</div>

{* $error = 'Required' *}
<div>
	<div class="error">Required</div>
</div>

Перевод

Чтобы теги перевода работали, необходимо настроить переводчик. Вы также можете использовать translate фильтр для перевода.

{_...}

Переводит значения на другие языки.

<a href="basket">{_'Basket'}</a>
<span>{_$item}</span>

Переводчику могут быть переданы и другие параметры:

<a href="basket">{_'Basket', domain: order}</a>

{translate}

Překládá části šablony:

<h1>{translate}Order{/translate}</h1>

{translate domain: order}Lorem ipsum ...{/translate}

Тег также может быть записан как n:attribute, чтобы перевести внутреннюю часть элемента:

<h1 n:translate>Order</h1>
версия: 3.0