Tagi Latte

Przegląd i opis wszystkich tagów dostępnych domyślnie w systemie szablonów Latte.

Wypisywanie
{$var}, {...} albo {=...} wypisuje zescapowaną zmienną lub wyrażenie
{$var|filter} wypisuje z zastosowanymi filtrami
{l} albo {r} wypisuje znak { albo }
Warunki
{if}{elseif}{else}{/if} warunek if
{ifset}{elseifset}{/ifset} warunek ifset
{ifchanged}{/ifchanged} sprawdza, czy wartość się zmieniła
{switch} {case} {default} {/switch} warunek switch
n:else, n:elseif alternatywna treść dla warunków
Pętle
{foreach}{/foreach} {foreach}
{for}{/for} {for}
{while}{/while} {while}
{continueIf $cond} przejście do następnej iteracji
{skipIf $cond} pominięcie bieżącej iteracji pętli
{breakIf $cond} przerwanie pętli
{exitIf $cond} wcześniejsze zakończenie
{first}{/first} czy to pierwsza iteracja?
{last}{/last} czy to ostatnia iteracja?
{sep}{/sep} czy nastąpi kolejna iteracja?
{iterateWhile}{/iterateWhile} strukturyzowany foreach
$iterator specjalna zmienna wewnątrz pętli foreach
Dołączanie innych szablonów
{include 'file.latte'} dołącza szablon z innego pliku
{sandbox 'file.latte'} dołącza szablon w trybie sandbox
Bloki, layouty, dziedziczenie szablonów
{block} blok anonimowy
{block blockname} definiuje blok
{define blockname} definiuje blok do późniejszego użycia
{include blockname} renderuje blok
{include blockname from 'file.latte'} renderuje blok z pliku
{import 'file.latte'} importuje bloki z szablonu
{layout 'file.latte'} / {extends} wskazuje plik layoutu
{embed}{/embed} osadza szablon lub blok i pozwala nadpisywać bloki
{ifset blockname}{/ifset} warunek sprawdzający istnienie bloku
Obsługa wyjątków
{try}{else}{/try} przechwytywanie wyjątków
{rollback} odrzuca blok try
Zmienne
{var $foo = value} tworzenie zmiennej
{default $foo = value} tworzy zmienną, jeśli nie istnieje
{parameters} deklaruje zmienne, typy i wartości domyślne
{capture}{/capture} przechwytuje wynik do zmiennej
Typy
{varType} deklaruje typ zmiennej
{varPrint} proponuje typy zmiennych
{templateType} deklaruje typy zmiennych na podstawie klasy
{templatePrint} proponuje klasę z typami zmiennych
Tłumaczenie
{_...} wypisuje tłumaczenie
{translate}{/translate} tłumaczy treść
Pozostałe
{contentType} przełącza escapowanie i wysyła nagłówek HTTP
{debugbreak} umieszcza w kodzie breakpoint
{do} wykonuje kod, nic nie wypisując
{dump} zrzuca zmienne do paska Tracy
{php} wykonuje dowolny kod PHP
{spaceless}{/spaceless} usuwa zbędne białe znaki
{syntax} zmienia składnię w czasie działania
{trace} wyświetla stack trace
Pomocnicy kodera HTML
n:class dynamiczny atrybut HTML class
n:attr dynamiczne atrybuty HTML
n:tag dynamiczna nazwa elementu HTML
n:ifcontent pomija pusty tag HTML
Dostępne tylko w Nette Framework
n:href odnośnik używany w elementach HTML <a>
{link} wypisuje odnośnik
{plink} wypisuje odnośnik do presentera
{linkBase} zmiana bazy odnośników
{control} renderuje komponent
{snippet}{/snippet} snippet szablonu, który można wysłać przez AJAX
{snippetArea} obudowanie snippetu
{cache}{/cache} cachuje część szablonu
Dostępne tylko z Nette Forms
{form}{/form} renderuje tagi formularza
{form scope}, {form detached} warianty formularza bez tagu albo odłączony
{label}{/label} renderuje etykietę elementu formularza
{input} renderuje element formularza
{inputError} wypisuje komunikat o błędzie elementu formularza
n:name aktywuje element formularza
{formContainer}{/formContainer} renderuje kontener formularza
Dostępne tylko z Nette Assets
{asset} renderuje zasób jako element HTML albo URL
{preload} generuje wskazówki preload dla optymalizacji wydajności
n:asset dodaje atrybuty zasobu do elementów HTML

Wypisywanie

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

W Latte tag {=...} służy do wypisania na wyjście dowolnego wyrażenia. Latte dba o Twoją wygodę, więc jeśli wyrażenie zaczyna się od zmiennej albo wywołania funkcji, nie trzeba pisać znaku równości. W praktyce oznacza to, że prawie nigdy nie trzeba go pisać:

Name: {$name} {$surname}<br>
Age: {date('Y') - $birth}<br>

Jako wyrażenie możesz zapisać wszystko, co znasz z PHP. Po prostu nie musisz uczyć się nowego języka. Na przykład:

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

Nie szukaj w poprzednim przykładzie żadnego sensu, ale jeśli go znajdziesz, daj nam znać :-)

Escapowanie wyniku

Jakie jest najważniejsze zadanie systemu szablonów? Zapobiegać podatnościom bezpieczeństwa. I dokładnie to robi Latte za każdym razem, gdy coś wypisujesz. Automatycznie to escapuje:

<p>{='one < two'}</p>   {* wypisze: '<p>one &lt; two</p>' *}

Ściśle rzecz biorąc, Latte używa escapowania świadomego kontekstu, które jest funkcją tak ważną i unikalną, że poświęciliśmy jej osobny rozdział.

A co, jeśli wypisujesz treść zakodowaną w HTML pochodzącą z zaufanego źródła? Wtedy możesz łatwo wyłączyć escapowanie:

{$trustedHtmlString|noescape}

Niewłaściwe użycie filtra noescape może prowadzić do podatności XSS! Nigdy go nie używaj, o ile nie masz absolutnej pewności, co robisz i że wypisywany łańcuch pochodzi z zaufanego źródła.

Wypisywanie w JavaScripcie

Dzięki escapowaniu świadomemu kontekstu wypisywanie zmiennych wewnątrz JavaScriptu jest cudownie łatwe, a Latte zadba o poprawne escapowanie.

Zmienna nie musi być łańcuchem, obsługiwany jest dowolny typ danych, który następnie zostaje zakodowany jako JSON:

{var $foo = ['hello', true, 1]}
<script>
	alert({$foo});
</script>

Wygeneruje:

<script>
	alert(["hello", true, 1]);
</script>

Właśnie dlatego nie powinieneś pisać cudzysłowów wokół zmiennej: Latte dodaje je dla łańcuchów automatycznie. A jeśli chcesz wstawić zmienną łańcuchową do innego łańcucha, po prostu je połącz:

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

	alert({="Hello $name!"});         // OK

	alert('Hello {$name} !');         // BŁĄD!
</script>

Filtry

Wypisywane wyrażenie można modyfikować filtrami. Ten przykład zamienia łańcuch na wielkie litery i skraca go do maksymalnie 30 znaków:

{$string|upper|truncate:30}

Filtry możesz zastosować także do części wyrażenia, o tak:

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

Warunki

{if} {elseif} {else}

Warunki zachowują się tak samo jak ich odpowiedniki w PHP. Możesz używać tych samych wyrażeń, które znasz z PHP, nie musisz uczyć się nowego języka.

{if $product->inStock > Stock::Minimum}
	Na stanie
{elseif $product->isOnWay()}
	W drodze
{else}
	Niedostępny
{/if}

Jak każdy tag parzysty, parę {if} ... {/if} można zapisać także n:atrybutem, na przykład:

<p n:if="$count > 0">Na stanie {$count} szt.</p>

Wiesz, że do n:atrybutów możesz dodać prefiks tag-? Wtedy warunek wpłynie tylko na wypisanie tagów HTML, a treść między nimi zostanie wypisana zawsze:

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

{* wypisze 'Hello', gdy $clickable jest fałszywe *}
{* wypisze '<a href="...">Hello</a>', gdy $clickable jest prawdziwe *}

Świetne.

n:else n:elseif

Jeśli zapiszesz warunek {if} ... {/if} w postaci n:atrybutu, masz możliwość podania alternatywnych gałęzi za pomocą n:else (od 3.0.12) i n:elseif (od 3.1):

<strong n:if="$count > 0">Na stanie {$count} szt.</strong>

<em n:elseif="$count < 0">Nieprawidłowa liczba</em>

<em n:else>niedostępny</em>

Atrybutu n:else można używać także w połączeniu z n:ifset, n:foreach, n:try, n:ifcontent i n:ifchanged.

{/if $cond}

Może Cię zaskoczyć, że wyrażenie warunku {if} można podać także w tagu zamykającym. Przydaje się to w sytuacjach, gdy w chwili otwierania warunku nie znamy jeszcze jego wartości. Nazwijmy to decyzją odroczoną.

Na przykład zaczynamy wypisywać tabelę z rekordami z bazy danych i dopiero po zakończeniu wypisywania orientujemy się, że w bazie nie było żadnych rekordów. Umieszczamy więc warunek w tagu zamykającym {/if} i jeśli rekordów nie ma, nic z tego się nie wypisze:

{if}
	<h1>Lista rekordów z bazy danych</h1>

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

Poręczne, prawda?

W odroczonym warunku możesz użyć również {else}, ale nie {elseif}.

{ifset} {elseifset}

Zobacz też {ifset block}

Warunku {ifset $var} używa się do ustalenia, czy zmienna (albo kilka zmiennych) istnieje i ma wartość różną od null. To właściwie to samo co if (isset($var)) w PHP. Jak każdy tag parzysty można go zapisać także n:atrybutem, pokażmy więc przykład:

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

{ifchanged}

{ifchanged} sprawdza, czy wartość zmiennej zmieniła się od ostatniej iteracji w pętli (foreach, for albo while).

Jeśli podamy w tagu jedną lub więcej zmiennych, sprawdzi, czy któraś z nich się zmieniła, i odpowiednio wypisze treść. Na przykład poniższy przykład przy wypisywaniu imion wypisuje jako nagłówek pierwszą literę imienia za każdym razem, gdy się ona zmieni:

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

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

Jeśli jednak nie podamy argumentu, sprawdzana będzie sama wyrenderowana treść w porównaniu z jej poprzednim stanem. Oznacza to, że w poprzednim przykładzie możemy bezpiecznie pominąć argument w tagu. I oczywiście możemy użyć też n:atrybutu:

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

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

Wewnątrz {ifchanged} można użyć również klauzuli {else}.

{switch} {case} {default}

Porównuje wartość z wieloma opcjami. Przypomina to instrukcję switch znaną z PHP. Latte jednak ją ulepsza:

  • używa porównania ścisłego (===)
  • nie wymaga break

Blisko więc odzwierciedla konstrukcję match wprowadzoną w PHP 8.0.

{switch $transport}
	{case train}
		Pociągiem
	{case plane}
		Samolotem
	{default}
		Inaczej
{/switch}

Klauzula {case} może zawierać kilka wartości oddzielonych przecinkami:

{switch $status}
{case $status::New}<b>nowy artykuł</b>
{case $status::Sold, $status::Unknown}<i>niedostępny</i>
{/switch}

Pętle

W Latte znajdziesz wszystkie pętle, które znasz z PHP: foreach, for i while.

{foreach}

Pętlę zapisujesz dokładnie tak samo jak w PHP:

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

Ma poza tym kilka poręcznych możliwości, o których teraz opowiemy.

Na przykład Latte sprawdza, czy tworzone zmienne przypadkiem nie nadpisują globalnych zmiennych o tej samej nazwie. Ratuje Cię to przed sytuacjami, w których oczekujesz, że $lang zawiera bieżący język strony, i nie zdajesz sobie sprawy, że foreach $langs as $lang tę zmienną nadpisał.

Pętlę foreach można też zapisać bardzo elegancko i oszczędnie n:atrybutem:

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

Wiesz, że do n:atrybutów możesz dodać prefiks inner-? Wtedy w pętli powtórzy się tylko wnętrze elementu:

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

Wypisze więc coś w rodzaju:

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

{else}

Wewnątrz pętli foreach możesz podać klauzulę {else}, której treść wyświetli się, gdy pętla będzie pusta:

<ul>
	{foreach $people as $person}
		<li>{$person->name}</li>
	{else}
		<li><em>Niestety, na tej liście nie ma użytkowników</em></li>
	{/foreach}
</ul>

$iterator

Wewnątrz pętli foreach Latte tworzy zmienną $iterator, która pozwala poznać przydatne informacje o trwającej pętli:

  • $iterator->first – czy to pierwsza iteracja?
  • $iterator->last – czy to ostatnia iteracja?
  • $iterator->counter – licznik iteracji, licząc od jedynki
  • $iterator->counter0 – licznik iteracji, licząc od zera
  • $iterator->odd – czy to nieparzysta iteracja?
  • $iterator->even – czy to parzysta iteracja?
  • $iterator->parent – iterator otaczający bieżący
  • $iterator->nextValue – następny element w pętli
  • $iterator->nextKey – klucz następnego elementu w pętli
{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 jest sprytne i $iterator->last działa nie tylko dla tablic, ale też wtedy, gdy pętla przebiega po ogólnym iteratorze, w którym liczba elementów nie jest znana z góry.

{first} {last} {sep}

Tych tagów można używać wewnątrz pętli {foreach}. Treść {first} renderuje się, jeśli to pierwsza iteracja. Treść {last} renderuje się… zgadniesz? Tak, jeśli to ostatnia iteracja. To właściwie skróty dla {if $iterator->first} i {if $iterator->last}.

Tagów można elegancko użyć również jako n:atrybutów:

{foreach $rows as $row}
	{first}<h1>Lista imion</h1>{/first}

	<p>{$row->name}</p>

	<hr n:last>
{/foreach}

Treść tagu {sep} renderuje się, jeśli iteracja nie jest ostatnia, co czyni go odpowiednim do renderowania separatorów, na przykład przecinków między wypisywanymi elementami:

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

Całkiem praktyczne, prawda?

{iterateWhile}

Upraszcza grupowanie danych liniowych przy iteracji w pętli foreach, wykonując iterację w zagnieżdżonej pętli tak długo, jak spełniony jest warunek. Przeczytaj szczegółową instrukcję.

Może też elegancko zastąpić {first} i {last} w powyższym przykładzie:

{foreach $rows as $row}
	<table>

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

	</table>
{/foreach}

Zobacz też filtry batchgroup.

{for}

Pętlę zapisujemy dokładnie tak samo jak w PHP:

{for $i = 0; $i < 10; $i++}
	<span>Element #{$i}</span>
{/for}

Tag można zapisać także jako n:atrybut:

<h1 n:for="$i = 0; $i < 10; $i++">{$i}</h1>

{while}

Znów zapisujemy pętlę dokładnie tak samo jak w PHP:

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

Albo jako n:atrybut:

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

Możliwy jest też wariant z warunkiem w tagu zamykającym, odpowiadający pętli do-while w PHP:

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

{continueIf} {skipIf} {breakIf}

Do sterowania dowolną pętlą można użyć specjalnych tagów {continueIf ?} i {breakIf ?}. Przeskakują odpowiednio do następnej iteracji albo kończą pętlę, jeśli warunek jest spełniony:

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

Tag {skipIf} jest bardzo podobny do {continueIf}, ale nie zwiększa $iterator->counter. Zapobiega to lukom w numeracji, gdy wypisujesz licznik i pomijasz część elementów. Ponadto klauzula {else} wyrenderuje się, jeśli wszystkie elementy zostaną pominięte.

<ul>
	{foreach $people as $person}
		{skipIf $person->age < 18}
		<li>{$iterator->counter}. {$person->name}</li>
	{else}
		<li><em>Niestety, na tej liście nie ma osób dorosłych</em></li>
	{/foreach}
</ul>

{exitIf}

Kończy renderowanie szablonu albo bloku, gdy spełniony jest warunek (czyli “early exit”).

{exitIf !$messages}

<h1>Messages</h1>
<div n:foreach="$messages as $message">
   {$message}
</div>

Dołączanie szablonów

{include 'file.latte'}

Zobacz też {include block} i {embed}

Tag {include} wczytuje i renderuje podany szablon. W naszym ulubionym języku PHP to coś w rodzaju:

<?php include 'header.phtml'; ?>

Dołączane szablony nie mają dostępu do zmiennych aktywnego kontekstu, mają natomiast dostęp do zmiennych globalnych.

Zmienne do dołączanego szablonu możesz przekazać tak:

{include 'template.latte', foo: 'bar', id: 123}

Nazwą szablonu może być dowolne wyrażenie PHP:

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

Czy szablon istnieje, można sprawdzić funkcją hasTemplate().

Dołączaną treść można modyfikować filtrami. Poniższy przykład usuwa cały HTML i dostosowuje wielkość liter:

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

Domyślnie dziedziczenie szablonów nie wchodzi tu w grę. Choć w dołączanych szablonach możesz używać bloków, nie zastąpią one odpowiadających im bloków w szablonie, do którego są dołączane. Traktuj dołączane szablony jak niezależne, odizolowane części stron albo modułów. To zachowanie można zmienić modyfikatorem with blocks:

{include 'template.latte' with blocks}

Związek między nazwą pliku podaną w tagu a plikiem na dysku zależy od loadera.

{sandbox}

Dołączając szablon utworzony przez użytkownika końcowego, powinieneś rozważyć umieszczenie go w sandboxie (więcej informacji w dokumentacji sandboxa):

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

{block}

Zobacz też {block name}

Bloki bez nazwy dają możliwość zastosowania filtrów do części szablonu. Możesz na przykład zastosować filtr spaceless, aby usunąć zbędne spacje:

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

Obsługa wyjątków

{try}

Dzięki temu tagowi tworzenie solidnych szablonów jest wyjątkowo łatwe.

Jeśli podczas renderowania bloku {try} wystąpi wyjątek, cały blok zostanie odrzucony, a renderowanie będzie kontynuowane za nim:

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

Treść opcjonalnej klauzuli {else} renderuje się tylko wtedy, gdy wystąpi wyjątek:

{try}
	<ul>
		{foreach $twitter->loadTweets() as $tweet}
  			<li>{$tweet->text}</li>
		{/foreach}
	</ul>
	{else}
	<p>Niestety, nie udało się załadować tweetów.</p>
{/try}

Tag można zapisać także jako n:atrybut:

<ul n:try>
	...
</ul>

Można też zdefiniować własny handler wyjątków, na przykład do celów logowania.

{rollback}

Blok {try} można też zatrzymać i pominąć ręcznie za pomocą {rollback}. Dzięki temu nie musisz sprawdzać wszystkich danych wejściowych z góry i dopiero podczas renderowania możesz zdecydować, że obiekt w ogóle nie ma być renderowany:

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

Zmienne

{var} {default}

Nowe zmienne tworzymy w szablonie tagiem {var}:

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

{* deklaracja wielokrotna *}
{var $name = 'John Smith', $age = 27}

Tag {default} działa podobnie, ale tworzy zmienne tylko wtedy, gdy nie istnieją. Jeśli zmienna już istnieje i zawiera wartość null, nie zostanie nadpisana:

{default $lang = 'en'}

Możesz podać także typy zmiennych. Na razie mają charakter informacyjny i Latte ich nie sprawdza.

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

{parameters}

Tak jak funkcja deklaruje swoje parametry, szablon może na początku zadeklarować swoje zmienne:

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

Zmienne $a i $b bez podanej wartości domyślnej mają automatycznie wartość domyślną null. Zadeklarowane typy mają na razie charakter informacyjny i Latte ich nie sprawdza.

Zmienne inne niż zadeklarowane nie są przekazywane do szablonu. Tym różni się to od tagu {default}.

{capture}

Przechwytuje wynik do zmiennej:

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

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

Jak każdy tag parzysty, ten tag można zapisać także jako n:atrybut:

<ul n:capture="$var">
	<li>Hello World</li>
</ul>

Wynik HTML zapisywany jest do zmiennej $var jako obiekt Latte\Runtime\Html, aby zapobiec niepożądanemu escapowaniu przy wypisywaniu.

Pozostałe

{contentType}

Tym tagiem podajesz, jaki typ treści reprezentuje szablon. Do wyboru są:

  • html (typ domyślny)
  • xml
  • javascript
  • css
  • calendar (iCal)
  • text

Jego użycie jest ważne, bo ustawia escapowanie zależne od kontekstu i dopiero wtedy Latte może escapować poprawnie. Na przykład {contentType xml} przełącza w tryb XML, a {contentType text} całkowicie wyłącza escapowanie.

Jeśli parametrem jest pełny typ MIME, na przykład application/xml, wysyła też do przeglądarki nagłówek HTTP Content-Type:

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

{debugbreak}

Wskazuje miejsce, w którym wykonywanie programu zostanie wstrzymane. Służy do celów debugowania i pozwala programiście zbadać środowisko uruchomieniowe oraz upewnić się, że kod działa zgodnie z oczekiwaniami. Obsługuje Xdebug. Możesz też dodać warunek określający, kiedy program ma się zatrzymać.

{debugbreak}                {* wstrzymuje program *}

{debugbreak $counter == 1}  {* wstrzymuje program, jeśli warunek jest spełniony *}

{do}

Wykonuje kod PHP i nic nie wypisuje. Jak przy wszystkich innych tagach, przez kod PHP rozumie się pojedyncze wyrażenie, zobacz Ograniczenia PHP.

{do $num++}

{dump}

Zrzuca zmienną albo bieżący kontekst.

{dump $name} {* zrzuca zmienną $name *}

{dump}       {* zrzuca wszystkie aktualnie zdefiniowane zmienne *}

Wymaga biblioteki Tracy.

{php}

Domyślnie {php} działa jak przestarzały alias dla {do} i oblicza tylko pojedyncze wyrażenie. Aby wykonywać dowolny kod PHP, tag trzeba aktywować rozszerzeniem RawPhpExtension.

{spaceless}

Usuwa z wyniku zbędne białe znaki. Działa podobnie jak filtr spaceless.

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

Wygeneruje:

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

Tag można zapisać także jako n:atrybut.

{syntax}

Tagi Latte nie muszą być zamknięte tylko w pojedynczych klamrach. Możesz wybrać inny separator, nawet w czasie działania. Służy do tego {syntax …}, gdzie parametrem może być:

  • double: {{...}}
  • off: całkowicie wyłącza przetwarzanie tagów Latte

Za pomocą n:atrybutów możesz wyłączyć Latte na przykład tylko dla jednego bloku JavaScriptu:

<script n:syntax="off">
	var obj = {var: 123}; // to już nie jest tag
</script>

Latte da się bardzo wygodnie używać wewnątrz JavaScriptu, wystarczy unikać konstrukcji jak w tym przykładzie, gdzie bezpośrednio po { następuje litera, zobacz Latte wewnątrz JavaScriptu lub CSS.

Jeśli wyłączysz Latte przez {syntax off} (czyli tagiem, a nie n:atrybutem), będzie ono ściśle ignorować wszystkie tagi aż do {/syntax}.

{trace}

Zgłasza wyjątek Latte\RuntimeException, którego stack trace utrzymany jest w duchu szablonów. Zamiast wywołań funkcji i metod chodzi więc o wywołania bloków i dołączanie szablonów. Jeśli używasz narzędzia do przejrzystego wyświetlania zgłoszonych wyjątków, na przykład Tracy, zobaczysz wyraźnie stos wywołań wraz ze wszystkimi przekazanymi argumentami.

Pomocnicy kodera HTML

n:class

Od Latte 3.1 standardowy atrybut HTML class zyskał tę samą funkcjonalność. Nie musisz więc już używać n:class.

Dzięki n:class bardzo łatwo wygenerujesz atrybut HTML class dokładnie tak, jak potrzebujesz.

Przykład: potrzebuję, aby aktywny element miał klasę active:

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

I dalej, potrzebuję, aby pierwszy element miał klasy first i main:

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

A wszystkie elementy mają mieć klasę list-item:

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

Zadziwiająco proste, prawda?

n:attr

Atrybut n:attr potrafi wygenerować dowolne atrybuty HTML z tą samą elegancją co class.

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

W zależności od zwracanych wartości wypisze na przykład:

<input type="checkbox">

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

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

Możliwości smart atrybutów w Latte 3.1, takie jak pomijanie wartości null czy przekazywanie tablic do class albo style, działają również wewnątrz n:attr:

<div n:attr="class: [a, b], title: $title"></div>

n:tag

Atrybut n:tag potrafi dynamicznie zmienić nazwę elementu HTML.

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

Jeśli $heading === null, tag <h1> zostanie wypisany bez zmian. W przeciwnym razie nazwa elementu zmieni się na wartość zmiennej, więc dla $heading === 'h3' zapisze:

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

Ponieważ Latte jest bezpiecznym systemem szablonów, sprawdza, czy nowa nazwa tagu jest poprawna i nie zawiera niepożądanych ani złośliwych wartości.

n:ifcontent

Zapobiega wypisaniu pustego elementu HTML, czyli elementu zawierającego wyłącznie białe znaki.

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

W zależności od wartości zmiennej $error wypisze:

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

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

Tłumaczenie

Aby tagi tłumaczeń działały, trzeba aktywować translator. Do tłumaczenia możesz użyć też filtra translate.

{_...}

Tłumaczy wartości na inne języki.

<a href="basket">{_'Koszyk'}</a>
<span>{_$item}</span>

Do translatora można przekazać także inne parametry:

<a href="basket">{_'Koszyk', domain: order}</a>

{translate}

Tłumaczy części szablonu:

<h1>{translate}Zamówienie{/translate}</h1>

{translate domain: order}Lorem ipsum ...{/translate}

Tag można zapisać także jako n:atrybut, aby przetłumaczyć wnętrze elementu:

<h1 n:translate>Zamówienie</h1>
wersja: 3.x