Rozšiřujeme Latte
Latte je mimořádně flexibilní šablonovací systém, který můžete přizpůsobit svým potřebám mnoha způsoby. Ať už potřebujete přidat vlastní filtry, funkce, značky nebo změnit způsob načítání šablon, Latte vám to umožní. Pojďme se podívat, jak na to.
Tato kapitola vás provede různými metodami rozšíření Latte. Pokud plánujete své rozšíření použít ve více projektech nebo ho sdílet s komunitou, doporučujeme vytvořit samostatné rozšíření.
Kolik cest vede do Říma?
Jelikož některé způsoby rozšíření Latte mohou být podobné, pojďme si nejprve objasnit rozdíly mezi nimi. Jako příklad implementujeme generátor textu Lorem ipsum, kterému předáme požadovaný počet slov.
Základním stavebním kamenem jazyka Latte je značka (tag). Generátor bychom mohli implementovat jako novou značku:
Tato značka by fungovala dobře, ale nemusí být dostatečně flexibilní, protože ji nelze použít ve výrazech. Mimochodem, v praxi je potřeba vytvářet nové značky jen zřídka, což je dobrá zpráva, protože jde o složitější způsob rozšíření.
Zkusme místo značky vytvořit filtr:
To je také platná možnost. Avšak filtr by měl typicky transformovat předanou hodnotu. V tomto případě hodnotu
40
, která určuje počet generovaných slov, používáme jako argument filtru, nikoli jako hodnotu
k transformaci.
Pojďme tedy zkusit funkci:
To je ono! Pro tento konkrétní případ je vytvoření funkce ideálním způsobem rozšíření. Můžete ji volat kdekoli, kde je povolen výraz, například:
Tento příklad ukazuje, že výběr správného způsobu rozšíření závisí na konkrétním použití. Nyní se pojďme podívat na jednotlivé metody podrobněji.
Filtry
Filtry jsou mocné nástroje pro transformaci dat přímo v šabloně. Vytvořit vlastní filtr je jednoduché:
V tomto případě by bylo užitečné, kdyby filtr přijímal další parametr:
V šabloně se pak volá takto:
Všimněte si, že:
- První argument filtru je vždy hodnota nalevo od
|
- Další argumenty se předávají za dvojtečkou
- Filtry mohou mít libovolný počet argumentů, včetně volitelných
Pokud filtr vrací řetězec v HTML, můžete jej označit tak, aby jej Latte automaticky (a tedy dvojitě) neescapovalo. Tím
se vyhnete nutnosti používat v šabloně |noescape
. Nejjednodušší způsob je obalit řetězec do objektu
Latte\Runtime\Html
, alternativou jsou Kontextové filtry.
Filtr musí v takovém případě zajistit správné escapování dat.
Filtry pomocí třídy
Alternativním způsobem definice filtru je využití třídy. Vytvoříme
metodu s atributem TemplateFilter
:
Tento přístup je zvláště užitečný, když máte více filtrů nebo když filtry potřebují přístup ke sdíleným zdrojům.
Zavaděč filtrů
Místo registrace jednotlivých filtrů lze vytvořit tzv. zavaděč. Jde o funkci, která se volá s názvem filtru jako argumentem a vrací jeho PHP callable, nebo null.
Tento přístup umožňuje dynamicky načítat filtry podle potřeby, což může být užitečné v rozsáhlých aplikacích.
Kontextové filtry
Kontextové filtry jsou speciální typ filtrů, které mají přístup k dodatečným informacím o kontextu, ve kterém jsou použity:
Kontextové filtry mohou zjišťovat a měnit content-type, který obdrží v proměnné $info->contentType
.
Pokud se filtr volá klasicky nad proměnnou (např. {$var|foo}
), bude $info->contentType
obsahovat null.
Filtr by měl nejprve ověřit, zda podporuje content-type vstupního řetězce. Může ho také změnit. Příklad filtru, který přijímá text (nebo null) a vrací HTML:
Filtr musí v takovém případě zajistit správné escapování dat.
Všechny filtry, které se používají nad bloky (např. jako
{block|foo}...{/block}
), musí být kontextové.
Funkce
V Latte lze standardně používat všechny nativní funkce PHP, pokud to nezakáže sandbox. Zároveň si můžete definovat vlastní funkce, které mohou přepsat i nativní funkce.
Funkci vytvoříme registrací jejího názvu a libovolného PHP callable:
Použití je pak stejné jako při volání PHP funkce:
Funkce pomocí třídy
Alternativním způsobem definice funkce je využití třídy. Vytvoříme
metodu s atributem TemplateFunction
:
Tento přístup je užitečný pro organizaci souvisejících funkcí a sdílení zdrojů mezi nimi.
Loadery
Loadery jsou zodpovědné za načítání šablon ze zdroje, například ze souborového systému. Nastavují se metodou
setLoader()
:
Latte nabízí tyto vestavěné loadery:
FileLoader
Výchozí loader. Načítá šablony ze souborového systému.
Přístup k souborům lze omezit nastavením základního adresáře:
StringLoader
Načítá šablony z řetězců. Tento loader je velmi užitečný pro testování. Lze jej také použít pro menší projekty, kde může být výhodné ukládat všechny šablony do jediného PHP souboru.
Zjednodušené použití:
Vytvoření vlastního loaderu
Loader je třída, která implementuje rozhraní Latte\Loader.
Tagy (makra)
Jednou z nejzajímavějších funkcí šablonovacího jádra je možnost definovat nové jazykové konstrukce pomocí značek. Je to také složitější funkcionalita a vyžaduje pochopení vnitřního fungování Latte.
Ve většině případů však značka není potřeba:
- pokud má generovat nějaký výstup, použijte místo ní funkci
- pokud má upravovat nějaký vstup a vracet ho, použijte filtr
- pokud má upravovat oblast textu, obalte jej značkou
{block}
a použijte filtr - pokud nemá nic vypisovat, ale pouze volat funkci, použijte
{do}
Pokud se přesto rozhodnete vytvořit tag, skvělé! Vše potřebné najdete v kapitole Vytváříme Extension.
Průchody kompilátoru
Průchody kompilátoru jsou funkce, které modifikují AST (abstraktní syntaktický strom) nebo z něj sbírají informace. V Latte je takto implementován například sandbox: projde všechny uzly AST, najde volání funkcí a metod a nahradí je za kontrolovaná volání.
Stejně jako v případě značek se jedná o složitější funkcionalitu, která vyžaduje pochopení vnitřního fungování Latte. Vše potřebné najdete v kapitole Vytváříme Extension.