Теги 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} |
отображает трассировку стека |
n:class |
динамическая запись HTML-атрибута class |
n:attr |
динамическая запись любых HTML-атрибутов |
n:tag |
динамическая запись имени HTML-элемента |
n:ifcontent |
пропускает пустой HTML-тег |
n:href |
ссылка, используемая
в HTML-элементах <a> |
{link} |
выводит ссылку |
{plink} |
выводит ссылку на презентер |
{control} |
рендерит компонент |
{snippet} … {/snippet} |
сниппет, который можно отправить через AJAX |
{snippetArea} |
обертка для сниппетов |
{cache} … {/cache} |
кеширует часть шаблона |
{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 < 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>