Теги Latte

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

Вывод
{$var}, {...} или {=...} выводит экранированную переменную или выражение
{$var|filter} выводит с использованием фильтров
{l} или {r} выводит символ { или }
Условия
{if}{elseif}{else}{/if} условие if
{ifset}{elseifset}{/ifset} условие ifset
{ifchanged}{/ifchanged} проверка, произошло ли изменение
{switch} {case} {default} {/switch} условие switch
n:else альтернативное содержимое для условий
Циклы
{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} предлагает класс с типами переменных
Переводы
{_...} выводит перевод
{translate}{/translate} переводит содержимое
Прочее
{contentType} переключает экранирование и отправляет HTTP-заголовок
{debugbreak} помещает точку останова в код
{do} выполняет код, но ничего не выводит
{dump} выводит переменные в Tracy Bar
{php} выполняет любой PHP-код
{spaceless}{/spaceless} удаляет лишние пробелы
{syntax} изменение синтаксиса во время выполнения
{trace} отображает трассировку стека
Помощники HTML-кодера
n:class динамическая запись HTML-атрибута 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 оживляет элемент формы
{formContainer}{/formContainer} рендеринг контейнера формы

Вывод

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

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

Имя: {$name} {$surname}<br>
Возраст: {date('Y') - $birth}<br>

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

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

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

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

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

<p>{='one < two'}</p>   {* выводит: '<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} !');         // ОШИБКА!
</script>

Фильтры

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

{$string|upper|truncate:30}

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

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

Условия

{if} {elseif} {else}

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

{if $product->inStock > Stock::Minimum}
	В наличии
{elseif $product->isOnWay()}
	В пути
{else}
	Недоступно
{/if}

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

<p n:if="$count > 0">В наличии {$count} штук</p>

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

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

{* выводит 'Hello' когда $clickable ложно *}
{* выводит '<a href="...">Hello</a>' когда $clickable истинно *}

Божественно.

n:else

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

<strong n:if="$count > 0">В наличии {$count} штук</strong>

<em n:else>недоступно</em>

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

{/if $cond}

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

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

{if}
	<h1>Вывод строк из базы данных</h1>

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

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

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

{ifset} {elseifset}

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

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

<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:атрибут:

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

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

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

{switch} {case} {default}

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

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

Это точный эквивалент структуры match, которая появилась в PHP 8.0.

{switch $transport}
	{case train}
		Поездом
	{case plane}
		Самолетом
	{default}
		Иначе
{/switch}

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

{switch $status}
{case $status::New}<b>новая позиция</b>
{case $status::Sold, $status::Unknown}<i>недоступно</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:атрибута:

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

Знаете ли вы, что к n:атрибутам можно добавить префикс 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>К сожалению, в этом списке нет пользователей</em></li>
	{/foreach}
</ul>

$iterator

Внутри цикла foreach Latte создает переменную $iterator, с помощью которой мы можем узнавать полезную информацию о текущем цикле:

  • $iterator->first – это первый проход цикла?
  • $iterator->last – это последний проход?
  • $iterator->counter – какой это проход, считая с единицы?
  • $iterator->counter0 – какой это проход, считая с нуля?
  • $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}

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

{first} {last} {sep}

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

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

{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}

См. также фильтры batch и group.

{for}

Цикл записываем точно так же, как в PHP:

{for $i = 0; $i < 10; $i++}
	<span>Элемент {$i}</span>
{/for}

Тег также можно использовать как n:атрибут:

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

{while}

Цикл опять же записываем точно так же, как в PHP:

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

Или как n:атрибут:

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

Возможен также вариант с условием в закрывающем теге, который соответствует в PHP циклу do-while:

{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>К сожалению, в этом списке нет взрослых</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}

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

{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>К сожалению, не удалось загрузить твиты.</p>
{/try}

Тег также можно использовать как n:атрибут:

<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}

{* Множественное объявление *}
{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 $var}
<ul>
	<li>Hello World</li>
</ul>
{/capture}

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

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

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

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

Прочее

{contentType}

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

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

Его использование важно, потому что он устанавливает контекстно-зависимое экранирование и только так может экранировать правильно. Например, {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}                {* приостанавливает программу *}

{debugbreak $counter == 1}  {* приостанавливает программу при выполнении условия *}

{do}

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

{do $num++}

{dump}

Выводит переменную или текущий контекст.

{dump $name} {* Выводит переменную $name *}

{dump}       {* Выводит все текущие определенные переменные *}

Требуется библиотека Tracy.

{php}

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

{spaceless}

Удаляет лишние пробелы из вывода. Работает аналогично фильтру spaceless.

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

Генерирует

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

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

{syntax}

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

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

С использованием n:атрибутов можно отключить Latte, например, только для одного блока JavaScript:

<script n:syntax="off">
	var obj = {var: 123}; // это уже не тег
</script>

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

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

{trace}

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

Помощники HTML-кодера

n:class

Благодаря 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 умеет с той же элегантностью, что и n:class, генерировать любые HTML-атрибуты.

{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">{_'Корзина'}</a>
<span>{_$item}</span>

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

<a href="basket">{_'Корзина', domain: order}</a>

{translate}

Переводит части шаблона:

<h1>{translate}Заказ{/translate}</h1>

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

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

<h1 n:translate>Заказ</h1>
версия: 3.0