Nette Documentation Preview

syntax
Latte tagy (makra)
******************

.[perex]
Přehled a popis všech tagů (neboli značek či maker) šablonovacího systému Latte, které jsou vám standardně k dispozici.

.[table-latte-tags language-latte]
|## Vypisování
| `{$var}`, `{...}` nebo `{=...}`  | [vypíše escapovanou proměnnou nebo výraz |#Vypisování]
| `{$var\|filter}`                 | [vypíše s použitím filtrů |#Filtry]
| `{l}` nebo `{r}`                 | vypíše znak `{` nebo `}`

.[table-latte-tags language-latte]
|## Podmínky
| `{if}` … `{elseif}` … `{else}` … `{/if}`    | [podmínka if|#if-elseif-else]
| `{ifset}` … `{elseifset}` … `{/ifset}`      | [podmínka ifset|#ifset-elseifset]
| `{ifchanged}` … `{/ifchanged}`              | [test jestli došlo ke změně |#ifchanged]
| `{switch}` `{case}` `{default}` `{/switch}` | [podmínka switch|#switch]

.[table-latte-tags language-latte]
|## Cykly
| `{foreach}` … `{/foreach}`     | [#foreach]
| `{for}` … `{/for}`             | [#for]
| `{while}` … `{/while}`         | [#while]
| `{continueIf $cond}`           | [pokračovat další iterací |#continueif-skipif-breakif]
| `{skipIf $cond}`               | [přeskočit iteraci |#continueif-skipif-breakif]
| `{breakIf $cond}`              | [přerušení cyklu |#continueif-skipif-breakif]
| `{first}` … `{/first}`         | [jde o první průchod? |#first-last-sep]
| `{last}` … `{/last}`           | [jde o poslední průchod? |#first-last-sep]
| `{sep}` … `{/sep}`             | [bude ještě následovat průchod? |#first-last-sep]
| `{iterateWhile}` … `{/iterateWhile}` | [strukturovaný foreach|#iterateWhile]
| `$iterator`                    | [speciální proměnná uvnitř foreach |#$iterator]

.[table-latte-tags language-latte]
|## Vložení dalších šablon
| `{include 'file.latte'}`       | [načte šablonu z dalšího souboru |#include]
| `{sandbox 'file.latte'}`       | [načte šablonu v sandbox režimu |#sandbox]

.[table-latte-tags language-latte]
|## Bloky, layouty, dědičnost šablon
| `{block}`                      | [anonymní blok|#block]
| `{block blockname}`            | [definuje blok |template-inheritance#bloky]
| `{define blockname}`           | [definuje blok pro pozdější použití |template-inheritance#definice]
| `{include blockname}`          | [vykreslení bloku|template-inheritance#Vykreslení bloků]
| `{include blockname from 'file.latte'}` | [vykreslí blok ze souboru |template-inheritance#Vykreslení bloků]
| `{import 'file.latte'}`        | [načte bloky ze šablony |template-inheritance#horizontální znovupoužití]
| `{layout 'file.latte'}` / `{extends}` | [určuje soubor s layoutem |template-inheritance#Layoutová dědičnost]
| `{embed}` … `{/embed}`         | [načte šablonu či blok a umožní přepsat bloky |template-inheritance#jednotková dědičnost]
| `{ifset blockname}` … `{/ifset}`   | [podmínka, zda existuje blok |template-inheritance#Kontrola existence bloků]

.[table-latte-tags language-latte]
|## Řízení výjimek
| `{try}` … `{else}` … `{/try}`  | [zachycení výjimek |#try]
| `{rollback}`                   | [zahození bloku try |#rollback]

.[table-latte-tags language-latte]
|## Proměnné
| `{var $foo = value}`           | [vytvoří proměnnou |#var-default]
| `{default $foo = value}`       | [vytvoří proměnnou, pokud neexistuje |#var-default]
| `{parameters}`                 | [deklaruje proměnné, typy a výchozí hodnoty |#parameters]
| `{capture}` … `{/capture}`     | [zachytí blok do proměnné |#capture]

.[table-latte-tags language-latte]
|## Typy
| `{varType}`                    | [deklaruje typ proměnné |type-system#varType]
| `{varPrint}`                   | [navrhne typy proměnných |type-system#varPrint]
| `{templateType}`               | [deklaruje typy proměnných podle třídy |type-system#templateType]
| `{templatePrint}`              | [navrhne třídu s typy proměnných |type-system#templatePrint]

.[table-latte-tags language-latte]
|## Ostatní
| `{contentType}`                | [přepne escapování a pošle HTTP hlavičku |#contenttype]
| `{debugbreak}`                 | [umístí do kódu breakpoint |#debugbreak]
| `{do}`                         | [vykoná kód, ale nic nevypíše |#do]
| `{dump}`                       | [dumpuje proměnné do Tracy Bar |#dump]
| `{spaceless}` … `{/spaceless}` | [odstraní nadbytečné mezery |#spaceless]
| `{syntax}`                     | [změna syntaxe za běhu |#syntax]
| `{trace}`                      | [zobrazí stack trace |#trace]

.[table-latte-tags language-latte]
|## Pomocníci HTML kodéra
| `n:class`                      | [dynamický zápis HTML atributu class |#n:class]
| `n:attr`                       | [dynamický zápis jakýchkoliv HTML atributů |#n:attr]
| `n:tag`                        | [dynamický zápis jména HTML elementu |#n:tag]
| `n:ifcontent`                  | [Vynechá prázdný HTML tag |#n:ifcontent]

.[table-latte-tags language-latte]
|## Dostupné pouze v Nette Frameworku
| `{_string}`                    | [vypíše překlad |doc:best-practices/translations#preklad-sablon]
| `{translate}` … `{/translate}` | [přeloží obsah |doc:best-practices/translations#preklad-sablon]
| `n:href`                       | [odkaz používaný v HTML elementech `<a>` |doc:application/creating-links#V šabloně presenteru]
| `{link}`                       | [vypíše odkaz |doc:application/creating-links#V šabloně presenteru]
| `{plink}`                      | [vypíše odkaz na presenter |doc:application/creating-links#V šabloně presenteru]
| `{control}`                    | [vykreslí komponentu |doc:application/components#Vykreslení]
| `{snippet}` … `{/snippet}`     | [výstřižek, který lze odeslat AJAXem |doc:application/ajax#tag-snippet]
| `{snippetArea}`                | obálka pro výstřižky
| `{cache}` … `{/cache}`         | [cachuje část šablony |doc:caching/@home#cachovani-v-latte]


.[table-latte-tags language-latte]
|## Dostupné pouze s Nette Forms
| `{form}` … `{/form}`           | [vykreslí značky formuláře |doc:forms/rendering#latte]
| `{label}` … `{/label}`         | [vykreslí popisku formulářového prvku |doc:forms/rendering#latte]
| `{input}`                      | [vykreslí formulářový prvek |doc:forms/rendering#latte]
| `{inputError}`                 | [vypíše chybovou hlášku formulářového prvku |doc:forms/rendering#latte]
| `n:name`                       | [oživí formulářový prvek |doc:forms/rendering#latte]
| `{formPrint}`                  | [navrhne Latte kód pro formulář |doc:forms/rendering#latte]
| `{formPrintClass}`             | [navrhne PHP kód třídy s daty formuláře |doc:forms/in-presenter#mapovani-na-tridy]
| `{formContext}` … `{/formContext}` | [částečné kreslení formuláře |doc:forms/rendering#latte]


Vypisování
==========


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

V Latte se používá značka `{=...}` pro výpis jakéhokoliv výrazu na výstup. Latte záleží na vašem pohodlí, takže pokud výraz začíná proměnnou nebo voláním funkce, není potřeba rovnítko psát. Což v praxi znamená, že ho není potřeba psát téměř nikdy:

```html
Jméno: {$name} {$surname}<br>
Věk: {date('Y') - $birth}<br>
```

Jako výraz můžete zapsat cokoliv, co znáte z PHP. Nemusíte se zkrátka učit nový jazyk. Tak třeba:


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

Prosím, nehledejte v předchozím příkladu žádný smysl, ale kdybyste tam nějaký našli, napište nám :-)


Escapování výstupu
------------------

Jaký je nejdůležitější úkol šablonovacího systému? Zamezit bezpečnostním dírám. A přesně tohle dělá Latte vždy, když něco vypisujete. Automaticky to escapuje:

```html
<p>{='one < two'}</p>   {* vypíše: '<p>one &lt; two</p>' *}
```

Abychom byli přesní, Latte používá kontextově sensitivně escapování, což je tak důležitá a unikátní věc, že jsme tomu věnovali [samostatnou kapitolu|safety-first#Kontextově sensitivní escapování].

A co když vypisujte obsah kódovaný v HTML z důvěryhodného zdroje? Pak lze snadno escapování vypnout:

```html
{$trustedHtmlString|noescape}
```

.[warning]
Špatné použití filtru `noescape` může vést ke vzniku zranitelnosti XSS! Nikdy jej nepoužívejte, pokud si nejste **zcela jisti** co děláte, a že vypisovaný řetězec pochází z důvěryhodného zdroje.


Vypsání v JavaScriptu
---------------------

Díky kontextově sensitivnímu escapování je nádherně snadné vypisovat proměnné uvnitř JavaScriptu a správné escapování zařídí Latte. Kolem proměnné se **nepíší uvozovky**, protože hodnota proměnné nemusí být řetězec.

```html
<script>
	alert({$name});
</script>
```

Pokud chcete proměnnou vložit do jiného řetězce, jednoduše je spojte:

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

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


Filtry
------

Vypsaný výraz může být upraven [filtrem|syntax#filtry]. Takto třeba řetězec převedeme na velká písmena a zkrátíme na maximálně 30 znaků:

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

Filtry můžete používat i na dílčí části výrazu tímto způsobem:

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


Podmínky
========


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

Podmínky se chovají stejně, jako jejich protějšky v PHP. Můžete v nich používat i stejné výrazy, jaké znáte z PHP, nemusíte se učit nový jazyk.

```html
{if $product->inStock > Stock::MINIMUM}
	Skladem
{elseif $product->isOnWay()}
	Na cestě
{else}
	Není dostupné
{/if}
```

Jako každou párovou značku, tak i dvojici `{if} ... {/if}` lze zapisovat i v podobě [n:attributu|syntax#n:atributy], například:

```latte
<p n:if="$count > 0">Skladem {$count} kusů</p>
```

Víte, že k n:atributům můžete připojit prefix `tag-`? Pak se bude podmínka vztahovat jen na vypsání HTML značek a obsah mezi nimi se vypíše vždycky:

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

{* vypíše 'Hello' když $clickable je nepravdivá *}
{* vypíše '<a href="...">Hello</a>' když $clickable je pravdivá *}
```

Boží.


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

Možná vás překvapí, že výraz v podmínce `{if}` lze uvést také v ukončovací značce. To se hodí v situacích, kdy při otevírání podmínky ještě jeho hodnotu neznáme. Říkejme tomu odložené rozhodnutí.

Například začneme vypisovat tabulku se záznamy z databáze a teprve po dokončení výpisu si uvědomíme, že v databázi žádný záznam nebyl. Tak dáme na to podmínku do koncové značky `{/if}` a pokud žádný záznam nebude, nic z toho se nevypíše:


```html
{if}
	<h1>Výpis řádků z databáze</h1>

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

Šikovné, že?

V odložené podmínce lze použít i `{else}`, ale nikoliv `{elseif}`.


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

Pomocí podmínky `{ifset $var}` zjistíme, zda proměnná (nebo více proměnných) existuje a má ne*null*ovou hodnotu. Vlastně jde o totéž, jako `if (isset($var))` v PHP. Jako každou párovou značku ji lze zapisovat i v podobě [n:attributu|syntax#n:atributy], tak si to ukažme jako příklad:

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

.[note]
Kromě kontrolování existence proměnných se `{ifset}` používá také k ověření [existence bloků |template-inheritance#Kontrola existence bloků].


`{ifchanged}` .{data-version:2.9}
---------------------------------

`{ifchanged}` zkontroluje, zda se hodnota proměnné změnila od poslední iterace ve smyčce (foreach, for nebo while).

Pokud ve značce uvedeme jednu či více proměnných, bude kontrolovat, zda se nějaká z nich změnila, a podle toho vypíše obsah. Například následující příklad vypíše první písmenko jména jako nadpis pokaždé, když se při výpisu jmen změní:

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

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

Pokud však neuvedeme žádný argument, bude se kontrolovat vykreslený obsah oproti jeho předchozímu stavu. To znamená, že v předchozím příkladě můžeme klidně argument ve značce vynechat. A samozřejmě také můžeme použít [n:attribut|syntax#n:atributy]:

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

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

Uvnitř `{ifchanged}` lze také uvést klauzuli `{else}`.


`{switch}` `{case}` `{default}`
-------------------------------
Porovnává hodnotu s více možnostmi. Jde o obdobu podmíněnému příklazu `switch`, který znáte z PHP. Nicméně Latte jej vylepšuje:

- používá striktní porovnání (`===`)
- nepotřebuje `break`

Je to tedy přesný ekvivalent struktury `match` se kterou přichází PHP 8.0.

```html
{switch $transport}
	{case train}
		Vlakem
	{case plane}
		Letecky
	{default}
		Jinak
{/switch}
```
.{data-version:2.9}
Klauzule `{case}` může obsahovat více hodnot oddělených čárkami:

```html
{switch $status}
{case $status::NEW}<b>nová položka</b>
{case $status::SOLD, $status::UNKNOWN}<i>není dostupná</i>
{/switch}
```


Cykly
=====

V Latte najdete všechny cykly, které znáte z PHP: foreach, for a while.


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

Cyklus zapíšeme úplně stejně jako v PHP:

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

Navíc má několik šikovných vychytávek, o kterých si nyní povíme.

Latte třeba kontroluje, zda vytvořené proměnné omylem nepřepisují globální proměnné téhož jména. Zachrání to situace, kdy počítáte s tím, že v `$lang` je aktuální jazyk stránky, a neuvědomíte si, že `foreach $langs as $lang` vám tu proměnnou přepsalo.

Cyklus foreach lze také velmi elegantně a úsporně zapsat pomocí [n:attributu|syntax#n:atributy]:

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

Víte, že k n:atributům můžete připojit prefix `inner-`? Pak se bude ve smyčce opakovat pouze vnitřek elementu:

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

Takže se vypíše něco jako:

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


`{else}` .{data-version:2.9}{toc: foreach-else}
-----------------------------------------------

Uvnitř cyklu `foreach` může uvést klauzuli `{else}`, jejíž obsah se zobrazí, pokud je cyklus prázdný:

```html
<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Litujeme, v tomto seznamu nejsou žádní uživatelé</em></li>
	{/foreach}
</ul>
```


`$iterator`
-----------

Uvnitř cyklu `foreach` vytvoří Latte proměnnou `$iterator`, pomocí které můžeme zjišťovat užitečné informace o probíhajícím cyklu:

- `$iterator->first` - prochází se cyklem poprvé?
- `$iterator->last` - jde o poslední průchod?
- `$iterator->counter` - kolikátý je to průchod počítáno od jedné?
- `$iterator->counter0` - kolikátý je to průchod počítáno od nuly? .{data-version:2.9}
- `$iterator->odd` - jde o lichý průchod?
- `$iterator->even` - jde o sudý průchod?
- `$iterator->parent` - iterátor obklopující ten aktuální .{data-version:2.9}
- `$iterator->nextValue` - následující položka v cyklu
- `$iterator->nextKey` - klíč následující položky v cyklu


```html
{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 je mazané a `$iterator->last` funguje nejen u polí, ale i když cyklus probíhá nad obecným iterátorem, kde není dopředu znám počet položek.


`{first}` `{last}` `{sep}`
--------------------------

Tyto značky lze používat uvnitř cyklu `{foreach}`. Obsah `{first}` se vykreslí, pokud jde o první průchod.
Obsah `{last}` se vykreslí … jestlipak to uhádnete? Ano, pokud jde o poslední průchod. Jde vlastně o zkratky pro `{if $iterator->first}` a `{if $iterator->last}`.

```html
{foreach $rows as $row}
	{first}<table>{/first}

	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>

	{last}</table>{/last}
{/foreach}
```

Obsah značky `{sep}` se vykreslí, pokud průchod není poslední, hodí se tedy pro vykreslování oddělovačů, například čárek mezi vypisovanými položkami:

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

To je docela praktické, že?


{iterateWhile} .{data-version:2.10}
-----------------------------------

Zjednodušuje seskupování lineárních dat během iterování v cyklu foreach tím, že iteraci provádí ve vnořené smyčce, dokud je splněná podmínka. [Přečtěte si návod|cookbook/iteratewhile].

Může také elegantně nahradit `{first}` a `{last}` v příkladu výše:

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

Cyklus zapisujeme úplně stejně jako v PHP:

```html
{for $i = 0; $i < 10; $i++}
	<span>Položka {$i}</span>
{/for}
```


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

Cyklus opět zapisujeme úplně stejně jako v PHP:

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

Je možná i varianta s podmínkou v koncové značce, která odpovídá v PHP cyklu do-while:

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


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

Pro řízení jakéhokoliv cyklu lze používat značky `{continueIf ?}` a `{breakIf ?}`, které přejdou na další prvek resp. ukončí cyklus při splnění podmínky:

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

.{data-version:2.9}
Značka `{skipIf}` je velmi podobná jako `{continueIf}`, ale nezvyšuje počítadlo `$iterator->counter`, takže pokud jej vypisujeme a zároveň přeskočíme některé položky, nebudou v číslování díry.

A také klauzule `{else}` se vykreslí, když přeskočíme všechny položky.

```html
<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Litujeme, v tomto seznamu nejsou žádní dospělí</em></li>
	{/foreach}
</ul>
```


Vložení šablony
===============


`{include}`
-----------

Značka `{include}` načte a vykreslí uvedenou šablonu. Pokud bychom se bavili v řeči našeho oblíbeného jazyka PHP, je to něco jako:

```php
<?php include('header.html'); ?>
```

.[note]
Kromě vkládání souborů se značka `{include}` používá také k [vykreslení bloků|template-inheritance#Vykreslení bloků].

Vložené šablony nemají přístup k proměnným aktivního kontextu, mají přístup jen ke globálním proměnným.

Další proměnné můžete předávat tímto způsobem:

```latte
{* od Latte 2.9 *}
{include 'template.latte', foo: 'bar', id: 123}

{* před Latte 2.9 *}
{include 'template.latte', foo => 'bar', id => 123}
```

Název šablony může být jakákoliv výraz v PHP:

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

Vložený obsah lze upravit pomocí [filtrů|syntax#filtry]. Následující příklad odebere všechno HTML a upraví velikost písmen:

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

Defaultně [dědičnost šablon|template-inheritance] v tomto případě nijak nefiguruje. I když v inkludované šabloně můžeme používat bloky, nedojde k nahrazení odpovídajících bloků v šabloně, do které se inkluduje. Přemýšlejte o inkludovaných šabloných jako samostatných odstíněných částech stránek nebo modulů. Toto chování se dá změnit pomocí modifikátoru `with blocks` (od Latte 2.9.1):

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

Vztah mezi názvem souboru uvedeným ve značce a souborem na disku je věcí [loaderu|develop#Loadery].


`{sandbox}` .{data-version:2.8}
-------------------------------

Při vkládání šablony vytvořené koncovým uživatelem byste měli zvážit sandbox režim (více informací v [dokumentaci sandboxu |sandbox]).

Sandboxovanou obdobou `{include}` je:

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


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

Pojmenované bloky jsou základní stavební jednotkou [dědičnosti a znovupoužitelnost šablon|template-inheritance]. Avšak bloky bez jména slouží
jako způsob jak aplikovat [filtry|syntax#filtry] na část šablony. Například takto lze aplikovat filtr [strip|filters#strip], který odstraní zbytečné mezery:

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


Řízení výjimek
==============


`{try}` .{data-version:2.9}
---------------------------

Díky této značce je extrémně snadné vytvářet robustní šablony.

Pokud při vykreslování bloku `{try}` dojde k výjimce, celý blok se zahodí a vykreslování bude pokračovat až po něm:

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

Obsah ve volitelné klauzuli `{else}` se vykreslí jen když nastane výjimka:

```html
{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Je nám líto, nepodařilo se načíst tweety.</p>
{/try}
```

Je také možné definovat vlastní [obslužný handler pro výjimky|develop#exception handler], například kvůli logování.


`{rollback}` .{data-version:2.9}
--------------------------------

Blok `{try}` lze zastavit a přeskočit také ručně pomocí `{rollback}`. Díky tomu nemusíte předem kontrolovat všechna vstupní data a až během vykreslování se můžete rozhodnout, že objekt nechcete vůbec vykreslit:

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


Proměnné
========


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

Nové proměnné vytvoříme v šabloně značkou `{var}`:

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

{* Vícenásobná deklarace *}
{var $name = 'John Smith', $age = 27}
```

Značka `{default}` funguje podobně s tím rozdílem, že vytváří proměnné jen tehdy, pokud neexistují:

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

Od Latte 2.7 můžete uvádět i [typy proměnných|type-system]. Zatím jsou informativní a Latte je nekontroluje.

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


`{parameters}` .{data-version:2.9}
----------------------------------

Tak jako funkce deklaruje své parametry, může i šablona na začátku deklarovat své proměnné:

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

Proměnné `$a` a `$b` bez uvedené výchozí hodnoty mají automaticky výchozí hodnotu `null`. Deklarované typy jsou zatím informativní a Latte je nekontroluje.

Jiné proměnné než deklarované se do šablony nepřenášejí. Tím se liší od značky `{default}`.


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

Zachytí výstup do proměnné:

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

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


Ostatní
=======


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

Značkou určíte, jaký typ obsahu šablona představuje. Možnosti jsou:

- `html` (výchozí typ)
- `xhtml`
- `xml`
- `javascript`
- `css`
- `calendar` (iCal)
- `text`

Její použití je důležité, protože nastaví [kontextově sensitivní escapování |safety-first#Kontextově sensitivní escapování] a jen tak může escapovat správně. Například `{contentType xml}` přepne do režimu XML, `{contentType text}` escapování zcela vypne.

Pokud je parametrem plnohodnotný MIME type, jako například `application/xml`, tak ještě navíc odešle HTTP hlavičku `Content-Type` do prohlížeče:

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


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

Označuje místo, kde dojde k pozastavení běhu programu a spuštění debuggeru, aby mohl programátor provést inspekci běhového prostředí a zjistit, zda program funguje podle očekávání. Podporuje [Xdebug |https://xdebug.org/]. Lze doplnit podmínku, která určuje, kdy má být program pozastaven.

```html
{debugbreak}                {* pozastaví program *}

{debugbreak $counter == 1}  {* pozastaví program při splnění podmínky *}
```


`{do}`
------

Vykoná kód a nic nevypisuje.

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

V Latte 2.7 a starších se používalo `{php}`.


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

Vypíše proměnnou nebo aktuální kontext.

```html
{dump $name} {* Vypíše proměnnou $name *}

{dump}       {* Vypíše všechny aktuálně definované proměnné *}
```

.[caution]
Vyžaduje knihovnu [Tracy|tracy:].


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

Odstraní zbytečné bílé místo z výstupu. Funguje podobně jako filtr [spaceless|filters#spaceless].

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

Vygeneruje

```html
<ul> <li>Hello</li> </ul>
```


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

Latte značky nemusejí být ohraničeny pouze do jednoduchých složených závorek. Můžeme si zvolit i jiný oddělovač a to dokonce za běhu. Slouží k tomu `{syntax …}`, kde jako parametr lze uvést:

- latte: `{...}`
- double: `{{...}}`
- off: zcela vypne zpracování Latte značek

S využitím n:atributů lze vypnout Latte třeba jen jednomu bloku JavaScriptu:

```html
<script n:syntax="off">
	var obj = {var: 123}; // tohle už není tag
</script>
```

Latte lze velmi pohodlně používat i uvnitř JavaScriptu, jen se stačí vynout konstrukcím jako v tomto příkladě, kdy následuje písmeno hned za `{`, viz [Latte uvnitř JavaScriptu nebo CSS|recipes#Latte uvnitř JavaScriptu nebo CSS].

Pokud Latte vypnete pomocí `{syntax off}` (tj. značkou, nikoliv n:atributem), bude důsledně ignorovat všechny značky až do `{/syntax}`


{trace} .{data-version:2.10}
----------------------------

Vyhodí výjimku `Latte\RuntimeException`, jejíž stack trace se nese v duchu šablon. Tedy místo volání funkcí a metod obsahuje volání bloků a vkládání šablon. Pokud používáte nástroj pro přehledné zobrazení vyhozených výjimek, jako je například [Tracy|tracy:], přehledně se vám zobrazí call stack včetně všech předávaných argumentů.


Pomocníci HTML kodéra
=====================


n:class
-------

Díky `n:class` velice snadno vygenerujete HTML atribut `class` přesně podle představ.

Příklad: potřebuji, aby aktivní prvek měl třídu `active`:

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

A dále, aby první prvek měl třídu `first`:

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

A všechny prvky mají mít třídu `main-item`:

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

Úžasně jednoduché, že?

/--comment
Anebo potřebujete označit aktivní menu třídou `current`?

```html
<a href="#" n:class="$presenter->isLinkCurrent('Presenter:*') ? current">
```

Pokud potřebujete přesnější detekci URL, tak metodě `isLinkCurrent()` lze předat i očekávaný parametr:

```html
<a href="#" n:class="$presenter->isLinkCurrent('Presenter:action', 'slug') ? current">
```
\--


n:attr
------

Atribut `n:attr` umí se stejnou elegancí jako má [n:class|#n:class] generovat libovolné HTML atributy.

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

V závislosti na vrácených hodnotách vypíše např.:

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

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

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


n:tag .{data-version:2.10}
--------------------------

Atribut `n:tag` umí dynamicky měnit název HTML elementu.

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

Pokud je `$heading === null`, vypíše se beze změny tag `<h1>`. Jinak se změní název elementu na hodnotu proměnné, takže pro `$heading === 'h3'` se vypíše:

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


n:ifcontent
-----------

Předchází tomu, aby se vypsal prázdný HTML element, tj. element neobsahující nic než mezery.

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

Vypíše v závislosti na hodnotě proměnné `$error`:

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

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


{{composer: latte/latte}}

Latte tagy (makra)

Přehled a popis všech tagů (neboli značek či maker) šablonovacího systému Latte, které jsou vám standardně k dispozici.

Vypisování
{$var}, {...} nebo {=...} vypíše escapovanou proměnnou nebo výraz
{$var|filter} vypíše s použitím filtrů
{l} nebo {r} vypíše znak { nebo }
Podmínky
{if}{elseif}{else}{/if} podmínka if
{ifset}{elseifset}{/ifset} podmínka ifset
{ifchanged}{/ifchanged} test jestli došlo ke změně
{switch} {case} {default} {/switch} podmínka switch
Cykly
{foreach}{/foreach} foreach
{for}{/for} for
{while}{/while} while
{continueIf $cond} pokračovat další iterací
{skipIf $cond} přeskočit iteraci
{breakIf $cond} přerušení cyklu
{first}{/first} jde o první průchod?
{last}{/last} jde o poslední průchod?
{sep}{/sep} bude ještě následovat průchod?
{iterateWhile}{/iterateWhile} strukturovaný foreach
$iterator speciální proměnná uvnitř foreach
Vložení dalších šablon
{include 'file.latte'} načte šablonu z dalšího souboru
{sandbox 'file.latte'} načte šablonu v sandbox režimu
Bloky, layouty, dědičnost šablon
{block} anonymní blok
{block blockname} definuje blok
{define blockname} definuje blok pro pozdější použití
{include blockname} vykreslení bloku
{include blockname from 'file.latte'} vykreslí blok ze souboru
{import 'file.latte'} načte bloky ze šablony
{layout 'file.latte'} / {extends} určuje soubor s layoutem
{embed}{/embed} načte šablonu či blok a umožní přepsat bloky
{ifset blockname}{/ifset} podmínka, zda existuje blok
Řízení výjimek
{try}{else}{/try} zachycení výjimek
{rollback} zahození bloku try
Proměnné
{var $foo = value} vytvoří proměnnou
{default $foo = value} vytvoří proměnnou, pokud neexistuje
{parameters} deklaruje proměnné, typy a výchozí hodnoty
{capture}{/capture} zachytí blok do proměnné
Typy
{varType} deklaruje typ proměnné
{varPrint} navrhne typy proměnných
{templateType} deklaruje typy proměnných podle třídy
{templatePrint} navrhne třídu s typy proměnných
Ostatní
{contentType} přepne escapování a pošle HTTP hlavičku
{debugbreak} umístí do kódu breakpoint
{do} vykoná kód, ale nic nevypíše
{dump} dumpuje proměnné do Tracy Bar
{spaceless}{/spaceless} odstraní nadbytečné mezery
{syntax} změna syntaxe za běhu
{trace} zobrazí stack trace
Pomocníci HTML kodéra
n:class dynamický zápis HTML atributu class
n:attr dynamický zápis jakýchkoliv HTML atributů
n:tag dynamický zápis jména HTML elementu
n:ifcontent Vynechá prázdný HTML tag
Dostupné pouze v Nette Frameworku
{_string} vypíše překlad
{translate}{/translate} přeloží obsah
n:href odkaz používaný v HTML elementech <a>
{link} vypíše odkaz
{plink} vypíše odkaz na presenter
{control} vykreslí komponentu
{snippet}{/snippet} výstřižek, který lze odeslat AJAXem
{snippetArea} obálka pro výstřižky
{cache}{/cache} cachuje část šablony
Dostupné pouze s Nette Forms
{form}{/form} vykreslí značky formuláře
{label}{/label} vykreslí popisku formulářového prvku
{input} vykreslí formulářový prvek
{inputError} vypíše chybovou hlášku formulářového prvku
n:name oživí formulářový prvek
{formPrint} navrhne Latte kód pro formulář
{formPrintClass} navrhne PHP kód třídy s daty formuláře
{formContext}{/formContext} částečné kreslení formuláře

Vypisování

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

V Latte se používá značka {=...} pro výpis jakéhokoliv výrazu na výstup. Latte záleží na vašem pohodlí, takže pokud výraz začíná proměnnou nebo voláním funkce, není potřeba rovnítko psát. Což v praxi znamená, že ho není potřeba psát téměř nikdy:

Jméno: {$name} {$surname}<br>
Věk: {date('Y') - $birth}<br>

Jako výraz můžete zapsat cokoliv, co znáte z PHP. Nemusíte se zkrátka učit nový jazyk. Tak třeba:

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

Prosím, nehledejte v předchozím příkladu žádný smysl, ale kdybyste tam nějaký našli, napište nám :-)

Escapování výstupu

Jaký je nejdůležitější úkol šablonovacího systému? Zamezit bezpečnostním dírám. A přesně tohle dělá Latte vždy, když něco vypisujete. Automaticky to escapuje:

<p>{='one < two'}</p>   {* vypíše: '<p>one &lt; two</p>' *}

Abychom byli přesní, Latte používá kontextově sensitivně escapování, což je tak důležitá a unikátní věc, že jsme tomu věnovali samostatnou kapitolu.

A co když vypisujte obsah kódovaný v HTML z důvěryhodného zdroje? Pak lze snadno escapování vypnout:

{$trustedHtmlString|noescape}

Špatné použití filtru noescape může vést ke vzniku zranitelnosti XSS! Nikdy jej nepoužívejte, pokud si nejste zcela jisti co děláte, a že vypisovaný řetězec pochází z důvěryhodného zdroje.

Vypsání v JavaScriptu

Díky kontextově sensitivnímu escapování je nádherně snadné vypisovat proměnné uvnitř JavaScriptu a správné escapování zařídí Latte. Kolem proměnné se nepíší uvozovky, protože hodnota proměnné nemusí být řetězec.

<script>
	alert({$name});
</script>

Pokud chcete proměnnou vložit do jiného řetězce, jednoduše je spojte:

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

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

Filtry

Vypsaný výraz může být upraven filtrem. Takto třeba řetězec převedeme na velká písmena a zkrátíme na maximálně 30 znaků:

{$string|upper|truncate:30}

Filtry můžete používat i na dílčí části výrazu tímto způsobem:

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

Podmínky

{if} {elseif} {else}

Podmínky se chovají stejně, jako jejich protějšky v PHP. Můžete v nich používat i stejné výrazy, jaké znáte z PHP, nemusíte se učit nový jazyk.

{if $product->inStock > Stock::MINIMUM}
	Skladem
{elseif $product->isOnWay()}
	Na cestě
{else}
	Není dostupné
{/if}

Jako každou párovou značku, tak i dvojici {if} ... {/if} lze zapisovat i v podobě n:attributu, například:

<p n:if="$count > 0">Skladem {$count} kusů</p>

Víte, že k n:atributům můžete připojit prefix tag-? Pak se bude podmínka vztahovat jen na vypsání HTML značek a obsah mezi nimi se vypíše vždycky:

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

{* vypíše 'Hello' když $clickable je nepravdivá *}
{* vypíše '<a href="...">Hello</a>' když $clickable je pravdivá *}

Boží.

{/if $cond}

Možná vás překvapí, že výraz v podmínce {if} lze uvést také v ukončovací značce. To se hodí v situacích, kdy při otevírání podmínky ještě jeho hodnotu neznáme. Říkejme tomu odložené rozhodnutí.

Například začneme vypisovat tabulku se záznamy z databáze a teprve po dokončení výpisu si uvědomíme, že v databázi žádný záznam nebyl. Tak dáme na to podmínku do koncové značky {/if} a pokud žádný záznam nebude, nic z toho se nevypíše:

{if}
	<h1>Výpis řádků z databáze</h1>

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

Šikovné, že?

V odložené podmínce lze použít i {else}, ale nikoliv {elseif}.

{ifset} {elseifset}

Pomocí podmínky {ifset $var} zjistíme, zda proměnná (nebo více proměnných) existuje a má nenullovou hodnotu. Vlastně jde o totéž, jako if (isset($var)) v PHP. Jako každou párovou značku ji lze zapisovat i v podobě n:attributu, tak si to ukažme jako příklad:

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

Kromě kontrolování existence proměnných se {ifset} používá také k ověření existence bloků.

{ifchanged}

{ifchanged} zkontroluje, zda se hodnota proměnné změnila od poslední iterace ve smyčce (foreach, for nebo while).

Pokud ve značce uvedeme jednu či více proměnných, bude kontrolovat, zda se nějaká z nich změnila, a podle toho vypíše obsah. Například následující příklad vypíše první písmenko jména jako nadpis pokaždé, když se při výpisu jmen změní:

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

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

Pokud však neuvedeme žádný argument, bude se kontrolovat vykreslený obsah oproti jeho předchozímu stavu. To znamená, že v předchozím příkladě můžeme klidně argument ve značce vynechat. A samozřejmě také můžeme použít n:attribut:

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

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

Uvnitř {ifchanged} lze také uvést klauzuli {else}.

{switch} {case} {default}

Porovnává hodnotu s více možnostmi. Jde o obdobu podmíněnému příklazu switch, který znáte z PHP. Nicméně Latte jej vylepšuje:

  • používá striktní porovnání (===)
  • nepotřebuje break

Je to tedy přesný ekvivalent struktury match se kterou přichází PHP 8.0.

{switch $transport}
	{case train}
		Vlakem
	{case plane}
		Letecky
	{default}
		Jinak
{/switch}

Klauzule {case} může obsahovat více hodnot oddělených čárkami:

{switch $status}
{case $status::NEW}<b>nová položka</b>
{case $status::SOLD, $status::UNKNOWN}<i>není dostupná</i>
{/switch}

Cykly

V Latte najdete všechny cykly, které znáte z PHP: foreach, for a while.

{foreach}

Cyklus zapíšeme úplně stejně jako v PHP:

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

Navíc má několik šikovných vychytávek, o kterých si nyní povíme.

Latte třeba kontroluje, zda vytvořené proměnné omylem nepřepisují globální proměnné téhož jména. Zachrání to situace, kdy počítáte s tím, že v $lang je aktuální jazyk stránky, a neuvědomíte si, že foreach $langs as $lang vám tu proměnnou přepsalo.

Cyklus foreach lze také velmi elegantně a úsporně zapsat pomocí n:attributu:

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

Víte, že k n:atributům můžete připojit prefix inner-? Pak se bude ve smyčce opakovat pouze vnitřek elementu:

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

Takže se vypíše něco jako:

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

{else}

Uvnitř cyklu foreach může uvést klauzuli {else}, jejíž obsah se zobrazí, pokud je cyklus prázdný:

<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Litujeme, v tomto seznamu nejsou žádní uživatelé</em></li>
	{/foreach}
</ul>

$iterator

Uvnitř cyklu foreach vytvoří Latte proměnnou $iterator, pomocí které můžeme zjišťovat užitečné informace o probíhajícím cyklu:

  • $iterator->first – prochází se cyklem poprvé?
  • $iterator->last – jde o poslední průchod?
  • $iterator->counter – kolikátý je to průchod počítáno od jedné?
  • $iterator->counter0 – kolikátý je to průchod počítáno od nuly?
  • $iterator->odd – jde o lichý průchod?
  • $iterator->even – jde o sudý průchod?
  • $iterator->parent – iterátor obklopující ten aktuální
  • $iterator->nextValue – následující položka v cyklu
  • $iterator->nextKey – klíč následující položky v cyklu
{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 je mazané a $iterator->last funguje nejen u polí, ale i když cyklus probíhá nad obecným iterátorem, kde není dopředu znám počet položek.

{first} {last} {sep}

Tyto značky lze používat uvnitř cyklu {foreach}. Obsah {first} se vykreslí, pokud jde o první průchod. Obsah {last} se vykreslí … jestlipak to uhádnete? Ano, pokud jde o poslední průchod. Jde vlastně o zkratky pro {if $iterator->first} a {if $iterator->last}.

{foreach $rows as $row}
	{first}<table>{/first}

	<tr id="row-{$iterator->counter}">
		<td>{$row->name}</td>
		<td>{$row->email}</td>
	</tr>

	{last}</table>{/last}
{/foreach}

Obsah značky {sep} se vykreslí, pokud průchod není poslední, hodí se tedy pro vykreslování oddělovačů, například čárek mezi vypisovanými položkami:

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

To je docela praktické, že?

{iterateWhile}

Zjednodušuje seskupování lineárních dat během iterování v cyklu foreach tím, že iteraci provádí ve vnořené smyčce, dokud je splněná podmínka. Přečtěte si návod.

Může také elegantně nahradit {first} a {last} v příkladu výše:

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

Cyklus zapisujeme úplně stejně jako v PHP:

{for $i = 0; $i < 10; $i++}
	<span>Položka {$i}</span>
{/for}

{while}

Cyklus opět zapisujeme úplně stejně jako v PHP:

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

Je možná i varianta s podmínkou v koncové značce, která odpovídá v PHP cyklu do-while:

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

{continueIf} {skipIf} {breakIf}

Pro řízení jakéhokoliv cyklu lze používat značky {continueIf ?} a {breakIf ?}, které přejdou na další prvek resp. ukončí cyklus při splnění podmínky:

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

Značka {skipIf} je velmi podobná jako {continueIf}, ale nezvyšuje počítadlo $iterator->counter, takže pokud jej vypisujeme a zároveň přeskočíme některé položky, nebudou v číslování díry.

A také klauzule {else} se vykreslí, když přeskočíme všechny položky.

<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Litujeme, v tomto seznamu nejsou žádní dospělí</em></li>
	{/foreach}
</ul>

Vložení šablony

{include}

Značka {include} načte a vykreslí uvedenou šablonu. Pokud bychom se bavili v řeči našeho oblíbeného jazyka PHP, je to něco jako:

<?php include('header.html'); ?>

Kromě vkládání souborů se značka {include} používá také k vykreslení bloků.

Vložené šablony nemají přístup k proměnným aktivního kontextu, mají přístup jen ke globálním proměnným.

Další proměnné můžete předávat tímto způsobem:

{* od Latte 2.9 *}
{include 'template.latte', foo: 'bar', id: 123}

{* před Latte 2.9 *}
{include 'template.latte', foo => 'bar', id => 123}

Název šablony může být jakákoliv výraz v PHP:

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

Vložený obsah lze upravit pomocí filtrů. Následující příklad odebere všechno HTML a upraví velikost písmen:

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

Defaultně dědičnost šablon v tomto případě nijak nefiguruje. I když v inkludované šabloně můžeme používat bloky, nedojde k nahrazení odpovídajících bloků v šabloně, do které se inkluduje. Přemýšlejte o inkludovaných šabloných jako samostatných odstíněných částech stránek nebo modulů. Toto chování se dá změnit pomocí modifikátoru with blocks (od Latte 2.9.1):

{include 'template.latte' with blocks}

Vztah mezi názvem souboru uvedeným ve značce a souborem na disku je věcí loaderu.

{sandbox}

Při vkládání šablony vytvořené koncovým uživatelem byste měli zvážit sandbox režim (více informací v dokumentaci sandboxu).

Sandboxovanou obdobou {include} je:

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

{block}

Pojmenované bloky jsou základní stavební jednotkou dědičnosti a znovupoužitelnost šablon. Avšak bloky bez jména slouží jako způsob jak aplikovat filtry na část šablony. Například takto lze aplikovat filtr strip, který odstraní zbytečné mezery:

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

Řízení výjimek

{try}

Díky této značce je extrémně snadné vytvářet robustní šablony.

Pokud při vykreslování bloku {try} dojde k výjimce, celý blok se zahodí a vykreslování bude pokračovat až po něm:

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

Obsah ve volitelné klauzuli {else} se vykreslí jen když nastane výjimka:

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Je nám líto, nepodařilo se načíst tweety.</p>
{/try}

Je také možné definovat vlastní obslužný handler pro výjimky, například kvůli logování.

{rollback}

Blok {try} lze zastavit a přeskočit také ručně pomocí {rollback}. Díky tomu nemusíte předem kontrolovat všechna vstupní data a až během vykreslování se můžete rozhodnout, že objekt nechcete vůbec vykreslit:

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

Proměnné

{var} {default}

Nové proměnné vytvoříme v šabloně značkou {var}:

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

{* Vícenásobná deklarace *}
{var $name = 'John Smith', $age = 27}

Značka {default} funguje podobně s tím rozdílem, že vytváří proměnné jen tehdy, pokud neexistují:

{default $lang = 'cs'}

Od Latte 2.7 můžete uvádět i typy proměnných. Zatím jsou informativní a Latte je nekontroluje.

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

{parameters}

Tak jako funkce deklaruje své parametry, může i šablona na začátku deklarovat své proměnné:

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

Proměnné $a a $b bez uvedené výchozí hodnoty mají automaticky výchozí hodnotu null. Deklarované typy jsou zatím informativní a Latte je nekontroluje.

Jiné proměnné než deklarované se do šablony nepřenášejí. Tím se liší od značky {default}.

{capture}

Zachytí výstup do proměnné:

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

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

Ostatní

{contentType}

Značkou určíte, jaký typ obsahu šablona představuje. Možnosti jsou:

  • html (výchozí typ)
  • xhtml
  • xml
  • javascript
  • css
  • calendar (iCal)
  • text

Její použití je důležité, protože nastaví kontextově sensitivní escapování a jen tak může escapovat správně. Například {contentType xml} přepne do režimu XML, {contentType text} escapování zcela vypne.

Pokud je parametrem plnohodnotný MIME type, jako například application/xml, tak ještě navíc odešle HTTP hlavičku Content-Type do prohlížeče:

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

{debugbreak}

Označuje místo, kde dojde k pozastavení běhu programu a spuštění debuggeru, aby mohl programátor provést inspekci běhového prostředí a zjistit, zda program funguje podle očekávání. Podporuje Xdebug. Lze doplnit podmínku, která určuje, kdy má být program pozastaven.

{debugbreak}                {* pozastaví program *}

{debugbreak $counter == 1}  {* pozastaví program při splnění podmínky *}

{do}

Vykoná kód a nic nevypisuje.

{do $num++}

V Latte 2.7 a starších se používalo {php}.

{dump}

Vypíše proměnnou nebo aktuální kontext.

{dump $name} {* Vypíše proměnnou $name *}

{dump}       {* Vypíše všechny aktuálně definované proměnné *}

Vyžaduje knihovnu Tracy.

{spaceless}

Odstraní zbytečné bílé místo z výstupu. Funguje podobně jako filtr spaceless.

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

Vygeneruje

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

{syntax}

Latte značky nemusejí být ohraničeny pouze do jednoduchých složených závorek. Můžeme si zvolit i jiný oddělovač a to dokonce za běhu. Slouží k tomu {syntax …}, kde jako parametr lze uvést:

  • latte: {...}
  • double: {{...}}
  • off: zcela vypne zpracování Latte značek

S využitím n:atributů lze vypnout Latte třeba jen jednomu bloku JavaScriptu:

<script n:syntax="off">
	var obj = {var: 123}; // tohle už není tag
</script>

Latte lze velmi pohodlně používat i uvnitř JavaScriptu, jen se stačí vynout konstrukcím jako v tomto příkladě, kdy následuje písmeno hned za {, viz Latte uvnitř JavaScriptu nebo CSS.

Pokud Latte vypnete pomocí {syntax off} (tj. značkou, nikoliv n:atributem), bude důsledně ignorovat všechny značky až do {/syntax}

{trace}

Vyhodí výjimku Latte\RuntimeException, jejíž stack trace se nese v duchu šablon. Tedy místo volání funkcí a metod obsahuje volání bloků a vkládání šablon. Pokud používáte nástroj pro přehledné zobrazení vyhozených výjimek, jako je například Tracy, přehledně se vám zobrazí call stack včetně všech předávaných argumentů.

Pomocníci HTML kodéra

n:class

Díky n:class velice snadno vygenerujete HTML atribut class přesně podle představ.

Příklad: potřebuji, aby aktivní prvek měl třídu active:

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

A dále, aby první prvek měl třídu first:

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

A všechny prvky mají mít třídu main-item:

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

Úžasně jednoduché, že?

n:attr

Atribut n:attr umí se stejnou elegancí jako má n:class generovat libovolné HTML atributy.

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

V závislosti na vrácených hodnotách vypíše např.:

<input type="checkbox">

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

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

n:tag

Atribut n:tag umí dynamicky měnit název HTML elementu.

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

Pokud je $heading === null, vypíše se beze změny tag <h1>. Jinak se změní název elementu na hodnotu proměnné, takže pro $heading === 'h3' se vypíše:

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

n:ifcontent

Předchází tomu, aby se vypsal prázdný HTML element, tj. element neobsahující nic než mezery.

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

Vypíše v závislosti na hodnotě proměnné $error:

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

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