Nette Documentation Preview

syntax
Syntaxe
*******

.[perex]
Syntaxe Latte vzešla z praktických požadavků webdesignerů. Hledali jsme tu nejpřívětivější syntaxi, se kterou elegantně zapíšete i konstrukce, které jinak představují skutečný oříšek. Zároveň se všechny výrazy 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, které řídí logiku šablony (například smyčky *foreach*) nebo vypisují výrazy. Pro obojí se používá jediný oddělovač `{ ... }`, takže nemusíte přemýšlet, jaký oddělovač v jaké situaci použít, jako je tomu u jiných systémů. Pokud za znakem `{` následuje bílý znak, uvozovka nebo další `{` či `}`, Latte jej nepovažuje za začátek značky, díky čemuž můžete v šablonách bez problémů používat i JavaScriptové konstrukce, JSON nebo pravidla v CSS.

Podívejte se na [přehled všech tagů|tags]. Kromě toho si můžete vytvářet i [vlastní tagy|custom tags]. Oddělovače `{ }` lze také změnit nebo zcela vypnout (pomocí `{syntax double}`, `{syntax off}` či atributu `n:syntax`); viz [změna syntaxe |tags#syntax].


Latte rozumí PHP
================

Uvnitř značek můžete používat PHP výrazy, které dobře znáte:

- proměnné
- řetězce (včetně HEREDOC a NOWDOC), pole, čísla, apod.
- [operátory |https://www.php.net/manual/en/language.operators.php]
- volání funkcí a metod (které lze omezit [sandboxem|sandbox])
- [match |https://www.php.net/manual/en/control-structures.match.php]
- [arrow funkce |https://www.php.net/manual/en/functions.arrow.php]
- [first class callable syntax |https://www.php.net/manual/en/functions.first_class_callable_syntax.php]
- víceřádkové komentáře `/* ... */`
- atd…

Latte navíc syntaxi PHP doplňuje o několik [příjemných rozšíření |#Syntaktický cukr].


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', '♥', 'Latte']}

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

vypíše:

```latte
<p>I</p>
<p>♥</p>
<p>Latte</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>Latte</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 |application:creating-links#V šabloně presenteru] nebo velešikovný pomocník kodéra [n:class |tags#n:class].

Kromě syntaxe s uvozovkami `<div n:if="$foo">` můžete použít alternativní syntaxi se složenými závorkami `<div n:if={$foo}>`. Hlavní výhodou je, že uvnitř `{...}` můžete volně používat jednoduché i dvojité uvozovky:

```latte
<div n:if={str_contains($val, "foo")}> ... </div>
```


Chytré HTML atributy .{data-version:3.1.0}
==========================================

Latte dělá práci se standardními HTML atributy neuvěřitelně snadnou. Za vás řeší boolean atributy jako `checked`, odstraňuje atributy obsahující `null` a umožňuje vám skládat hodnoty `class` a `style` pomocí polí. Dokonce automaticky serializuje data pro `data-` atributy do JSON.

```latte
{* null odstraní atribut *}
<div title={$title}>

{* boolean ovládá přítomnost boolean atributů *}
<input type="checkbox" checked={$isChecked}>

{* pole fungují v class *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* pole se v data- atributech převedou na JSON *}
<div data-config={[theme: dark, version: 2]}>
```

Více informací v samostatné kapitole [Chytré HTML atributy|html-attributes].


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í zleva doprava:

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

Argumenty se zapisují za jménem filtru po dvojtečce, další se oddělují čárkami; funguje i zápis se závorkami:

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

Filtry lze aplikovat i na výraz:

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

Na blok:

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

Nebo přímo na hodnotu (v kombinaci s tagem [`{=expr}` |tags#Vypisování]):

```latte
<h1>{='  Hello world  '|trim}</h1>
```

Pokud může být hodnota `null` a chcete v takovém případě zabránit použití filtru, použijte [nullsafe filtr |filters#Nullsafe filtry] `?|`:

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


Dynamické HTML značky .{data-version:3.0.9}
===========================================

Latte podporuje dynamické HTML značky, které jsou užitečné, když potřebujete flexibilitu v názvech značek:

```latte
<h{$level}>Heading</h{$level}>
```

Výše uvedený kód může například generovat `<h1>Heading</h1>` nebo `<h2>Heading</h2>` v závislosti na hodnotě proměnné `$level`. Dynamické HTML značky v Latte musí být vždy párové. Jejich alternativou je [n:tag |tags#n:tag].

Protože Latte je bezpečný šablonovací systém, kontroluje, zda je výsledný název značky platný a neobsahuje žádné nežádoucí nebo škodlivé hodnoty. Dále zajistí, že název koncové značky bude vždy stejný jako název otevírací značky.


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

Komentáře se zapisují tímto způsobem a do výstupu se nedostanou:

```latte
{* tohle je komentář v Latte *}
```

Uvnitř značek fungují PHP komentáře:

```latte
{include 'file.info', /* value: 123 */}
```


Řízení bílých znaků
===================

Latte zachází s bílými znaky inteligentně. Kód můžete volně odsazovat pro čitelnost a výstup zůstane čistý. Když se řídicí tag objeví na řádku sám, celý řádek (odsazení i konec řádku) se z výstupu odstraní (to neplatí pro tagy vypisující výstup, jako `{$var}`, `{=...}` nebo `{_...}`, které si odsazení i konec řádku ponechají):

```latte
<ul>
	{foreach $items as $item}
	<li>{$item}</li>
	{/foreach}
</ul>
```

Vypíše:

```latte
<ul>
	<li>foo</li>
	<li>bar</li>
</ul>
```

A co když tag není na řádku sám, ale je tam i další obsah? Bílé znaky před tagem pak patří *dovnitř* tagu:

```latte
<div>
	{if $foo}hello{/if}
</div>
```

Odsazení je tedy fakticky uvnitř `{if}`: pokud je `$foo` false, nevypíše se nic - ani odsazení, ani prázdný řádek. Pokud je `$foo` true, výstup přirozeně obsahuje odsazení. Prostě pište přehledně odsazené šablony a výstup bude vždy čistý.

Pro ještě čistší výstup lze aktivovat funkci [Dedent |develop#Dedent], která odstraní i odsazení vzniklé zanořením v párových značkách jako `{if}` nebo `{foreach}`.


Syntaktický cukr
================


Řetězce bez uvozovek
--------------------

U jednoduchých řetězců lze vynechat uvozovky:

```latte
jako v PHP:  {var $arr = ['hello', 'btn--default', '€']}

zkráceně:    {var $arr = [hello, btn--default, €]}
```

Jednoduché řetězce jsou ty, které jsou tvořeny čistě z písmen, číslic, podtržítek, pomlček a teček. Nesmí začínat číslicí a nesmí začínat nebo končit pomlčkou. Nesmí být složené jen z velkých písmen a podtržítek, protože pak se považují za konstantu (např. `PHP_VERSION`). A nesmí kolidovat s klíčovými slovy: `and`, `array`, `clone`, `default`, `false`, `in`, `instanceof`, `new`, `null`, `or`, `return`, `true`, `xor`.


Konstanty
---------

K rozlišení globálních konstant od jednoduchých řetězců použijte oddělovač globálního jmenného prostoru:

```latte
{if \PROJECT_ID === 1} ... {/if}
```

Tento zápis je zcela validní v samotném PHP, zpětné lomítko říká, že konstanta je v globálním jmenném prostoru.


Zkrácený ternární operátor
--------------------------

Je-li třetí hodnota ternárního operátoru prázdná, lze ji vynechat:

```latte
jako v PHP:  {$stock ? 'Skladem' : ''}

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


Moderní zápis klíčů v poli
--------------------------

Klíče v poli lze zapisovat podobně jako pojmenované parametry při volání funkcí:

```latte
jako v PHP:  {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

moderně:     {var $arr = [one: 'item 1', two: 'item 2']}
```


Filtry
------

Filtry lze použít pro jakékoliv výrazy, stačí celek uzavřít do závorek:

```latte
{var $content = ($text|truncate: 30|upper)}
```


Operátor `in`
-------------

Operátorem `in` lze nahradit funkci `in_array()`. Porovnání je vždy striktní:

```latte
{* obdoba in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}
```


Historické okénko
-----------------

Latte přišlo v průběhu své historie s celou řadou syntaktických cukříků, které se po pár letech objevily v samotném PHP. Například v Latte bylo možné psát pole jako `[1, 2, 3]` místo `array(1, 2, 3)` nebo používat nullsafe operátor `$obj?->foo` dávno předtím, než to bylo možné v samotném PHP. Latte také zavedlo operátor pro rozbalení pole `(expand) $arr`, který je ekvivalentem dnešního operátoru `...$arr` z PHP.


Omezení PHP v Latte
===================

V Latte lze zapisovat jen PHP výrazy. Tedy nelze používat statementy ukončené středníkem. Nelze deklarovat třídy nebo používat [řídicí struktury |https://www.php.net/manual/en/language.control-structures.php], např. `if`, `foreach`, `switch`, `return`, `try`, `throw` a další, místo kterých Latte nabízí své [značky|tags]. Také nelze používat [atributy |https://www.php.net/manual/en/language.attributes.php], [backticks |https://www.php.net/manual/en/language.operators.execution.php] či některé [magické konstanty |https://www.php.net/manual/en/language.constants.magic.php]. Nelze používat ani `unset`, `echo`, `include`, `require`, `exit`, `eval`, protože nejde o funkce, ale speciální jazykové konstrukce PHP, a nejsou to tedy výrazy. Komentáře jsou podporované jen víceřádkové `/* ... */`.

Tato omezení lze nicméně obejít tím, že si aktivujete rozšíření [RawPhpExtension |develop#RawPhpExtension], díky kterému lze pak používat ve značce `{php ...}` jakýkoliv PHP kód na zodpovědnost autora šablony.

Syntaxe

Syntaxe Latte vzešla z praktických požadavků webdesignerů. Hledali jsme tu nejpřívětivější syntaxi, se kterou elegantně zapíšete i konstrukce, které jinak představují skutečný oříšek. Zároveň se všechny výrazy 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, které řídí logiku šablony (například smyčky foreach) nebo vypisují výrazy. Pro obojí se používá jediný oddělovač { ... }, takže nemusíte přemýšlet, jaký oddělovač v jaké situaci použít, jako je tomu u jiných systémů. Pokud za znakem { následuje bílý znak, uvozovka nebo další { či }, Latte jej nepovažuje za začátek značky, díky čemuž můžete v šablonách bez problémů používat i JavaScriptové konstrukce, JSON nebo pravidla v CSS.

Podívejte se na přehled všech tagů. Kromě toho si můžete vytvářet i vlastní tagy. Oddělovače { } lze také změnit nebo zcela vypnout (pomocí {syntax double}, {syntax off} či atributu n:syntax); viz změna syntaxe.

Latte rozumí PHP

Uvnitř značek můžete používat PHP výrazy, které dobře znáte:

Latte navíc syntaxi PHP doplňuje o několik příjemných rozšíření.

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', '♥', 'Latte']}

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

vypíše:

<p>I</p>
<p>♥</p>
<p>Latte</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>Latte</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.

Kromě syntaxe s uvozovkami <div n:if="$foo"> můžete použít alternativní syntaxi se složenými závorkami <div n:if={$foo}>. Hlavní výhodou je, že uvnitř {...} můžete volně používat jednoduché i dvojité uvozovky:

<div n:if={str_contains($val, "foo")}> ... </div>

Chytré HTML atributy

Latte dělá práci se standardními HTML atributy neuvěřitelně snadnou. Za vás řeší boolean atributy jako checked, odstraňuje atributy obsahující null a umožňuje vám skládat hodnoty class a style pomocí polí. Dokonce automaticky serializuje data pro data- atributy do JSON.

{* null odstraní atribut *}
<div title={$title}>

{* boolean ovládá přítomnost boolean atributů *}
<input type="checkbox" checked={$isChecked}>

{* pole fungují v class *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* pole se v data- atributech převedou na JSON *}
<div data-config={[theme: dark, version: 2]}>

Více informací v samostatné kapitole Chytré HTML atributy.

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í zleva doprava:

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

Argumenty se zapisují za jménem filtru po dvojtečce, další se oddělují čárkami; funguje i zápis se závorkami:

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

Filtry lze aplikovat i na výraz:

{var $name = ($title|upper) . ($subtitle|lower)}

Na blok:

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

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

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

Pokud může být hodnota null a chcete v takovém případě zabránit použití filtru, použijte nullsafe filtr ?|:

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

Dynamické HTML značky

Latte podporuje dynamické HTML značky, které jsou užitečné, když potřebujete flexibilitu v názvech značek:

<h{$level}>Heading</h{$level}>

Výše uvedený kód může například generovat <h1>Heading</h1> nebo <h2>Heading</h2> v závislosti na hodnotě proměnné $level. Dynamické HTML značky v Latte musí být vždy párové. Jejich alternativou je n:tag.

Protože Latte je bezpečný šablonovací systém, kontroluje, zda je výsledný název značky platný a neobsahuje žádné nežádoucí nebo škodlivé hodnoty. Dále zajistí, že název koncové značky bude vždy stejný jako název otevírací značky.

Komentáře

Komentáře se zapisují tímto způsobem a do výstupu se nedostanou:

{* tohle je komentář v Latte *}

Uvnitř značek fungují PHP komentáře:

{include 'file.info', /* value: 123 */}

Řízení bílých znaků

Latte zachází s bílými znaky inteligentně. Kód můžete volně odsazovat pro čitelnost a výstup zůstane čistý. Když se řídicí tag objeví na řádku sám, celý řádek (odsazení i konec řádku) se z výstupu odstraní (to neplatí pro tagy vypisující výstup, jako {$var}, {=...} nebo {_...}, které si odsazení i konec řádku ponechají):

<ul>
	{foreach $items as $item}
	<li>{$item}</li>
	{/foreach}
</ul>

Vypíše:

<ul>
	<li>foo</li>
	<li>bar</li>
</ul>

A co když tag není na řádku sám, ale je tam i další obsah? Bílé znaky před tagem pak patří dovnitř tagu:

<div>
	{if $foo}hello{/if}
</div>

Odsazení je tedy fakticky uvnitř {if}: pokud je $foo false, nevypíše se nic – ani odsazení, ani prázdný řádek. Pokud je $foo true, výstup přirozeně obsahuje odsazení. Prostě pište přehledně odsazené šablony a výstup bude vždy čistý.

Pro ještě čistší výstup lze aktivovat funkci Dedent, která odstraní i odsazení vzniklé zanořením v párových značkách jako {if} nebo {foreach}.

Syntaktický cukr

Řetězce bez uvozovek

U jednoduchých řetězců lze vynechat uvozovky:

jako v PHP:  {var $arr = ['hello', 'btn--default', '€']}

zkráceně:    {var $arr = [hello, btn--default, €]}

Jednoduché řetězce jsou ty, které jsou tvořeny čistě z písmen, číslic, podtržítek, pomlček a teček. Nesmí začínat číslicí a nesmí začínat nebo končit pomlčkou. Nesmí být složené jen z velkých písmen a podtržítek, protože pak se považují za konstantu (např. PHP_VERSION). A nesmí kolidovat s klíčovými slovy: and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.

Konstanty

K rozlišení globálních konstant od jednoduchých řetězců použijte oddělovač globálního jmenného prostoru:

{if \PROJECT_ID === 1} ... {/if}

Tento zápis je zcela validní v samotném PHP, zpětné lomítko říká, že konstanta je v globálním jmenném prostoru.

Zkrácený ternární operátor

Je-li třetí hodnota ternárního operátoru prázdná, lze ji vynechat:

jako v PHP:  {$stock ? 'Skladem' : ''}

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

Moderní zápis klíčů v poli

Klíče v poli lze zapisovat podobně jako pojmenované parametry při volání funkcí:

jako v PHP:  {var $arr = ['one' => 'item 1', 'two' => 'item 2']}

moderně:     {var $arr = [one: 'item 1', two: 'item 2']}

Filtry

Filtry lze použít pro jakékoliv výrazy, stačí celek uzavřít do závorek:

{var $content = ($text|truncate: 30|upper)}

Operátor in

Operátorem in lze nahradit funkci in_array(). Porovnání je vždy striktní:

{* obdoba in_array($item, $items, true) *}
{if $item in $items}
	...
{/if}

Historické okénko

Latte přišlo v průběhu své historie s celou řadou syntaktických cukříků, které se po pár letech objevily v samotném PHP. Například v Latte bylo možné psát pole jako [1, 2, 3] místo array(1, 2, 3) nebo používat nullsafe operátor $obj?->foo dávno předtím, než to bylo možné v samotném PHP. Latte také zavedlo operátor pro rozbalení pole (expand) $arr, který je ekvivalentem dnešního operátoru ...$arr z PHP.

Omezení PHP v Latte

V Latte lze zapisovat jen PHP výrazy. Tedy nelze používat statementy ukončené středníkem. Nelze deklarovat třídy nebo používat řídicí struktury, např. if, foreach, switch, return, try, throw a další, místo kterých Latte nabízí své značky. Také nelze používat atributy, backticks či některé magické konstanty. Nelze používat ani unset, echo, include, require, exit, eval, protože nejde o funkce, ale speciální jazykové konstrukce PHP, a nejsou to tedy výrazy. Komentáře jsou podporované jen víceřádkové /* ... */.

Tato omezení lze nicméně obejít tím, že si aktivujete rozšíření RawPhpExtension, díky kterému lze pak používat ve značce {php ...} jakýkoliv PHP kód na zodpovědnost autora šablony.