Теги 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, n:elseif |
альтернативное содержимое для условий |
{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 |
{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} |
выводит ссылку на презентер |
{linkBase} |
изменение базы ссылок |
{control} |
отрисовывает компонент |
{snippet} … {/snippet} |
сниппет шаблона, который можно отправить через AJAX |
{snippetArea} |
обёртка сниппетов |
{cache} … {/cache} |
кеширует часть шаблона |
{form} … {/form} |
отрисовывает теги формы |
{form scope}, {form detached} |
варианты формы без тега или отсоединённая |
{label} … {/label} |
отрисовывает подпись элемента формы |
{input} |
отрисовывает элемент формы |
{inputError} |
выводит сообщение об ошибке элемента формы |
n:name |
активирует элемент формы |
{formContainer} … {/formContainer} |
отрисовывает контейнер формы |
{asset} |
отрисовывает ресурс как HTML-элемент или URL |
{preload} |
генерирует подсказки preload для оптимизации производительности |
n:asset |
добавляет атрибуты ресурса к HTML-элементам |
Вывод
{$var} {...} {=...}
В Latte тег {=...} служит для вывода любого выражения. Latte заботится
о вашем удобстве, поэтому, если выражение начинается с переменной или
вызова функции, знак равенства писать не нужно. На практике это значит,
что писать его почти никогда не приходится:
Name: {$name} {$surname}<br>
Age: {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} !'); // ERROR!
</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 n:elseif
Если вы записываете условие {if} ... {/if} в виде n:атрибута, у вас есть возможность
указать альтернативные ветви через n:else (начиная с 3.0.12) и
n:elseif (начиная с 3.1):
<strong n:if="$count > 0">В наличии {$count} шт.</strong>
<em n:elseif="$count < 0">Неверное количество</em>
<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>Список имён</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>Item #{$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>
Возможен и вариант с условием в закрывающем теге, соответствующий циклу 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>К сожалению, в этом списке нет взрослых</em></li>
{/foreach}
</ul>
{exitIf}
Завершает отрисовку шаблона или блока при выполнении условия (то есть “досрочный выход”).
{exitIf !$messages}
<h1>Messages</h1>
<div n:foreach="$messages as $message">
{$message}
</div>
Подключение шаблонов
{include 'file.latte'}
См. также {include block} и {embed}
Тег {include} загружает и отрисовывает указанный шаблон. В нашем
любимом языке PHP это что-то вроде:
<?php include 'header.phtml'; ?>
Подключённые шаблоны не имеют доступа к переменным активного контекста, но имеют доступ к глобальным переменным.
Передать переменные в подключаемый шаблон можно так:
{include 'template.latte', foo: 'bar', id: 123}
Имя шаблона может быть любым выражением PHP:
{include $someVar}
{include $ajax ? 'ajax.latte' : 'not-ajax.latte'}
Существует ли шаблон, можно проверить функцией hasTemplate().
Подключаемое содержимое можно изменить фильтрами. Следующий пример убирает весь 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}
Блоки без имени дают возможность применить фильтры к части шаблона. Например, вы можете применить фильтр spaceless, чтобы убрать лишние пробелы:
{block|spaceless}
<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 = 'en'}
Вы можете указать и типы переменных. Пока они носят информативный характер, и 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(тип по умолчанию)xmljavascriptcsscalendar(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} {* приостанавливает программу *}
{debugbreak $counter == 1} {* приостанавливает программу при выполнении условия *}
{do}
Выполняет PHP-код и ничего не выводит. Как и во всех остальных тегах, под PHP-кодом понимается одно выражение, см. Ограничения PHP.
{do $num++}
{dump}
Выводит дамп переменной или текущего контекста.
{dump $name} {* Выводит дамп переменной $name *}
{dump} {* Выводит дамп всех определённых на данный момент переменных *}
Требует библиотеку Tracy.
{php}
По умолчанию {php} работает как устаревший псевдоним для {do} и вычисляет только одно выражение. Чтобы выполнять
произвольный 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, вы ясно увидите стек вызовов
вместе со всеми переданными аргументами.
Помощники верстальщика
n:class
Начиная с Latte 3.1 такую же функциональность получил и обычный HTML-атрибут class. Так что использовать 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 умеет формировать произвольные HTML-атрибуты с той
же изящностью, что и 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>
Возможности умных атрибутов в Latte 3.1, такие как опускание значений
null или передача массивов в class или style, работают и
внутри n:attr:
<div n:attr="class: [a, b], title: $title"></div>
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>