Nette Documentation Preview

syntax
Тагове Latte
************

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

.[table-latte-tags language-latte]
|## Отпечатване
| `{$var}`, `{...}` или `{=...}` | [отпечатва скринирана променлива или израз |#Printing]
| `{$var\|filter}` | [отпечатва с филтри |#Filters]
| `{l}` или `{r}` | отпечатва символ `{` or `}`

.[table-latte-tags language-latte]
|## условия
| `{if}`... `{elseif}`... `{else}`... `{/if}` |# [условие ако |#if-elseif-else]
| `{ifset}`... `{elseifset}`... `{/ifset}` | [условие ifset |#ifset-elseifset]
| `{ifchanged}`... `{/ifchanged}` | [проверка за промени |#ifchanged]
| `{switch}` `{case}` `{default}` `{/switch}` | [състояние на превключване |#switch-case-default]
| `n:else` | [алтернативно съдържание за условията |#n:else]

.[table-latte-tags language-latte]
|## Цикли
| `{foreach}`... `{/foreach}` | [foreach |#foreach]
|# `{for}`... `{/for}` | [за |#for]
|# `{while}`... `{/while}` | [while |#while]
| `{continueIf $cond}` | [преминаване към следващата итерация |#continueIf-skipIf-breakIf]
| `{skipIf $cond}` | [прескачане на текущата итерация на цикъла |#continueIf-skipIf-breakIf]
| `{breakIf $cond}` | [прекъсване на цикъла |#continueIf-skipIf-breakIf]
| `{exitIf $cond}` | [ранен изход |#exitIf]
| `{first}`... `{/first}` | [Това ли е първата итерация |#first-last-sep]?
| `{last}`... `{/last}` | [Това ли е последната итерация |#first-last-sep]?
| `{sep}`... `{/sep}` | [Ще последва ли следващата итерация |#first-last-sep]?
| `{iterateWhile}`... `{/iterateWhile}` | [структуриран foreach |#iterateWhile]
| `$iterator` | [специална променлива в цикъла foreach |#iterator]

.[table-latte-tags language-latte]
|## Включване на други шаблони
| `{include 'file.latte'}` | [включване на шаблон от друг файл |#include]
| `{sandbox 'file.latte'}` |00 | [включва шаблона в режим на пясъчник |#sandbox]

.[table-latte-tags language-latte]
|## Блокове, оформления, наследяване на шаблони
| `{block}` | [анонимен блок |#block]
| `{block blockname}` |00 | [дефиниция на блок |template-inheritance#Blocks]
| `{define blockname}` | [блок за дефиниции |template-inheritance#Definitions] за [бъдеща употреба |template-inheritance#Definitions]
| `{include blockname}` | [принтира блок |template-inheritance#Printing-Blocks]
| `{include blockname from 'file.latte'}` отпечатва [блок от файл |template-inheritance#Printing-Blocks]
| `{import 'file.latte'}` | [зарежда блокове от друг шаблон |template-inheritance#Horizontal-Reuse]
| `{layout 'file.latte'}` / `{extends}` | [посочва файл за оформление |template-inheritance#Layout-Inheritance]
| `{embed}`... `{/embed}` | [зарежда шаблон или блок и позволява презаписване на блокове |template-inheritance#Unit-Inheritance]
| `{ifset blockname}`... `{/ifset}` | [условие, ако е дефиниран блок |template-inheritance#Checking-Block-Existence]

.[table-latte-tags language-latte]
|## Обработка на изключения
| `{try}`... `{else}`... `{/try}` |# [улавяне на изключение |#try]
| `{rollback}` | [опит за отхвърляне на блок |#rollback]

.[table-latte-tags language-latte]
|## Променливи
| `{var $foo = value}` | [създаване на променливи |#var-default]
| `{default $foo = value}` | [стойност по подразбиране, когато не е декларирана променлива |#var-default]
| `{parameters}` | [деклариране на променливи, типове стойности по подразбиране |#parameters]
| `{capture}`... `{/capture}` | [улавя секцията за променливата |#capture]

.[table-latte-tags language-latte]
|## Типове
| `{varType}` | [декларира тип променлива |type-system#varType]
| `{varPrint}` |00 | [предлага видове променливи |type-system#varPrint]
| `{templateType}` | [декларира типове променливи с клас |type-system#templateType]
| `{templatePrint}` | [генерира клас със свойства |type-system#templatePrint]

.[table-latte-tags language-latte]
|## Превод
| `{_string}` | [отпечатва превода |#Translation]
| `{translate}`... `{/translate}` |# превежда [съдържанието |#Translation]

.[table-latte-tags language-latte]
|## Други
| `{contentType}` | [превключва режима на избягване и изпраща HTTP заглавие |#contentType]
| `{debugbreak}` | [задава точка на прекъсване в кода |#debugbreak]
| `{do}` | [оценява израза, без да го отпечатва |#do]
| `{dump}` | [нулиране на променливите в Tracy Bar |#dump]
| `{php}` | [Изпълнява всеки код на PHP |#php]
| `{spaceless}`... `{/spaceless}` | [изтрива нежеланите символи за бял интервал |#spaceless]
| `{syntax}` | [смяна на синтаксиса по време на изпълнение|#Syntax]
| `{trace}` | [показва проследяването на стека |#trace]

.[table-latte-tags language-latte]
|## Помощни средства за HTML тагове
| `n:class` | [атрибут на интелигентен клас |#n-class]
| `n:attr` | [интелигентни атрибути на HTML |#n-attr]
| `n:tag` | [име на динамичен HTML елемент |#n-tag]
| `n:ifcontent` | [пропускане на празен HTML таг |#n-ifcontent]

.[table-latte-tags language-latte]
|## Налично само в Nette Framework
| `n:href` | [връзка в елементи на HTML |application:creating-links#In-the-Presenter-Template]
| `{link}` |00 | [отпечатва връзка |application:creating-links#In-the-Presenter-Template]
| `{plink}` | [отпечатва връзката към главния модул |application:creating-links#In-the-Presenter-Template]
| `{control}` | [отпечатва компонент |application:components#Rendering]
| `{snippet}`... `{/snippet}` | [откъс от шаблон, който може да бъде изпратен чрез AJAX |application:ajax#snippets-in-latte]
| `{snippetArea}` | [плик за фрагмент |application:ajax#snippet-areas]
| `{cache}`... `{/cache}` | [кеширане на секцията с шаблони |caching:#Caching-in-Latte]

.[table-latte-tags language-latte]
|## Налично само в Nette Forms
| `{form}`... `{/form}` |# [Отпечатва елемента на формата |forms:rendering#form]
| `{label}`|00 ... `{/label}` | [отпечатва тага за въвеждане на формуляра |forms:rendering#label-input]
| `{input}` | [отпечатва елемента за влизане във формата|forms:rendering#label-input]
| `{inputError}` | [отпечатва съобщението за грешка за елемента за въвеждане на форма |forms:rendering#inputError]
| `n:name` [активира входния елемент на HTML |forms:rendering#n:name]
| `{formContainer}`... `{/formContainer}` | [визуализиране на контейнера за формуляри |forms:rendering#special-cases]


Отпечатъци .[#toc-printing]
===========================


`{$var}` `{...}` `{=...}`
-------------------------

Latte използва етикета `{=...}`, за да отпечата на изхода всеки израз. Ако изразът започва с променлива или с извикване на функция, не е необходимо да се пише знак за равенство. Това на практика означава, че почти никога не е необходимо да се пише:

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

Можете да запишете всичко, което знаете от PHP, като израз. Не е нужно да учите нов език. Например:


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

Моля, не търсете смисъл в предишния пример, но ако го откриете там, пишете ни :-)


Избягване на изхода .[#toc-escaping-output]
-------------------------------------------

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

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

За да бъдем точни, Latte използва контекстно чувствително ескапиране, което е толкова важна и уникална функция. че сме [му |safety-first#Context-Aware-Escaping] посветили [отделна глава |safety-first#Context-Aware-Escaping].

А ако отпечатвате кодирано в HTML съдържание от надежден източник? След това можете лесно да деактивирате ескапирането:

```latte
{$trustedHtmlString|noescape}
```

.[warning]
Неправилното използване на филтъра `noescape` може да доведе до уязвимост XSS! Никога не го използвайте, освен ако не сте абсолютно сигурни** в това, което правите, и че низът, който отпечатвате, е от надежден източник.


Отпечатване в JavaScript .[#toc-printing-in-javascript]
-------------------------------------------------------

Благодарение на контекстно чувствителното ескапиране е много лесно да отпечатвате променливи в JavaScript и Latte ще ги ескапира правилно.

Не е задължително променливата да бъде низ, поддържа се всякакъв тип данни, които след това се кодират като JSON:

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

Генерира:

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

Това е и причината, поради която **не ограждайте променливата в кавички**: Latte ги добавя около струните. А ако искате да поставите символна променлива в друг символен низ, просто ги конкатенирайте:

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

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

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


Филтри .[#toc-filters]
----------------------

Въведеният израз може да бъде променен с помощта на [филтри |syntax#Filters]. Например в този пример низът се преобразува в главни букви и се свежда до максимум 30 символа:

```latte
{$string|upper|truncate:30}
```

Можете също така да прилагате филтри към части от израз, както следва:

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


Условия .[#toc-conditions]
==========================


`{if}` `{elseif}` `{else}`
--------------------------

Условията се държат точно както техните аналози в PHP. Можете да използвате същите изрази, които познавате от PHP, и не е необходимо да учите нов език.

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

Както всеки сдвоен таг, двойката `{if} ... {/ if}` може да се запише като [n:attribute |syntax#n-attributes], например:

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

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

```latte
<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` .{data-version:3.0.11}
-------------------------------

Ако запишете условието `{if} ... {/if}` под формата на [n:атрибут |syntax#n:attributes], имате възможност да посочите алтернативен клон, като използвате `n:else`:

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

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

Атрибутът `n:else` може да се използва и в комбинация с [`n:ifset` |#ifset-elseifset], [`n:foreach` |#foreach], [`n:try` |#try], [`n:ifcontent` |#n:ifcontent], и [`n:ifchanged` |#ifchanged].


`{/if $cond}`
-------------

Може би ще се изненадате да научите, че изразът в условието `{if}` може да бъде посочен и в тага за край. Това е полезно в ситуации, в които все още не знаем стойността на условието в момента на отваряне на тага. Нека го наречем забавено решение.

Например, започваме да извеждаме таблица със записи от база данни и едва след като отчетът е завършен, разбираме, че в базата данни няма записи. Затова поставяме условието в крайния таг `{/if}`, и ако няма запис, няма да бъде отпечатан нито един от тях:

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

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

Удобно е, нали?

Можете също така да използвате `{else}` в условие за забавяне, но не и `{elseif}`.


`{ifset}` `{elseifset}`
-----------------------

.[note]
Вижте също [`{ifset block}` |template-inheritance#Checking-Block-Existence]

Използвайте условието `{ifset $var}`, за да определите дали дадена променлива (или няколко променливи) съществува и има ненулева стойност. Всъщност това е същото като `if (isset($var))` в PHP. Както всеки сдвоен таг, и този може да бъде записан като [n:attribute |syntax#n-attributes], затова нека го покажем с пример:

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


`{ifchanged}`
-------------

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

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

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

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

Ако обаче не е посочен аргумент, самото съдържание за визуализиране ще бъде проверено според предишното му състояние. Това означава, че в предишния пример можем спокойно да пропуснем аргумента в тага. Разбира се, можем да използваме и [n:attribute |syntax#n-attributes]:

```latte
{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.

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

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

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


Цикли .[#toc-loops]
===================

В Latte са налични всички цикли, познати от PHP: foreach, for и while.


`{foreach}`
-----------

Записвате цикъла по същия начин, както в PHP:

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

Той има и някои удобни настройки, за които ще говорим след малко.

Например, Latte проверява дали създадените променливи не презаписват случайно глобални променливи със същото име. Това ще ви спаси, когато приемете, че `$lang` е текущият език на страницата и не осъзнаете, че `foreach $langs as $lang` е презаписала тази променлива.

Цикълът foreach също може да бъде написан много елегантно и икономично с помощта на [n:attribute |syntax#n-attributes]:

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

Знаете ли, че можете да използвате префикс n:attributes с `inner-`? Тогава в цикъла ще се повтаря само вътрешността на елемента:

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

Така ще се получи нещо подобно на:

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


`{else}` .{toc: foreach-else}
-----------------------------

Цикълът `foreach` може да приеме незадължително изречение `{else}`, чийто текст се извежда, ако даденият масив е празен:

```latte
<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` - ключ на следващия елемент в цикъла


```latte
{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 |syntax#n-attributes]:

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

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

	<hr n:last>
{/foreach}
```

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

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

Това е доста практично, нали?


`{iterateWhile}`
----------------

Опростява групирането на линейни данни по време на итерация в цикъл foreach чрез итерация във вложен цикъл, докато условието е изпълнено. [Прочетете инструкциите в книгата с рецепти |cookbook/iteratewhile].

Той може също така елегантно да замени `{first}` и `{last}` в примера по-горе:

```latte
{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:

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

Тагът може да се запише и като [n:attribute |syntax#n-attributes]:

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


`{while}`
---------

Отново записваме цикъла по същия начин, както в PHP:

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

Или като [n:attribute |syntax#n-attributes]:

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

Условният вариант в края на тага съответства на цикъла do-while в PHP:

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


`{continueIf}` `{skipIf}` `{breakIf}`
-------------------------------------

Съществуват специални маркери, които могат да се използват за управление на всеки цикъл - `{continueIf ?}` и `{breakIf ?}`, които преминават към следващата итерация и съответно прекратяват цикъла, когато са изпълнени условията:

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


Тагът `{skipIf}` е много подобен на `{continueIf}`, но не увеличава брояча. По този начин няма да има дупки в номерацията при отпечатване на `$iterator->counter` и прескачане на някои елементи. Също така изречението {else} ще бъде изведено, ако всички елементи са пропуснати.

```latte
<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}` .{data-version:3.0.5}
--------------------------------

Завършва визуализирането на шаблона или блока, когато условието е изпълнено.

```latte
{exitIf !$messages}

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


Разрешаване на шаблони .[#toc-including-templates]
==================================================


`{include 'file.latte'}` .{toc: include}
----------------------------------------

.[note]
Вижте също [`{include block}` |template-inheritance#Printing-Blocks]

Тагът `{include}` зарежда и показва посочения шаблон. На любимия ни език PHP тя изглежда по следния начин

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

Разрешените шаблони нямат достъп до променливите на активния контекст, но имат достъп до глобалните променливи.

Можете да предавате променливи на вмъкнатия шаблон по следния начин:

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

Името на шаблона може да бъде произволен израз на PHP:

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

Вмъкнатото съдържание може да се променя с помощта на [филтри |syntax#Filters]. Следващият пример премахва целия HTML и коригира регистрите:

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

[Наследяването на шаблона |template inheritance] **не участва** в това по подразбиране. Въпреки че можете да добавяте блокови тагове към включените шаблони, те няма да заменят съответстващите блокове в шаблона, в който са включени. Мислете за включванията като за независими и защитени части от страници или модули. Това поведение може да бъде променено с помощта на модификатора `with blocks`:

```latte
{include 'template.latte' with blocks}
```

Връзката между името на файла, посочено в тага, и файла на диска зависи от [програмата за зареждане |extending-latte#Loaders].


`{sandbox}`
-----------

Когато разрешавате генериран от крайния потребител шаблон, помислете за неговото изолиране (за повече информация вижте [документацията за изолиране |sandbox]):

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


`{block}`
=========

.[note]
Вижте също [`{block name}` |template-inheritance#Blocks]

Блоковете без заглавие се използват, за да позволят прилагането на [филтри |syntax#Filters] към част от шаблона. Например можете да приложите филтър за [ленти |filters#strip], за да премахнете ненужните интервали:

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


Обработка на изключения .[#toc-exception-handling]
==================================================


`{try}`
-------

Тези етикети улесняват създаването на надеждни шаблони.

Ако при визуализиране на блок възникне изключение `{try}`, целият блок се изхвърля и визуализирането ще продължи след него:

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

Съдържанието на незадължителната клауза `{else}` се визуализира само при възникване на изключение:

```latte
{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 |syntax#n-attributes]:

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

Можете също така да дефинирате [свой собствен обработчик на изключения за |develop#Exception-Handler] регистриране:


`{rollback}`
------------

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

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


Променливи .[#toc-variables]
============================


`{var}` `{default}`
-------------------

Ще създадем нови променливи в шаблона, като използваме тага `{var}`:

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

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

Тагът `{default}` работи по подобен начин, с изключение на това, че създава променливи само ако те не съществуват:

```latte
{default $lang = 'cs'}
```

Можете също така да зададете [типове променливи |type-system]. Засега те са информативни и Latte не ги проверява.

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


`{parameters}`
--------------

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

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

Променливите `$a` и `$b` без стойност по подразбиране автоматично се подразбират на `null`. Декларираните типове остават информативни и Latte не ги проверява.

В противен случай декларираните променливи не се предават на шаблона. Това е различно от тага `{default}`.


`{capture}`
-----------

С помощта на маркера `{capture}`, можете да уловите изхода в променлива:

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

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

Тагът може да се запише и като [n:attribute |syntax#n:attributes], както всеки друг двойков таг:

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

Изходът на HTML се съхранява в променливата `$var` като обект `Latte\Runtime\Html`, за да [се избегне нежелано ескапиране |develop#disabling-auto-escaping-of-variable] при отпечатване.


Други .[#toc-others]
====================


`{contentType}`
---------------

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

- `html` (тип по подразбиране)
- `xml`
- `javascript`
- `css`
- `calendar` (iCal)
- `text`

Използването му е важно, тъй като той задава [контекстно ескапиране |safety-first#Context-Aware-Escaping] и само тогава Latte може да ескапира правилно. Например `{contentType xml}` превключва на режим XML, а `{contentType text}` деактивира напълно ескапирането.

Ако параметърът е пълен MIME тип, като например `application/xml`, той също така изпраща HTTP заглавие към браузъра `Content-Type`:

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


`{debugbreak}`
--------------

Посочва мястото, където изпълнението на кода се прекъсва. Използва се за отстраняване на грешки, за да може програмистът да провери средата на изпълнение и да се увери, че кодът се изпълнява според очакванията. Поддържа се от [Xdebug |https://xdebug.org]. Възможно е също така да се посочи условието, при което кодът трябва да се прекъсне.

```latte
{debugbreak}                {* прекъсва програмата *}

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


`{do}`
------

Изпълнява кода на PHP и не отпечатва нищо. Както и при всички останали тагове, PHP кодът е единичен израз, вижте [Ограничения на PHP |syntax#PHP Limitations in Latte].

```latte
{do $num++}
```


`{dump}`
--------

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

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

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

.[caution]
Изисква се пакет [Tracy |tracy:].


`{php}`
-------

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


`{spaceless}`
-------------

Премахва ненужните бели символи. Подобно на филтъра [без бели полета |filters#spaceless].

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

Изход:

```latte
<ul> <li>Hello</li> </ul>
```

Тагът може да се запише и като [n:attribute |syntax#n-attributes]:


`{syntax}`
----------

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

- двойно: `{{...}}`
- off: деактивира напълно маркерите Latte

Като използваме означението n:attribute, можем да забраним Latte само за блок на JavaScript:

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

Latte може да се използва много удобно в JavaScript, само избягвайте конструкции като в този пример, където буквата следва непосредствено след `{`, вижте [Latte в JavaScript или CSS |recipes#Latte-Inside-JavaScript-or-CSS].

Ако деактивирате Latte с `{syntax off}` (т.е. тага, а не атрибута n:), той ще игнорира стриктно всички тагове до `{/syntax}`.


{trace}
-------

Хвърля изключение `Latte\RuntimeException`, чието проследяване на стека е направено в духа на шаблоните. Така че вместо извикване на функции и методи се използват извикване на блокове и вмъкване на шаблони. Ако използвате инструмент за визуално показване на хвърлени изключения, като например [Tracy |tracy:], ще видите ясно стека на извикванията, включително всички подадени аргументи.


Помощни средства за HTML тагове .[#toc-html-tag-helpers]
========================================================


n:class .[#toc-n-class]
-----------------------

С помощта на `n:class` е много лесно да генерирате HTML атрибута `class` точно по желания от вас начин.

Пример: Искам активният елемент да има клас `active`:

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

Освен това ми е необходимо първият елемент да има класовете `first` и `main`:

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

И всички елементи трябва да имат клас `list-item`:

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

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


n:attr .[#toc-n-attr]
---------------------

Атрибутът `n:attr` може да генерира произволни HTML атрибути със същата елегантност като [n:class |#n-class].

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

В зависимост от върнатите стойности се показват например:

```latte
<input type="checkbox">

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

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


n:tag .[#toc-n-tag]
-------------------

Атрибутът `n:tag` може динамично да променя името на HTML елемент.

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

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

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

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


n:ifcontent .[#toc-n-ifcontent]
-------------------------------

Предотвратява отпечатването на празен HTML елемент, т.е. елемент, съдържащ само интервали.

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

В зависимост от стойностите на променливата ще бъде отпечатан `$error`:

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

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


Превод .[#toc-translation]
==========================

За да работят етикетите за превод, трябва да настроите [преводач |develop#TranslatorExtension]. Можете също така да използвате [`translate` |filters#translate] филтър за превод.


`{_...}`
--------

Превежда стойности на други езици.

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

Други параметри също могат да бъдат прехвърлени към транслатора:

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


`{translate}`
-------------

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

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

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

Тагът може да се запише и като [n:attribute |syntax#n-attributes], за да се преведе вътрешната част на елемента:

```latte
<h1 n:translate>Order</h1>
```

Тагове 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>