Nette Documentation Preview

syntax
Syntaxe
*******

.[perex]
Syntax Latte vzešla z praktických požadavků webdesignerů. Hledali jsme tu nejpřívětivější syntax, se kterou elegantně zapíšete i konstrukce, které jinak představují skutečný oříšek.
Zároveň všechny výrazy se píší úplně stejně jako v PHP, takže se nemusíte učit nový jazyk. Prostě zúročíte co už dávno umíte.

Níže je uvedena minimální šablona, která ilustruje několik základních prvků: tagy, n:atributy, komentáře a filtry.

```latte
{* toto je komentář *}
<ul n:if="$items">                {* n:if je n:atribut *}
{foreach $items as $item}         {* tag představující cyklus foreach *}
	<li>{$item|capitalize}</li>   {* tag vypisující proměnnou s filtrem *}
{/foreach}                        {* konec cyklu *}
</ul>
```

Podívejme se blíže na tyto důležité prvky a na to, jak vám mohou pomoci vytvořit úžasnou šablonu.


Tagy
====

Šablona obsahuje tagy (neboli značky či makra), které řídí logiku šablony (například smyčky *foreach*) nebo vypisují výrazy. Používají jediný delimiter: `{ ... }`, takže nemusíte přemýšlet, jaké delimitery v jaké situaci použít, jako je tomu u jiných systémů.

Podívejte se na [přehled všech tagů|tags]. Krom toho si můžete vytvářet i [vlastní tagy|extending-latte#tagy].

Uvnitř značek přitom můžeme používat PHP takové, jaké ho známe. Dokonce včetně komentářů. Latte navíc syntaxi PHP rozšiřuje o několik příjemných vlastností:

1) můžeme vynechat uvozovky kolem řetězce z písmen, číslic a pomlček
2) stručnější zápis podmínek `$a ? 'b'` odpovídající `$a ? 'b' : null`
3) můžete používat [#filtry] `$a|upper`
4) můžete používat [undefined-safe operátor|#Volitelné řetězení s undefined-safe operátorem] `$var??->call()??->elem[1]??->item`

Příklad:

```latte
{$cond ? hello}  // vypíše 'hello' pokud je $cond truthy

{$order->item??->name} // znamená isset($order->item) ? $order->item->name : null
```


Vypsání výrazu
--------------

Tag `{$item|capitalize}`, který slouží k vypsání proměnné `$item`, obsahuje tzv. [filtr |#filtry], v tomto případě `capitalize`, který převede první písmenko každého slova na velké.

Velmi důležité je, že Latte vypisované proměnné **automaticky escapuje.** Vypsání proměnné totiž vyžaduje escapování, tj. převedení znaků majících v HTML speciální význam na jiné odpovídající sekvence. Opomenutí by vedlo ke vzniku závažné bezpečnostní díry Cross Site Scripting (XSS).
Protože v různých dokumentech a na různých místech stránky se používají jiné escapovací funkce, disponuje Latte zcela unikátní technologií [security|#Kontextově sensitivní escapování], která rozezná, ve které části dokumentu se značka nachází a **podle toho zvolí správné escapování.** Nemusíte se proto bát, že váš kodér na escapování zapomene a způsobí vám velké starosti kvůli bezpečnostní díře. Což je skvělé!

Pokud by proměnná `$item` obsahovala důvěryhodný HTML kód a chtěli bychom ji vypsat bez jakékoliv transformace, stačí přidat filter [noescape|filters#noescape]. Opomenutí přitom nezpůsobí bezpečností díru, dle principu „less code, more security“.


n:atributy
==========

Všechny párové značky, například `{if} … {/if}`, operující nad jedním HTML elementem, se dají přepsat do podoby n:atributů. Takto by bylo možné zapsat například i `{foreach}` v úvodní ukázce:

```latte
<ul n:if="$items">
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>
```

Funkcionalita se pak vztahuje na HTML element, do něhož je umístěný:

```latte
{var $items = ['I', '♥', 'Nette Framework']}

<p n:foreach="$items as $item">{$item}</p>
```

vypíše:

```latte
<p>I</p>
<p>♥</p>
<p>Nette Framework</p>
```

Pomocí prefixu `inner-` můžeme chování poupravit tak, aby se vztahovalo jen na vnitřní část elementu:

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

Vypíše se:

```latte
<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Nette Framework</p>
	<hr>
</div>
```

Nebo pomocí prefixu `tag-` aplikujeme funkcionalitu jen na samotné HTML značky:

```latte
<p><a href="{$url}" n:tag-if="$url">Title</a></p>
```

Což vypíše v závislosti na proměnné `$url`:

```latte
{* když je $url prázdné *}
<p>Title</p>

{* když $url obsahuje 'https://nette.org' *}
<p><a href="https://nette.org">Title</a></p>
```

Avšak n:atributy nejsou jen zkratkou pro párové značky. Existují i ryzí n:atributy, jako třeba [n:href |doc:application/creating-links#V šabloně presenteru] nebo velešikovný pomocník kodéra [n:class |tags#n:class].


Filtry
======

Podívejte se na přehled [standardních filtrů |filters].

Filtry se zapisují za svislítko (může být před ním mezera):

```latte
<h1>{$heading|upper}</h1>
```

Filtry lze zřetězit a poté se aplikují v pořadí od levého k pravému:

```latte
<h1>{$heading|lower|capitalize}</h1>
```

Parametry se zadávají za jménem filtru oddělené dvojtečkami nebo čárkami:

```latte
<h1>{$heading|truncate:20,''}</h1>
```

Filtry lze aplikovat i na výraz:

```latte
{var $name = ($title|upper) . ($subtitle|lower)}</h1>
```

Na blok:

```latte
<h1>{block |lower}{$heading}{/block}</h1>
```

Nebo přímo na hodnotu (v kombinaci s tagem [`{=expr}`| https://latte.nette.org/en/tags#Vypisování]):
```latte
<h1>{='  Hello world  '|trim}<h1>
```


Výrazy
======

/--comment
```latte
dostupnost: {$stock ? 'Skladem' : 'Není dostupné'}

zkráceně: {$stock ? 'Skladem'}
```
\--


.{data-version:2.6}
Volitelné řetězení s nullsafe operátorem
----------------------------------------

Volitelné řetězení umožňuje psát kód, kde Latte okamžitě zastaví vyhodnocování výrazů, pokud narazí na null. A to díky novému operátoru `?->` umožňujícímu volitelný přístup k proměnným nebo prvkům pole. Stejnou věc přináší PHP 8, nicméně v Latte ho můžete používat i v PHP 7.

Když píšeme kód jako:

```latte
{$order?->id}
```

říkáme tím, že když `$order` není null, bude vypsán `$order->id`, ale když je `$order` null, zastaví se vyhodnocování a prostě se vrátí null.

Uvidíte, že pomocí `?->` nahradíte spoustu kódu, který by jinak opakovaně kontroloval null:

```latte
{$user?->address?->street}
// znamená cca ($user !== null) && ($user->address !== null) ? $user->address->street : null

{$items[2]?->count}
// zamená cca ($items[2] !== null) ? $items[2]->count : null

{$user->getIdentity()?->name}
// zamená cca $user->getIdentity() !== null ? $user->getIdentity()->name : null
```

Význam je "cca", protože ve skutečnosti se výraz vyhodnocuje důmyslněji a žádný krok se neopakuje. Například `$user->getIdentity()` se zavolá jen jednou, tedy nemůže nastat problém způsobený tím, že by v podmínce vrátilo objekt a následně pak null.

Výrazy s volitelným řetězením lze používat kdekoliv, například v podmínkách:

```latte
{if $blogPost?->count('*')}
	// znamená if (isset($blogPost) && $blogPost->count('*'))
	...
{/if}
```


.{data-version:2.9}
Volitelné řetězení s undefined-safe operátorem
----------------------------------------------

Undefined-safe operator `??->` je obdoba nullsafe operatoru `?->`, avšak nevyvolá chybu, pokud proměnná, property nebo index v poli vůbec neexistuje.

```latte
{$order??->id}
```

říkáme tím, že když existuje `$order` a není null, bude vypsán `$order->id`, ale když je `$order` null nebo neexistuje, zastaví se vyhodnocování a prostě se vrátí null.

```latte
{$user??->address??->street}
// znamená cca isset($user) && isset($user->address) ? $user->address->street : null
```


Operátor rozbalení pole `(expand)` .{toc: (expand)}
---------------------------------------------------

Operátor `(expand)` umožňuje použití pole v místě, kde se očekává více argumentů. Jde o obdobu operátoru [`...` z PHP |https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list.new], na rozdíl od něj však zachovává i klíče.

Lze jej použít například pro předání argumentů do bloků nebo vkládaných šablon, pokud je máme v poli.

```latte
{include 'foobar.latte' (expand) $args}     {* argumenty pro include *}
```

/--comment
| `{"a": 1}`                     | JSON
| `$cond ? $value`               | [zkrácený "ternární" operátor |#podminky]
| `$obj?->prop                   | různé formy [volitelného řetězení |#volitelné řetězení]
| `$obj??->prop                  | různé formy [volitelného řetězení |#volitelné řetězení]
| `func($obj)`                   | custom functions
| `(expand)`                     | [rozbalení polí |#(expand)]
\--


Komentáře
=========

Komentáře se zapisují `{* tímto způsobem *}` a do výstupu se nedostanou.

Syntaxe

Syntax Latte vzešla z praktických požadavků webdesignerů. Hledali jsme tu nejpřívětivější syntax, se kterou elegantně zapíšete i konstrukce, které jinak představují skutečný oříšek. Zároveň všechny výrazy se píší úplně stejně jako v PHP, takže se nemusíte učit nový jazyk. Prostě zúročíte co už dávno umíte.

Níže je uvedena minimální šablona, která ilustruje několik základních prvků: tagy, n:atributy, komentáře a filtry.

{* toto je komentář *}
<ul n:if="$items">                {* n:if je n:atribut *}
{foreach $items as $item}         {* tag představující cyklus foreach *}
	<li>{$item|capitalize}</li>   {* tag vypisující proměnnou s filtrem *}
{/foreach}                        {* konec cyklu *}
</ul>

Podívejme se blíže na tyto důležité prvky a na to, jak vám mohou pomoci vytvořit úžasnou šablonu.

Tagy

Šablona obsahuje tagy (neboli značky či makra), které řídí logiku šablony (například smyčky foreach) nebo vypisují výrazy. Používají jediný delimiter: { ... }, takže nemusíte přemýšlet, jaké delimitery v jaké situaci použít, jako je tomu u jiných systémů.

Podívejte se na přehled všech tagů. Krom toho si můžete vytvářet i vlastní tagy.

Uvnitř značek přitom můžeme používat PHP takové, jaké ho známe. Dokonce včetně komentářů. Latte navíc syntaxi PHP rozšiřuje o několik příjemných vlastností:

  1. můžeme vynechat uvozovky kolem řetězce z písmen, číslic a pomlček
  2. stručnější zápis podmínek $a ? 'b' odpovídající $a ? 'b' : null
  3. můžete používat filtry $a|upper
  4. můžete používat undefined-safe operátor $var??->call()??->elem[1]??->item

Příklad:

{$cond ? hello}  // vypíše 'hello' pokud je $cond truthy

{$order->item??->name} // znamená isset($order->item) ? $order->item->name : null

Vypsání výrazu

Tag {$item|capitalize}, který slouží k vypsání proměnné $item, obsahuje tzv. filtr, v tomto případě capitalize, který převede první písmenko každého slova na velké.

Velmi důležité je, že Latte vypisované proměnné automaticky escapuje. Vypsání proměnné totiž vyžaduje escapování, tj. převedení znaků majících v HTML speciální význam na jiné odpovídající sekvence. Opomenutí by vedlo ke vzniku závažné bezpečnostní díry Cross Site Scripting (XSS). Protože v různých dokumentech a na různých místech stránky se používají jiné escapovací funkce, disponuje Latte zcela unikátní technologií security, která rozezná, ve které části dokumentu se značka nachází a podle toho zvolí správné escapování. Nemusíte se proto bát, že váš kodér na escapování zapomene a způsobí vám velké starosti kvůli bezpečnostní díře. Což je skvělé!

Pokud by proměnná $item obsahovala důvěryhodný HTML kód a chtěli bychom ji vypsat bez jakékoliv transformace, stačí přidat filter noescape. Opomenutí přitom nezpůsobí bezpečností díru, dle principu „less code, more security“.

n:atributy

Všechny párové značky, například {if} … {/if}, operující nad jedním HTML elementem, se dají přepsat do podoby n:atributů. Takto by bylo možné zapsat například i {foreach} v úvodní ukázce:

<ul n:if="$items">
	<li n:foreach="$items as $item">{$item|capitalize}</li>
</ul>

Funkcionalita se pak vztahuje na HTML element, do něhož je umístěný:

{var $items = ['I', '♥', 'Nette Framework']}

<p n:foreach="$items as $item">{$item}</p>

vypíše:

<p>I</p>
<p>♥</p>
<p>Nette Framework</p>

Pomocí prefixu inner- můžeme chování poupravit tak, aby se vztahovalo jen na vnitřní část elementu:

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

Vypíše se:

<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Nette Framework</p>
	<hr>
</div>

Nebo pomocí prefixu tag- aplikujeme funkcionalitu jen na samotné HTML značky:

<p><a href="{$url}" n:tag-if="$url">Title</a></p>

Což vypíše v závislosti na proměnné $url:

{* když je $url prázdné *}
<p>Title</p>

{* když $url obsahuje 'https://nette.org' *}
<p><a href="https://nette.org">Title</a></p>

Avšak n:atributy nejsou jen zkratkou pro párové značky. Existují i ryzí n:atributy, jako třeba n:href nebo velešikovný pomocník kodéra n:class.

Filtry

Podívejte se na přehled standardních filtrů.

Filtry se zapisují za svislítko (může být před ním mezera):

<h1>{$heading|upper}</h1>

Filtry lze zřetězit a poté se aplikují v pořadí od levého k pravému:

<h1>{$heading|lower|capitalize}</h1>

Parametry se zadávají za jménem filtru oddělené dvojtečkami nebo čárkami:

<h1>{$heading|truncate:20,''}</h1>

Filtry lze aplikovat i na výraz:

{var $name = ($title|upper) . ($subtitle|lower)}</h1>

Na blok:

<h1>{block |lower}{$heading}{/block}</h1>

Nebo přímo na hodnotu (v kombinaci s tagem {=expr}):

<h1>{='  Hello world  '|trim}<h1>

Výrazy

Volitelné řetězení s nullsafe operátorem

Volitelné řetězení umožňuje psát kód, kde Latte okamžitě zastaví vyhodnocování výrazů, pokud narazí na null. A to díky novému operátoru ?-> umožňujícímu volitelný přístup k proměnným nebo prvkům pole. Stejnou věc přináší PHP 8, nicméně v Latte ho můžete používat i v PHP 7.

Když píšeme kód jako:

{$order?->id}

říkáme tím, že když $order není null, bude vypsán $order->id, ale když je $order null, zastaví se vyhodnocování a prostě se vrátí null.

Uvidíte, že pomocí ?-> nahradíte spoustu kódu, který by jinak opakovaně kontroloval null:

{$user?->address?->street}
// znamená cca ($user !== null) && ($user->address !== null) ? $user->address->street : null

{$items[2]?->count}
// zamená cca ($items[2] !== null) ? $items[2]->count : null

{$user->getIdentity()?->name}
// zamená cca $user->getIdentity() !== null ? $user->getIdentity()->name : null

Význam je „cca“, protože ve skutečnosti se výraz vyhodnocuje důmyslněji a žádný krok se neopakuje. Například $user->getIdentity() se zavolá jen jednou, tedy nemůže nastat problém způsobený tím, že by v podmínce vrátilo objekt a následně pak null.

Výrazy s volitelným řetězením lze používat kdekoliv, například v podmínkách:

{if $blogPost?->count('*')}
	// znamená if (isset($blogPost) && $blogPost->count('*'))
	...
{/if}

Volitelné řetězení s undefined-safe operátorem

Undefined-safe operator ??-> je obdoba nullsafe operatoru ?->, avšak nevyvolá chybu, pokud proměnná, property nebo index v poli vůbec neexistuje.

{$order??->id}

říkáme tím, že když existuje $order a není null, bude vypsán $order->id, ale když je $order null nebo neexistuje, zastaví se vyhodnocování a prostě se vrátí null.

{$user??->address??->street}
// znamená cca isset($user) && isset($user->address) ? $user->address->street : null

Operátor rozbalení pole (expand)

Operátor (expand) umožňuje použití pole v místě, kde se očekává více argumentů. Jde o obdobu operátoru ... z PHP, na rozdíl od něj však zachovává i klíče.

Lze jej použít například pro předání argumentů do bloků nebo vkládaných šablon, pokud je máme v poli.

{include 'foobar.latte' (expand) $args}     {* argumenty pro include *}

Komentáře

Komentáře se zapisují {* tímto způsobem *} a do výstupu se nedostanou.