Тагове Latte

Обобщение и описание на всички вградени тагове на Latte.

Отпечатване
{$var}, {...} или {=...} отпечатва скринирана променлива или израз
{$var|filter} отпечатва с филтри
{l} или {r} отпечатва символ { or }
условия
{if}{elseif}{else}{/if} # условие ако
{ifset}{elseifset}{/ifset} условие ifset
{ifchanged}{/ifchanged} проверка за промени
{switch} {case} {default} {/switch} състояние на превключване
n:else алтернативно съдържание за условията
Цикли
{foreach}{/foreach} foreach
# {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'} 00 включва шаблона в режим на пясъчник
Блокове, оформления, наследяване на шаблони
{block} анонимен блок
{block blockname} 00 дефиниция на блок
{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} опит за отхвърляне на блок
Променливи
{var $foo = value} създаване на променливи
{default $foo = value} стойност по подразбиране, когато не е декларирана променлива
{parameters} деклариране на променливи, типове стойности по подразбиране
{capture}{/capture} улавя секцията за променливата
Типове
{varType} декларира тип променлива
{varPrint} 00 предлага видове променливи
{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
{link} 00 отпечатва връзка
{plink} отпечатва връзката към главния модул  
{control} отпечатва компонент  
{snippet}{/snippet} откъс от шаблон, който може да бъде изпратен чрез AJAX  
{snippetArea} плик за фрагмент  
{cache}{/cache} кеширане на секцията с шаблони  
Налично само в Nette Forms
{form}{/form} # Отпечатва елемента на формата
{label} 00 … {/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:атрибут, имате възможност да посочите алтернативен клон, като използвате 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} може да бъде посочен и в тага за край. Това е полезно в ситуации, в които все още не знаем стойността на условието в момента на отваряне на тага. Нека го наречем забавено решение.

Например, започваме да извеждаме таблица със записи от база данни и едва след като отчетът е завършен, разбираме, че в базата данни няма записи. Затова поставяме условието в крайния таг {/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

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

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

Lata е умен и $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} работи по подобен начин, с изключение на това, че създава променливи само ако те не съществуват:

{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}                {* прекъсва програмата *}

{debugbreak $counter == 1}  {* прекъсва програмата, ако условието е изпълнено *}

{do}

Изпълнява кода на PHP и не отпечатва нищо. Както и при всички останали тагове, PHP кодът е единичен израз, вижте Ограничения на PHP.

{do $num++}

{dump}

Разтоварване на променлива или на текущия контекст.

{dump $name} {* изхвърля променливата $name *}

{dump}       {* изхвърля всички дефинирани променливи *}

Изисква се пакет Tracy.

{php}

Позволява ви да изпълнявате всеки код на PHP. Тагът трябва да бъде активиран с помощта на разширението RawPhpExtension.

{spaceless}

Премахва ненужните бели символи. Подобно на филтъра без бели полета.

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

Изход:

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

Тагът може да се запише и като n:attribute:

{syntax}

Не е необходимо таговете Latte да бъдат затворени само в единични къдрави скоби. Можете да изберете различен разделител, дори по време на изпълнение. Това се прави с помощта на {syntax…}, където параметърът може да бъде:

  • двойно: {{...}}
  • 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:), той ще игнорира стриктно всички тагове до {/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 може да генерира произволни 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