Výchozí Latte makra
Přehled a popis všech maker šablonovacího systému Latte, které jsou vám standardně k dispozici.
Zajímají vás bližší informace o syntaxi Latte nebo o výchozích helperech? Makra najdete v namespace Nette\Latte\Macros.
Výpis proměnných a výrazů | |
---|---|
{$variable} |
vypíše escapovanou proměnnou |
{$variable|noescape} |
vypíše proměnnou bez escapování |
{expression} |
vypíše escapovaný výraz |
{expression|noescape} |
vypíše výraz bez escapování |
Podmínky | |
{if $cond} … {elseif $cond} … {else} … {/if} podmínka if |
|
{$cond ? $value1 : $value2} |
ternární operátor |
{$cond ? $value} |
zkrácený „ternární“ operátor |
{ifset $var} … {elseifset $var} … {/ifset} podmínka if
(isset()) |
|
Cykly | |
{foreach $arr as $item} … {/foreach} |
cyklus foreach |
{for expr; expr; expr} … {/for} |
cyklus for |
{while expr} … {/while} |
cyklus while |
{continueIf $cond} |
podmíněný skok na další iteraci |
{breakIf $cond} |
podmíněné ukončení cyklu |
{first [$mod]} … {/first} |
vypsat při prvním průchodu |
{last [$mod]} … {/last} |
vypsat při posledním průchodu |
{sep} … {/sep} |
separátor |
Proměnné | |
{var $foo = value} |
vytvoří proměnnou |
{default $foo = value} |
výchozí proměnnou pokud neexistuje |
{capture $var} … {/capture} |
zachytí blok do proměnné |
Systémové | |
{include 'file.latte'} |
načte šablonu z dalšího souboru |
{cache $key} … {/cache} |
cachuje část šablony |
{? expression} |
vyhodnotí výraz, ale nevypíše |
{* text komentáře *} |
komentář, bude odstraněn |
{syntax mode} … {/syntax} |
změna syntaxe maker za běhu |
{use Class} |
načte nová makra |
{l} nebo {r} |
vypíše znak { nebo } |
{contentType $type} |
přepne escapování a pošle HTTP hlavičku |
{status $code} |
nastaví stavový HTTP kód |
Pomocí HTML kodéra | |
n:class |
chytrý zápis HTML atributu class |
n:attr |
chytrý zápis jakéhokoliv HTML atributu |
n:tag-if |
Vynechá HTML tag, pokud je podmínka FALSE |
Překlady | |
{_}Text{/_} |
přeloží text |
{_expression} |
přeloží výraz a vypíše s escapováním |
Bloky, layouty, dědičnost šablon | |
{block block} |
definuje a hned vykreslí blok |
{define block} |
definuje blok pro pozdější použití |
{include block} |
vloží blok |
{includeblock 'file.latte'} |
načte bloky z externí šablony |
{layout 'file.latte'} |
určuje soubor s layoutem |
{extends 'file.latte'} |
alias pro {layout} |
{ifset #block} … {/ifset} |
podmínka, zda existuje blok |
Odkazy | |
n:href |
odkaz používaný v HTML elementech <a> |
{link Presenter:action} |
vygeneruje odkaz |
{plink Presenter:action} |
vygeneruje odkaz na presenter |
{ifCurrent $link} … {/ifCurrent} |
vykoná příkazy uvnitř bloku, pokud je odkaz shodný s aktuální adresou |
Ovládací prvky a formuláře | |
{control loginForm} |
vykreslí komponentu |
{form formName} … {/form} |
vykreslí značky formuláře |
{label fieldName} … {/label} |
vykreslí popisku formulářového prvku |
{input fieldName} |
vykreslí formulářový prvek |
{inputError fieldName} |
vypíše chybovou hlášku formulářového prvku |
n:name |
oživí formulářový prvek |
AJAX | |
{snippet name} … {/snippet} |
výstřižek, který lze odeslat AJAXem |
Ladění | |
{dump $variable} |
dumpuje proměnné do Debugger Bar |
{debugbreak $cond} |
umístí do kódu breakpoint |
Vypsání proměnné nebo výrazu {expression}
S escapováním: (eliminuje riziko Cross Site Scripting):
Jméno: {$name} {$surname}<br>
Věk: {date('Y') - $birth}<br>
Bez escapování uvedením modifikátoru |noescape
(dříve se používal vykříčník):
<div class="article">
{$content|noescape}
{nl2br($notes)|noescape}
</div>
Alternativně lze použit zápis s rovnítkem {=expression}
.
Díky technologií Context-Aware Escaping je mimo jiné možné nativně používat PHP proměnné uvnitř JavaScriptu:
$template->arr = array(1, 2, 3);
$template->name = 'Jim Beam';
<script type="text/javascript">
var pole = {$arr};
var name = {$name}; // pozor, zapisuje se bez uvozovek!
</script>
Podmínky {if $cond} … {/if}
, {$cond ? … : …}
Podmínky se chovají stejně, jako jejich protějšky v PHP:
{if $stock}
Skladem
{elseif $onWay}
Na cestě
{else}
Není dostupné
{/if}
Lze použít i makro {ifset}
, která kontroluje existenci proměnné a odpovídá zápisu
if (isset($var))
. Makro {ifset}
lze také použít pro ověření existence bloků.
Výraz v podmínce {if}
lze uvést také v ukončovací značce, což se hodí v situacích, kdy při
otevírání podmínky ještě jeho výsledek neznáme:
{if}
<h1>Výpis řádků z databáze</h1>
{foreach $database->table as $row} ... {/foreach}
{/if $row}
Blok {if}
s podmínkou v ukončovací značce nepodporuje makro {elseif}
. Makro
{else}
použít lze.
dostupnost: {$stock ? 'Skladem' : 'Není dostupné'}
zkráceně: {$stock ? 'Skladem'}
Cykly {foreach}
, {for}
, {while}
Cykly foreach
, for
a while
se chovají stejně, jako jejich protějšky v PHP.
{foreach $result as $row}
<span>{$row->title}</span>
{/foreach}
{while $row = $result->fetch()}
<span>{$row->title}</span>
{/while}
{for $i = 0; $i < 10; $i++}
<span>Položka {$i}</span>
{/for}
Uvnitř cyklu foreach
je inicializovaná proměnná $iterator
, díky které můžeme zjišťovat
užitečné informace o probíhajícím cyklu. Její
API disponuje čítačem průchodů a metodami zjišťujícími, zda je aktuální průchod sudý, lichý, první nebo
poslední:
isFirst()
– prochází se cyklem poprvé?isLast()
– jde o poslední průchod?getCounter()
– čítač průchodů cyklem počítaný od jedničkyisOdd()
– jde o lichý průchod?isEven()
– jde o sudý průchod?
Objekt $iterator
má vlastnosti
třídy Nette\Object, proto lze místo $iterator->isFirst()
psát $iterator->first
a podobně.
Příklad:
{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}
Konstrukci {if $iterator->first}<table>{/if}
lze nahradit za ekvivalentní
{first}<table>{/first}
, obdobně podmínku s last
lze zapsat jako
{last}</table>{/last}
. Makra {first}
a {last}
mají nepovinný parametr, který lze
využít jako modulo.
{foreach $rows as $row}
{first}<table>{/first}
{first 5}<tr>{/first} {* nový řádek po 5 záznamech *}
<td>{$row->value}</td>
{last 5}</tr>{/last}
{last}</table>{/last}
{/foreach}
A nakonec, ekvivalentem {if !$iterator->last} … {/if}
(tj. neposlední prvek) je makro
{sep} … {/sep}
. Obvykle jim označíme oddělovač, například čárku mezi vypisovanými položkami, čímž
zajistíme, že se nevypíše přebývající pravostranná čárka:
{foreach $items as $item} {$item} {sep}, {/sep} {/foreach}
Uvnitř cyklu lze používat makra {continueIf ?}
a {breakIf ?}
, které přejdou na další prvek
resp. ukončí cyklus při splnění podmínky:
{foreach $rows as $row}
{continueIf $row->parent == NULL}
...
{/foreach}
Definici cyklu lze sloučit s definicí obalujícího prvku HTML následujícím způsobem: (vypíše pro každou řádku tag div a jeho vnitřek)
<div n:foreach="$rows as $row">
...
</div>
Nebo pomocí vnitřního cyklu opakovat pouze vnitřek tagu: (ul zobrazí jednou, li pro každou řádku)
<ul n:inner-foreach="$rows as $row">
<li>
...
</li>
</ul>
Deklarace proměnných {var}
a {default}
Proměnné můžeme deklarovat přímo v šabloně makrem {var}
:
{var $name = 'John Smith'}
{var $age = 27}
{* Vícenásobná deklarace *}
{var $name = 'John Smith', $age = 27}
Makro {default}
funguje podobně s tím rozdílem, že nastavuje hodnoty jen neexistujícím proměnným:
{default $lang = 'cs'}
Zachytávání do proměnné {capture}
Makrem {capture}
lze zachytit výstup do proměnné:
{capture $var}
<ul>
<li>Hello World</li>
</ul>
{/capture}
<p>Captured: {$var}</p>
Pokud chcete zachytit výstup jen proto, abyste na něj mohli aplikovat nějaký helper, je jednodušší helper aplikovat přímo na blok:
{block|strip}
<ul>
<li>Hello World</li>
</ul>
{/block}
Vložení souboru {include}
Do šablony lze vložit jinou šablonu. Vložený soubor má k dispozici globální proměnné aktuální šablony a případné další parametry, které mu při volání předáme:
{include 'basket.latte'}
{include 'menu.latte', level => 3, data => $menu}
Makro {include}
se kromě vkládání souborů používá i pro vkládání bloků.
Vyhodnocení kódu {? expression}
Vyhodnotí kód a nic nevypisuje.
Hlavička {contentType}
Přepne Context-Aware Escaping do kontextu určeného argumentem a
všechny proměnné se escapují podle pravidel tohoto kontextu. Například {contentType xml}
přepne do režimu
XML, {contentType text}
escapování zcela vypne.
Pokud je parametrem plnohodnotný MIME type, tak se navíc odešle jako HTTP hlavička do prohlížeče:
{contentType application/xml}
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>RSS feed</title>
<item>
...
</item>
</channel>
</rss>
Hlavička {status}
Odešle HTTP stavový kód:
{status 500}
Pokud již nelze hlavičky odeslat, vyhodí výjimku. Té se dá předejít „volitelným odesláním“ uvedením otazníku
za kód {status 500?}
.
Změna syntaxe {syntax}
Makra nemusejí být uzavřena výhradně 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 makro {syntax …}
, kde jako parametr lze uvést:
- latte:
{...}
- double:
{{...}}
- asp:
<%...%>
- python:
{% ... %}
a{{ ... }}
- off: vypne zpracování maker
S využitím n:maker lze vypnout Latte třeba jen jednomu bloku JavaScriptu:
<script n:syntax="off">
var obj = {var: 123}; // tohle neni makro
</script>
Latte je pohodlně použitelné i v JavaScriptu, jen se stačí vyhnout konstrukci uvedené v předchozím příkladu. Buď
zápisem mezery za otevírací složenou závorku { var: 123}
nebo použitím uvozovek kolem identifikátoru
{'var': 123}
.
Pokud Latte vypnete pomocí {syntax off}
(tj. makrem syntax, nikoliv n:makrem), mějte na paměti, že ho již
zpátky nemůžete zapnout pomocí {/syntax}
. Žádné složené závorky se nezpracovávají, tudíž ani tag pro
ukončení výjimky v syntaxi.
n:class
Potřebujeme vyřešit běžný úkol: vypisujeme data z databáze jako elementy <li>
, neznáme dopředu
jejich počet a chceme, aby každý lichý řádek měl třídu alt
a poslední třídu last
. Pokud by
byl poslední řádek lichý, má mít obě třídy. A protože jsme puntičkáři, nechceme v kódu žádné prázdné
<li class=" ">
apod.
Díky makru n:class
tohle zapíšeme neskutečně snadno:
<ul>
{foreach $data as $item}
<li n:class="$iterator->odd ? alt, $iterator->last ? last">{$item}</li>
{/foreach}
</ul>
Anebo potřebujete označit aktivní menu třídou current
?
<a href="#" n:class="$presenter->isLinkCurrent('Presenter:*') ? current">
Úžasné, že?
n:attr
Makro n:attr
umí s elegancí podobnou makru n:class generovat libovolné HTML
atributy. Hodí se především v případech, kdy nevíme, které atributy budeme chtít vypsat a které ne.
<input type="checkbox" n:attr="value => $value, checked => $checked">
Vypíše v závislosti na hodnotách proměnných $value
nebo $checked
:
<input type="checkbox">
{* $value = 'Hello' *}
<input type="checkbox" value="Hello">
{* $checked = TRUE *}
<input type="checkbox" value="Hello" checked>
Překlady {_expression}
Makro usnadňuje automatizované překlady v šablonách. Pro jejich správnou funkčnost musí být nastaven překladač, viz lokalizace:
$template->setTranslator(new MyTranslator);
Poté bude jakýkoliv výraz zapsaný v tomto makru automaticky přeložen:
{_$variable}
Pro textové části šablony lze použít párovou variantu:
{_}Text, který bude přeložen{/_}
Bloky {block}
a {define}
Bloky slouží pro označení libovolné oblasti šablony. Třeba proto, abychom na ni aplikovali volání helperu (viz příklad) nebo proto, abychom ji pojmenovali a mohli poté na jiném místě znovu vložit.
{block sidebar}
<h3>Menu</h3>
...
{/block}
Bloky lze zanořovat do sebe. A pochopitelně je můžeme zapsat prostřednictvím n:makra:
{block sidebar}
<h3>Menu</h3>
...
<ul n:block="menulist">
...
</ul>
{/block}
Blok se na svém místě vykreslí. Pokud bychom chtěli pojmenovaný blok jen definovat bez vykreslení, použijeme místo
makra {block}
makro {define}
.
Název bloku může být také určen proměnnou: {block $var} … {/block}
.
Každý blok vidí proměnné ze svého okolí. Avšak vytvoření nebo změna hodnoty proměnné uvnitř bloku se projeví pouze v něm (a pochopitelně i ve vnořených blocích).
Existenci bloku můžeme ověřit makrem {ifset #sidebar}
.
Vkládání bloků {include block}
Vložení bloku zajistí makro {include}
.
{include sidebar}
Při vkládání bloku je možné mu předat parametry:
{include sidebar, id => 123, name => $value}
Můžeme vložit i blok, jehož název je uložen v proměnné (abychom se odlišili od vkládání souboru, uvedeme před názvem bloku mřížku):
{include #$block$name}
V bloku lze vložit i sebe sama, což lze použít např. pro vykreslení stromového menu.
{block menu}
<ul>
{foreach $menu as $item}
<li>{if is_array($item)}
{include menu, menu => $item}
{else}
{$item}
{/if}</li>
{/foreach}
</ul>
{/block}
Místo {include menu, ...}
lze psát také {include this, ...}
.
Pokud je potřeba doplnit již definovaný blok (např. přidání nových stylů), není kvůli tomu potřeba kopírovat celý
obsah tohoto bloku. Místo toho si nadefinujeme nový (stejně pojmenovaný) blok a uvnitř zavoláme
{include parent}
.
{block styles}
{include parent}
<link href="http://url.to.styles.css" rel="stylesheet">
{/block}
Rozšiřování a dědičnost šablon {layout}
Rozšiřování šablon (též dědičnost šablon) představuje mocný nástroj, který umožňuje snadnou a efektivní tvorbu i velmi komplikovaných layoutů bez nutnosti zbytečného opakování kódu.
Mějme dvě jednoduché stránky. První:
<html>
<head>
<title>První stránka | Můj web</title>
</head>
<body>
<div id="sidebar">
<ul>...</ul>
</div>
<div id="content">
<p>Lorem Gypsum...</p>
</div>
</body>
</html>
A druhou:
<html>
<head>
<title>Druhá stránka | Můj web</title>
</head>
<body>
<div id="sidebar">
<ul>...</ul>
</div>
<div id="content">
<p>Proin eu sem purus. Donec bibendum
vestibulum...</p>
</div>
</body>
</html>
Stránky se liší pouze elementem <title>
a <div#content>
. Vytvoříme si proto layout,
ve kterém budou všechny společné části, a vytvoříme tzv. placeholdery. Což kupodivu nebude nic jiného, než
klasický blok:
Soubor @layout.latte
:
<html>
<head>
<title>{block title}{/block} | Můj web</title>
</head>
<body>
<div id="sidebar">
<ul>...</ul>
</div>
<div id="content">{block content}{/block}</div>
</body>
</html>
V jednotlivých šablonách se nyní na layout odkážeme makrem {layout}
a můžeme je redukovat na ony
dva bloky:
{layout '@layout.latte'}
{block title}První stránka{/block}
{block content}<p>Lorem Gypsum...</p>{/block}
Obdobně bude vypadat i stránka druhá.
Nejsme dokonce ani omezeni dvoustupňovým layoutem. Vrstev může být totiž tolik, kolik se nám hodí.
Vykreslování komponent {control …}
Značka {control}
slouží k vykreslování komponent presenteru. Pro lepší pochopení je dobré vědět, jak
se tato značka přeloží do PHP.
{control cartControl} pro celý košík na stránce
{control cartControl:small} pro malý náhledový košík
se přeloží jako:
$control->getComponent('cartControl')->render();
$control->getComponent('cartControl')->renderSmall();
Metoda getComponent()
vrací komponentu cartControl
a nad touto komponentou volá metodu
render()
, resp. renderSmall()
pokud je jiný způsob renderování uveden ve značce za dvojtečkou.
Lze použít i volání s parametry, které se předají render metodám, například:
{control cartControl, $maxItems, $showSummary}
{control cartControl, maxItems => 5, showSummary => true}
{control cartControl, [maxItems => 5, showSummary => true]}
{control cartControl:small, $maxItems, $showSummary}
se přeloží jako:
$control->getComponent('cartControl')->render($maxItems, $showSummary);
$control->getComponent('cartControl')->render(array('maxItems' => 5, 'showSummary' => true));
$control->getComponent('cartControl')->render(array(array('maxItems' => 5, 'showSummary' => true)));
$control->getComponent('cartControl')->renderSmall($maxItems, $showSummary);
Pokud se kdekoliv v parametrech objeví =>
, všechny parametry budou zabaleny do pole a
předány jako první argument.
Vykreslení sub-komponety:
{control cartControl-someForm}
se přeloží jako:
$control->getComponent("cartControl-someForm")->render();
Formuláře {form}
, {input}
,
{inputError}
, {label}
Makra usnadňují vykreslení formulářů a jejich prvků:
{form myForm}
<table>
<tr n:foreach="$form->controls as $name => $field">
<th>{label $name /}<th>
<td>{input $name}</td>
<td n:ifcontent>{inputError $name}</td>
</tr>
</table>
{/form}
Makro {input}
vykreslí jakýkoliv prvek, včetně select boxů nebo textarea. Makro {label}
může
být volitelně párové, např. {label}Věk{/label}
, a ohraničený text bude u vícejazyčných formulářů také přeložen. Pokud formulářový prvek
obsahuje chybu, makro {inputError} ji vypíše.
Dumpování proměnných {dump}
{dump $name} {* Vypíše proměnnou $name *}
{dump} {* Vypíše všechny aktuálně definované proměnné *}
Break point {debugbreak}
Určuje místo, kde dojde k zastavení vykonávání programu. Používá se při ladění, aby mohl programátor provést inspekci běhového prostředí a zjistil, zda program funguje podle očekávání. Podporován je Xdebug a PhpEd. Lze doplnit podmínku, která určuje, kdy má být program zastaven.
{debugbreak} {* Zastaví program *}
{debugbreak $counter == 1} {* Zastaví program při splnění podmínky *}