Składnia

Składnia Latte wyrosła z praktycznych potrzeb webdesignerów. Szukaliśmy składni maksymalnie przyjaznej, w której da się elegancko zapisać konstrukcje będące gdzie indziej prawdziwym wyzwaniem. Jednocześnie wszystkie wyrażenia zapisuje się dokładnie tak samo jak w PHP, więc nie musisz uczyć się nowego języka. Po prostu korzystasz z tego, co już umiesz.

Poniżej minimalny szablon ilustrujący kilka podstawowych elementów: tagi, n:atrybuty, komentarze i filtry.

{* to jest komentarz *}
<ul n:if=$items>                  {* n:if to n:atrybut *}
{foreach $items as $item}         {* tag reprezentujący pętlę foreach *}
	<li>{$item|capitalize}</li>   {* tag wypisujący zmienną z filtrem *}
{/foreach}                        {* koniec pętli *}
</ul>

Przyjrzyjmy się bliżej tym ważnym elementom i temu, jak pomogą Ci stworzyć niesamowity szablon.

Tagi

Szablon zawiera tagi sterujące logiką szablonu (na przykład pętle foreach) albo wypisujące wyrażenia. Dla obu używa się jednego ogranicznika { ... }, więc w odróżnieniu od innych systemów nie musisz zastanawiać się, którego ogranicznika użyć w której sytuacji. Jeśli bezpośrednio po znaku { następuje biały znak, cudzysłów albo kolejny { czy }, Latte nie uzna go za początek tagu, dzięki czemu bez problemu użyjesz w szablonach konstrukcji JavaScriptu, JSON-a czy reguł CSS.

Zobacz przegląd wszystkich tagów. Możesz też tworzyć własne tagi. Da się również zmienić ograniczniki { } albo całkiem je wyłączyć (przez {syntax double}, {syntax off} albo atrybut n:syntax), zobacz zmiana składni.

Latte rozumie PHP

Wewnątrz tagów możesz używać znanych Ci wyrażeń PHP:

Ponadto Latte wzbogaca składnię PHP o kilka przyjemnych rozszerzeń.

n:atrybuty

Każdy parzysty tag, na przykład {if} … {/if}, działający na jednym elemencie HTML, można zapisać w postaci n:atrybutu. Na przykład {foreach} ze wstępnego przykładu dałoby się zapisać także tak:

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

Funkcjonalność stosuje się wtedy do elementu HTML, w którym n:atrybut umieszczono:

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

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

wypisze:

<p>I</p>
<p>♥</p>
<p>Latte</p>

Za pomocą prefiksu inner- możemy zmienić zachowanie tak, aby dotyczyło tylko wnętrza elementu:

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

Wypisze:

<div>
	<p>I</p>
	<hr>
	<p>♥</p>
	<hr>
	<p>Latte</p>
	<hr>
</div>

Albo za pomocą prefiksu tag- zastosujemy funkcjonalność wyłącznie do samych tagów HTML:

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

Co, w zależności od zmiennej $url, wypisze:

{* gdy $url jest puste *}
<p>Tytuł</p>

{* gdy $url zawiera 'https://nette.org' *}
<p><a href="https://nette.org">Tytuł</a></p>

n:atrybuty nie są jednak tylko skrótem dla tagów parzystych, istnieją też czyste n:atrybuty, na przykład najlepszy przyjaciel kodera n:class albo bardzo poręczny n:href.

Oprócz zapisu z cudzysłowami <div n:if="$foo"> możesz użyć alternatywnego zapisu z klamrami <div n:if={$foo}>. Główną zaletą jest to, że wewnątrz {...} możesz swobodnie używać zarówno pojedynczych, jak i podwójnych cudzysłowów:

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

Smart atrybuty HTML

Latte niezwykle ułatwia pracę ze standardowymi atrybutami HTML. Samo zajmuje się atrybutami logicznymi, takimi jak checked, usuwa atrybuty zawierające null i pozwala składać wartości class i style z tablic. Dane dla atrybutów data- nawet automatycznie serializuje do JSON-a.

{* null usuwa atrybut *}
<div title={$title}>

{* wartość logiczna steruje obecnością atrybutów logicznych *}
<input type="checkbox" checked={$isChecked}>

{* w class działają tablice *}
<div class={['btn', 'btn-primary', active => $isActive]}>

{* w atrybutach data- tablice są kodowane do JSON *}
<div data-config={[theme: dark, version: 2]}>

Więcej przeczytasz w osobnym rozdziale Smart atrybuty HTML.

Filtry

Zobacz przegląd standardowych filtrów.

Filtry zapisuje się po znaku potoku (poprzedzająca spacja jest dozwolona):

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

Filtry można łączyć w łańcuch, a stosowane są kolejno od lewej do prawej:

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

Argumenty podaje się po nazwie filtra po dwukropku, a kolejne oddziela przecinkami; działa też wywołanie w nawiasach:

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

Filtry można stosować również do wyrażenia:

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

Do bloku:

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

Albo bezpośrednio do wartości (w połączeniu z tagiem {=expr}):

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

Jeśli wartość może być null, a chcesz w takim przypadku uniknąć zastosowania filtra, użyj filtra nullsafe ?|:

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

Dynamiczne tagi HTML

Latte obsługuje dynamiczne tagi HTML, przydatne wtedy, gdy potrzebujesz elastyczności w nazwach tagów:

<h{$level}>Nagłówek</h{$level}>

Powyższy kod może na przykład wygenerować <h1>Nagłówek</h1> albo <h2>Nagłówek</h2> w zależności od wartości zmiennej $level. Dynamiczne tagi HTML w Latte muszą być zawsze parzyste. Ich alternatywą jest n:tag.

Ponieważ Latte jest bezpiecznym systemem szablonów, sprawdza, czy wynikowa nazwa tagu jest poprawna i nie zawiera niepożądanych ani złośliwych wartości. Dba też o to, aby nazwa tagu zamykającego zawsze odpowiadała nazwie tagu otwierającego.

Komentarze

Komentarze zapisuje się w ten sposób i nie trafiają one do wyniku:

{* to jest komentarz w Latte *}

Wewnątrz tagów działają komentarze PHP:

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

Sterowanie białymi znakami

Latte inteligentnie obchodzi się z białymi znakami. Możesz swobodnie wcinać kod dla czytelności, a wynik pozostanie czysty. Gdy tag sterujący stoi samotnie w wierszu, cały wiersz (wcięcie i znak nowego wiersza) znika z wyniku (nie dotyczy to tagów wypisujących, takich jak {$var}, {=...} czy {_...}, które zachowują swoje wcięcie i końcowy znak nowego wiersza):

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

Wypisze:

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

A co, jeśli tag nie stoi w wierszu sam, lecz obok innej treści? Białe znaki przed tagiem należą wtedy do wnętrza tagu:

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

Wcięcie jest w praktyce wewnątrz {if}: gdy $foo jest fałszywe, nie wypisze się nic – ani wcięcie, ani pusty wiersz. Gdy $foo jest prawdziwe, wynik naturalnie zawiera wcięcie. Piszesz po prostu dobrze ustrukturyzowane szablony, a wynik jest zawsze czysty.

Aby wynik był jeszcze czystszy, możesz włączyć funkcję Dedent, która usuwa również wcięcia powstałe z zagnieżdżenia w tagach parzystych, takich jak {if} czy {foreach}.

Lukier składniowy

Łańcuchy bez cudzysłowów

Przy prostych łańcuchach można pominąć cudzysłowy:

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

skrótowo:  {var $arr = [hello, btn--default, €]}

Proste łańcuchy to takie, które składają się wyłącznie z liter, cyfr, podkreśleń, myślników i kropek. Nie mogą zaczynać się od cyfry ani zaczynać się lub kończyć myślnikiem. Nie mogą składać się wyłącznie z wielkich liter i podkreśleń, bo wtedy uznawane są za stałe (np. PHP_VERSION). I nie mogą kolidować ze słowami kluczowymi: and, array, clone, default, false, in, instanceof, new, null, or, return, true, xor.

Stałe

Aby odróżnić stałe globalne od prostych łańcuchów, użyj separatora globalnej przestrzeni nazw:

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

Ten zapis jest całkowicie poprawny również w samym PHP, gdzie odwrotny ukośnik oznacza, że stała leży w globalnej przestrzeni nazw.

Skrócony operator warunkowy

Jeśli trzecia wartość operatora warunkowego jest pusta, można ją pominąć:

jak w PHP: {$stock ? 'Na stanie' : ''}

skrótowo:  {$stock ? 'Na stanie'}

Nowoczesny zapis kluczy w tablicach

Klucze tablic można zapisywać podobnie jak parametry nazwane przy wywołaniu funkcji:

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

nowocześnie: {var $arr = [one: 'item 1', two: 'item 2']}

Filtry

Filtrów można użyć do dowolnego wyrażenia; wystarczy zamknąć całe wyrażenie w nawiasach:

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

Operator in

Operator in może zastąpić funkcję in_array(). Porównanie jest zawsze ścisłe:

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

Okno na historię

W swojej historii Latte wprowadziło kilka udogodnień składniowych, które w samym PHP pojawiły się kilka lat później. Na przykład w Latte dało się zapisywać tablice jako [1, 2, 3] zamiast array(1, 2, 3) albo używać operatora nullsafe $obj?->foo na długo przed tym, zanim stało się to możliwe w samym PHP. Latte wprowadziło też operator rozwijania tablic (expand) $arr, będący odpowiednikiem dzisiejszego operatora ...$arr z PHP.

Ograniczenia PHP w Latte

W Latte można zapisywać wyłącznie wyrażenia PHP. Nie da się więc użyć instrukcji zakończonych średnikiem. Nie można deklarować klas ani używać struktur sterujących, takich jak if, foreach, switch, return, try, throw i innych, dla których Latte oferuje własne tagi. Nie można też używać atrybutów, backticków ani niektórych stałych magicznych. Nie użyjesz również unset, echo, include, require, exit ani eval, bo nie są to funkcje, lecz specjalne konstrukcje języka PHP, a więc nie wyrażenia. Obsługiwane są tylko komentarze wielowierszowe /* ... */.

Te ograniczenia można jednak obejść, aktywując rozszerzenie RawPhpExtension, które pozwala używać dowolnego kodu PHP w tagu {php ...} na odpowiedzialność autora szablonu.

wersja: 3.x