Znaczniki Latte
Przegląd i opis wszystkich znaczników (czyli tagów lub makr) systemu szablonów Latte, które są standardowo dostępne.
{$var} , {...} lub {=...} |
wyświetla escapowaną zmienną lub wyrażenie |
{$var|filter} |
wyświetla z użyciem filtrów |
{l} lub {r} |
wyświetla znak { lub } |
{if} … {elseif} … {else} … {/if} |
warunek if |
{ifset} … {elseifset} … {/ifset} |
warunek ifset |
{ifchanged} … {/ifchanged} |
sprawdza, czy nastąpiła zmiana |
{switch} {case} {default} {/switch} |
warunek switch |
n:else |
alternatywna zawartość dla warunków |
{foreach} … {/foreach} |
foreach |
{for} … {/for} |
for |
{while} … {/while} |
while |
{continueIf $cond} |
kontynuuj następną iterację |
{skipIf $cond} |
pomiń iterację |
{breakIf $cond} |
przerwanie pętli |
{exitIf $cond} |
wczesne zakończenie |
{first} … {/first} |
czy to pierwsze przejście? |
{last} … {/last} |
czy to ostatnie przejście? |
{sep} … {/sep} |
czy nastąpi kolejne przejście? |
{iterateWhile} … {/iterateWhile} |
ustrukturyzowany foreach |
$iterator |
specjalna zmienna wewnątrz foreach |
{include 'file.latte'} |
wczytuje szablon z innego pliku |
{sandbox 'file.latte'} |
wczytuje szablon w trybie sandbox |
{block} |
blok anonimowy |
{block blockname} |
definiuje blok |
{define blockname} |
definiuje blok do późniejszego użycia |
{include blockname} |
renderowanie bloku |
{include blockname from 'file.latte'} |
renderuje blok z pliku |
{import 'file.latte'} |
wczytuje bloki z szablonu |
{layout 'file.latte'} / {extends} |
określa plik z layoutem |
{embed} … {/embed} |
wczytuje szablon lub blok i pozwala nadpisać bloki |
{ifset blockname} … {/ifset} |
warunek, czy blok istnieje |
{try} … {else} … {/try} |
przechwytywanie wyjątków |
{rollback} |
odrzucenie bloku try |
{var $foo = value} |
tworzy zmienną |
{default $foo = value} |
tworzy zmienną, jeśli nie istnieje |
{parameters} |
deklaruje zmienne, typy i wartości domyślne |
{capture} … {/capture} |
przechwytuje blok do zmiennej |
{varType} |
deklaruje typ zmiennej |
{varPrint} |
proponuje typy zmiennych |
{templateType} |
deklaruje typy zmiennych według klasy |
{templatePrint} |
proponuje klasę z typami zmiennych |
{_...} |
wyświetla tłumaczenie |
{translate} … {/translate} |
tłumaczy zawartość |
{contentType} |
przełącza escapowanie i wysyła nagłówek HTTP |
{debugbreak} |
umieszcza breakpoint w kodzie |
{do} |
wykonuje kod, ale nic nie wyświetla |
{dump} |
zrzuca zmienne do Tracy Bar |
{php} |
wykonuje dowolny kod PHP |
{spaceless} … {/spaceless} |
usuwa zbędne spacje |
{syntax} |
zmiana składni w locie |
{trace} |
wyświetla ślad stosu |
n:class |
dynamiczny zapis atrybutu HTML class |
n:attr |
dynamiczny zapis dowolnych atrybutów HTML |
n:tag |
dynamiczny zapis nazwy elementu HTML |
n:ifcontent |
pomija pusty znacznik HTML |
n:href |
link używany w elementach HTML
<a> |
{link} |
wyświetla link |
{plink} |
wyświetla link do presentera |
{control} |
renderuje komponent |
{snippet} … {/snippet} |
fragment, który można wysłać AJAXem |
{snippetArea} |
opakowanie dla fragmentów |
{cache} … {/cache} |
buforuje część szablonu |
{form} … {/form} |
renderuje znaczniki formularza |
{label} … {/label} |
renderuje etykietę elementu formularza |
{input} |
renderuje element formularza |
{inputError} |
wyświetla komunikat błędu elementu formularza |
n:name |
ożywia element formularza |
{formContainer} … {/formContainer} |
rysowanie kontenera formularza |
Wyświetlanie
{$var}
{...}
{=...}
W Latte używa się znacznika {=...}
do wyświetlania dowolnego wyrażenia na wyjściu. Latte dba o Twoją
wygodę, więc jeśli wyrażenie zaczyna się od zmiennej lub wywołania funkcji, nie trzeba pisać znaku równości. Co w
praktyce oznacza, że prawie nigdy nie trzeba go pisać:
Jako wyrażenie możesz zapisać cokolwiek, co znasz z PHP. Nie musisz po prostu uczyć się nowego języka. Na przykład:
Proszę, nie szukaj w poprzednim przykładzie żadnego sensu, ale gdybyś tam jakiś znalazł, napisz do nas :-)
Escapowanie wyjścia
Jakie jest najważniejsze zadanie systemu szablonów? Zapobieganie lukom bezpieczeństwa. I dokładnie to robi Latte zawsze, gdy coś wyświetlasz. Automatycznie to escapuje:
Aby być precyzyjnym, Latte używa escapowania kontekstowego, co jest tak ważną i unikalną rzeczą, że poświęciliśmy temu osobny rozdział.
A co jeśli wyświetlasz zawartość zakodowaną w HTML z zaufanego źródła? Wtedy można łatwo wyłączyć escapowanie:
Nieprawidłowe użycie filtra noescape
może prowadzić do powstania podatności XSS! Nigdy go nie
używaj, jeśli nie jesteś całkowicie pewien, co robisz, i że wyświetlany ciąg pochodzi z zaufanego źródła.
Wyświetlanie w JavaScript
Dzięki escapowaniu kontekstowemu jest niezwykle łatwo wyświetlać zmienne wewnątrz JavaScriptu, a poprawne escapowanie załatwi Latte.
Zmienna nie musi być tylko ciągiem znaków, obsługiwany jest dowolny typ danych, który następnie zostanie zakodowany jako JSON:
Wygeneruje:
To jest również powód, dla którego wokół zmiennej nie pisze się cudzysłowów: Latte doda je samo dla ciągów znaków. A jeśli chciałbyś wstawić zmienną ciągową do innego ciągu, po prostu je połącz:
Filtry
Wyświetlone wyrażenie może być zmodyfikowane filtrem. W ten sposób na przykład ciąg znaków przekształcimy na wielkie litery i skrócimy do maksymalnie 30 znaków:
Filtry możesz stosować również do częściowych części wyrażenia w ten sposób:
Warunki
{if}
{elseif}
{else}
Warunki zachowują się tak samo, jak ich odpowiedniki w PHP. Możesz w nich używać tych samych wyrażeń, jakie znasz z PHP, nie musisz uczyć się nowego języka.
Jak każdy znacznik parzysty, tak i parę {if} ... {/if}
można zapisywać również w postaci n:atrybutu, na przykład:
Czy wiesz, że do n:atrybutów możesz dołączyć prefiks tag-
? Wtedy warunek będzie odnosił się tylko do
wyświetlenia znaczników HTML, a zawartość między nimi zostanie wyświetlona zawsze:
Boskie.
n:else
Jeśli warunek {if} ... {/if}
zapiszesz w postaci n:atrybutu, masz
możliwość podania również alternatywnej gałęzi za pomocą n:else
:
Atrybut n:else
można użyć również w parze z n:ifset
, n:foreach
, n:try
, n:ifcontent
i n:ifchanged
.
{/if $cond}
Być może Cię zaskoczy, że wyrażenie w warunku {if}
można podać również w znaczniku zamykającym. Jest to
przydatne w sytuacjach, gdy przy otwieraniu warunku jeszcze nie znamy jego wartości. Nazwijmy to odroczoną decyzją.
Na przykład zaczynamy wyświetlać tabelę z rekordami z bazy danych i dopiero po zakończeniu wyświetlania zdajemy sobie
sprawę, że w bazie danych nie było żadnego rekordu. Wtedy umieszczamy warunek w znaczniku końcowym {/if}
i jeśli nie będzie żadnego rekordu, nic z tego się nie wyświetli:
Sprytne, prawda?
W odroczonym warunku można użyć również {else}
, ale nie {elseif}
.
{ifset}
{elseifset}
Zobacz także {ifset block}
Za pomocą warunku {ifset $var}
sprawdzimy, czy zmienna (lub więcej zmiennych) istnieje i ma wartość inną
niż null. Właściwie jest to to samo, co if (isset($var))
w PHP. Jak każdy znacznik parzysty, można go
zapisywać również w postaci n:atrybutu, więc pokażmy to jako przykład:
{ifchanged}
{ifchanged}
sprawdza, czy wartość zmiennej zmieniła się od ostatniej iteracji w pętli (foreach, for lub
while).
Jeśli w znaczniku podamy jedną lub więcej zmiennych, będzie sprawdzał, czy któraś z nich się zmieniła, i zgodnie z tym wyświetli zawartość. Na przykład poniższy przykład wyświetli pierwszą literę imienia jako nagłówek za każdym razem, gdy się zmieni podczas wyświetlania imion:
Jeśli jednak nie podamy żadnego argumentu, będzie sprawdzana renderowana zawartość w porównaniu do jej poprzedniego stanu. Oznacza to, że w poprzednim przykładzie możemy spokojnie pominąć argument w znaczniku. I oczywiście możemy również użyć n:atrybutu:
Wewnątrz {ifchanged}
można również podać klauzulę {else}
.
{switch}
{case}
{default}
Porównuje wartość z wieloma opcjami. Jest to odpowiednik instrukcji warunkowej switch
, którą znasz z PHP.
Jednak Latte ją ulepsza:
- używa ścisłego porównania (
===
) - nie potrzebuje
break
Jest to więc dokładny odpowiednik struktury match
, która pojawiła się w PHP 8.0.
Klauzula {case}
może zawierać wiele wartości oddzielonych przecinkami:
Pętle
W Latte znajdziesz wszystkie pętle, które znasz z PHP: foreach, for i while.
{foreach}
Pętlę zapisujemy dokładnie tak samo jak w PHP:
Ponadto ma kilka sprytnych ulepszeń, o których teraz opowiemy.
Latte na przykład sprawdza, czy utworzone zmienne przypadkowo nie nadpisują zmiennych globalnych o tej samej nazwie. Ratuję
to sytuacje, gdy liczysz na to, że w $lang
jest aktualny język strony, i nie zdajesz sobie sprawy, że
foreach $langs as $lang
Ci tę zmienną nadpisało.
Pętlę foreach można również bardzo elegancko i oszczędnie zapisać za pomocą n:atrybutu:
Czy wiesz, że do n:atrybutów możesz dołączyć prefiks inner-
? Wtedy w pętli będzie powtarzane tylko
wnętrze elementu:
Więc wyświetli się coś takiego:
{else}
Wewnątrz pętli foreach
można podać klauzulę {else}
, której zawartość zostanie wyświetlona,
jeśli pętla jest pusta:
$iterator
Wewnątrz pętli foreach
Latte tworzy zmienną $iterator
, za pomocą której możemy sprawdzać
przydatne informacje o trwającej pętli:
$iterator->first
– czy to pierwsze przejście przez pętlę?$iterator->last
– czy to ostatnie przejście?$iterator->counter
– które to przejście liczone od jednego?$iterator->counter0
– które to przejście liczone od zera?$iterator->odd
– czy to nieparzyste przejście?$iterator->even
– czy to parzyste przejście?$iterator->parent
– iterator otaczający bieżący$iterator->nextValue
– następny element w pętli$iterator->nextKey
– klucz następnego elementu w pętli
Latte jest sprytne i $iterator->last
działa nie tylko dla tablic, ale również gdy pętla przebiega nad
ogólnym iteratorem, gdzie liczba elementów nie jest znana z góry.
{first}
{last}
{sep}
Te znaczniki można używać wewnątrz pętli {foreach}
. Zawartość {first}
zostanie wyrenderowana,
jeśli jest to pierwsze przejście. Zawartość {last}
zostanie wyrenderowana… czy zgadniesz? Tak, jeśli jest to
ostatnie przejście. Są to właściwie skróty dla {if $iterator->first}
i
{if $iterator->last}
.
Znaczniki można również elegancko użyć jako n:atrybut:
Zawartość znacznika {sep}
zostanie wyrenderowana, jeśli przejście nie jest ostatnie, jest więc przydatna do
renderowania separatorów, na przykład przecinków między wyświetlanymi elementami:
To całkiem praktyczne, prawda?
{iterateWhile}
Upraszcza grupowanie danych liniowych podczas iteracji w pętli foreach, wykonując iterację w zagnieżdżonej pętli, dopóki warunek jest spełniony. Przeczytaj szczegółowy przewodnik.
Może również elegancko zastąpić {first}
i {last}
w przykładzie powyżej:
Zobacz także filtry batch i group.
{for}
Pętlę zapisujemy dokładnie tak samo jak w PHP:
Znacznik można również użyć jako n:atrybut:
{while}
Pętlę znów zapisujemy dokładnie tak samo jak w PHP:
Lub jako n:atrybut:
Możliwa jest również wariacja z warunkiem w znaczniku końcowym, która odpowiada w PHP pętli do-while:
{continueIf}
{skipIf}
{breakIf}
Do sterowania dowolną pętlą można używać znaczników {continueIf ?}
i {breakIf ?}
, które
przejdą do następnego elementu odpowiednio zakończą pętlę przy spełnieniu warunku:
Znacznik {skipIf}
jest bardzo podobny do {continueIf}
, ale nie zwiększa licznika
$iterator->counter
, więc jeśli go wyświetlamy i jednocześnie pomijamy niektóre elementy, nie będzie dziur w
numeracji. A także klauzula {else}
zostanie wyrenderowana, jeśli pominiemy wszystkie elementy.
{exitIf}
Zakończy renderowanie szablonu lub bloku przy spełnieniu warunku (tzw. „early exit“).
Dołączanie szablonu
{include 'file.latte'}
Zobacz także {include block}
Znacznik {include}
wczytuje i renderuje podany szablon. Jeśli mówilibyśmy w języku naszego ulubionego języka
PHP, jest to coś w rodzaju:
Dołączone szablony nie mają dostępu do zmiennych aktywnego kontekstu, mają dostęp tylko do zmiennych globalnych.
Zmienne do dołączonego szablonu możesz przekazywać w ten sposób:
Nazwa szablonu może być dowolnym wyrażeniem w PHP:
Dołączoną zawartość można modyfikować za pomocą filtrów. Poniższy przykład usunie cały HTML i zmodyfikuje wielkość liter:
Domyślnie dziedziczenie szablonów w tym przypadku w żaden sposób nie figuruje.
Chociaż w dołączonym szablonie możemy używać bloków, nie dojdzie do zastąpienia odpowiadających bloków w szablonie, do
którego się dołącza. Myśl o dołączonych szablonach jako o oddzielnych, zacienionych częściach stron lub modułów. To
zachowanie można zmienić za pomocą modyfikatora with blocks
:
Relacja między nazwą pliku podaną w znaczniku a plikiem na dysku jest kwestią loadera.
{sandbox}
Przy dołączaniu szablonu utworzonego przez użytkownika końcowego powinieneś rozważyć tryb sandbox (więcej informacji w dokumentacji sandbox):
{block}
Zobacz także {block name}
Bloki bez nazwy służą jako sposób na zastosowanie filtrów do części szablonu. Na przykład w ten sposób można zastosować filtr strip, który usunie zbędne spacje:
Obsługa wyjątków
{try}
Dzięki temu znacznikowi jest niezwykle łatwo tworzyć solidne szablony.
Jeśli podczas renderowania bloku {try}
dojdzie do wyjątku, cały blok zostanie odrzucony, a renderowanie będzie
kontynuowane po nim:
Zawartość w opcjonalnej klauzuli {else}
zostanie wyrenderowana tylko wtedy, gdy wystąpi wyjątek:
Znacznik można również użyć jako n:atrybut:
Możliwe jest również zdefiniowanie własnego niestandardowego handlera wyjątków, na przykład w celu logowania.
{rollback}
Blok {try}
można zatrzymać i pominąć również ręcznie za pomocą {rollback}
. Dzięki temu nie
musisz z góry sprawdzać wszystkich danych wejściowych, a dopiero podczas renderowania możesz zdecydować, że obiektu w
ogóle nie chcesz renderować:
Zmienne
{var}
{default}
Nowe zmienne tworzymy w szablonie znacznikiem {var}
:
Znacznik {default}
działa podobnie, ale tworzy zmienne tylko wtedy, gdy nie istnieją. Jeśli zmienna już
istnieje i zawiera wartość null
, nie zostanie nadpisana:
Możesz podawać również typy zmiennych. Na razie są one informacyjne i Latte ich nie kontroluje.
{parameters}
Tak jak funkcja deklaruje swoje parametry, tak i szablon może na początku zadeklarować swoje zmienne:
Zmienne $a
i $b
bez podanej wartości domyślnej mają automatycznie wartość domyślną
null
. Zadeklarowane typy są na razie informacyjne i Latte ich nie kontroluje.
Inne zmienne niż zadeklarowane nie są przekazywane do szablonu. Tym różni się od znacznika {default}
.
{capture}
Przechwytuje wyjście do zmiennej:
Znacznik można, podobnie jak każdy znacznik parzysty, zapisać również jako n:atrybut:
Wyjście HTML zostanie zapisane do zmiennej $var
w postaci obiektu Latte\Runtime\Html
, aby nie doszło do niepożądanego escapowania przy wyświetlaniu.
Inne
{contentType}
Znacznikiem określisz, jaki typ zawartości reprezentuje szablon. Możliwości są:
html
(typ domyślny)xml
javascript
css
calendar
(iCal)text
Jego użycie jest ważne, ponieważ ustawia escapowanie
kontekstowe i tylko tak może escapować poprawnie. Na przykład {contentType xml}
przełącza do trybu XML,
{contentType text}
całkowicie wyłącza escapowanie.
Jeśli parametrem jest pełnoprawny typ MIME, taki jak na przykład application/xml
, to dodatkowo wysyła
nagłówek HTTP Content-Type
do przeglądarki:
{debugbreak}
Oznacza miejsce, w którym nastąpi zatrzymanie wykonania programu i uruchomienie debuggera, aby programista mógł przeprowadzić inspekcję środowiska wykonawczego i sprawdzić, czy program działa zgodnie z oczekiwaniami. Obsługuje Xdebug. Można dodać warunek, który określa, kiedy program ma zostać zatrzymany.
{do}
Wykonuje kod PHP i nic nie wyświetla. Podobnie jak w przypadku wszystkich innych znaczników, kodem PHP rozumie się jedno wyrażenie, zobacz ograniczenia PHP.
{dump}
Wyświetla zmienną lub aktualny kontekst.
Wymaga biblioteki Tracy.
{php}
Umożliwia wykonanie dowolnego kodu PHP. Znacznik należy aktywować za pomocą rozszerzenia RawPhpExtension.
{spaceless}
Usuwa zbędne białe znaki z wyjścia. Działa podobnie jak filtr spaceless.
Wygeneruje
Znacznik można również zapisać jako n:atrybut.
{syntax}
Znaczniki Latte nie muszą być ograniczone tylko do pojedynczych nawiasów klamrowych. Możemy wybrać również inny
ogranicznik, i to nawet w locie. Służy do tego {syntax …}
, gdzie jako parametr można podać:
- double:
{{...}}
- off: całkowicie wyłącza przetwarzanie znaczników Latte
Z wykorzystaniem n:atrybutów można wyłączyć Latte na przykład tylko dla jednego bloku JavaScriptu:
Latte można bardzo wygodnie używać również wewnątrz JavaScriptu, wystarczy unikać konstrukcji jak w tym przykładzie,
gdy litera następuje bezpośrednio po {
, zobacz Latte
wewnątrz JavaScriptu lub CSS.
Jeśli Latte wyłączysz za pomocą {syntax off}
(tj. znacznikiem, a nie n:atrybutem), będzie konsekwentnie
ignorować wszystkie znaczniki aż do {/syntax}
{trace}
Wyrzuca wyjątek Latte\RuntimeException
, którego ślad stosu jest w duchu szablonów. Zatem zamiast wywołań
funkcji i metod zawiera wywołania bloków i dołączania szablonów. Jeśli używasz narzędzia do przejrzystego wyświetlania
wyrzuconych wyjątków, takiego jak na przykład Tracy, przejrzyście wyświetli się
call stack wraz ze wszystkimi przekazywanymi argumentami.
Pomocnicy kodera HTML
n:class
Dzięki n:class
bardzo łatwo wygenerujesz atrybut HTML class
dokładnie według potrzeb.
Przykład: potrzebuję, aby aktywny element miał klasę active
:
A ponadto, aby pierwszy element miał klasy first
i main
:
I wszystkie elementy mają mieć klasę list-item
:
Niesamowicie proste, prawda?
n:attr
Atrybut n:attr
potrafi z tą samą elegancją co n:class generować dowolne
atrybuty HTML.
W zależności od zwróconych wartości wyświetli np.:
n:tag
Atrybut n:tag
potrafi dynamicznie zmieniać nazwę elementu HTML.
Jeśli $heading === null
, wyświetli się bez zmian tag <h1>
. W przeciwnym razie zmieni się
nazwa elementu na wartość zmiennej, więc dla $heading === 'h3'
wyświetli się:
Ponieważ Latte jest bezpiecznym systemem szablonów, sprawdza, czy nowa nazwa znacznika jest prawidłowa i nie zawiera żadnych niepożądanych lub szkodliwych wartości.
n:ifcontent
Zapobiega temu, aby wyświetlił się pusty element HTML, tj. element nie zawierający niczego poza spacjami.
Wyświetli w zależności od wartości zmiennej $error
:
Tłumaczenia
Aby znaczniki do tłumaczenia działały, należy aktywować translator. Do
tłumaczenia możesz również użyć filtra translate
.
{_...}
Tłumaczy wartości na inne języki.
Translatorowi można przekazywać również inne parametry:
{translate}
Tłumaczy części szablonu:
Znacznik można również zapisać jako n:atrybut, do tłumaczenia wnętrza elementu: