Rozšiřování Latte
Latte je navrženo s ohledem na rozšiřitelnost. Přestože jeho standardní sada tagů, filtrů a funkcí pokrývá mnoho případů použití, často potřebujete přidat vlastní specifickou logiku nebo pomocné nástroje. Tato stránka poskytuje přehled způsobů, jak rozšířit Latte tak, aby dokonale odpovídalo požadavkům vašeho projektu – od jednoduchých pomocníků až po komplexní novou syntaxi.
Způsoby rozšíření Latte
Zde je rychlý přehled hlavních způsobů, jak můžete přizpůsobit a rozšířit Latte:
- Vlastní filtry: Pro formátování nebo transformaci dat
přímo ve výstupu šablony (např.
{$var|myFilter}
). Ideální pro úlohy jako formátování datumů, úpravy textu nebo aplikování specifického escapování. Můžete je také použít k úpravě větších bloků HTML obsahu tak, že obsah obalíte anonymním{block}
a aplikujete na něj vlastní filtr. - Vlastní funkce: Pro přidání znovupoužitelné logiky,
kterou lze volat v rámci výrazů v šabloně (např.
{myFunction($arg1, $arg2)}
). Užitečné pro výpočty, přístup k pomocným funkcím aplikace nebo generování malých částí obsahu. - Vlastní tagy: Pro vytváření zcela nových jazykových
konstrukcí (
{mytag}...{/mytag}
nebon:mytag
). Tagy nabízejí nejvíce možností, umožňují definovat vlastní struktury, řídit parsování šablony a implementovat komplexní vykreslovací logiku. - Kompilační průchody: Funkce, které upravují abstraktní syntaktický strom (AST) šablony po parsování, ale před generováním PHP kódu. Používají se pro pokročilé optimalizace, bezpečnostní kontroly (jako je Sandbox) nebo automatické úpravy kódu.
- Vlastní loadery: Pro změnu způsobu, jakým Latte vyhledává a načítá soubory šablon (např. načítání z databáze, šifrovaného úložiště atd.).
Výběr správné metody rozšíření je klíčový. Než vytvoříte složitý tag, zvažte, zda by nestačil jednodušší filtr nebo funkce. Ukažme si to na příkladu: implementace generátoru Lorem ipsum, který jako argument přijímá počet slov k vygenerování.
- Jako tag?
{lipsum 40}
– Možné, ale tagy jsou vhodnější pro řídicí struktury nebo generování složitých značek. Tagy nelze použít přímo ve výrazech. - Jako filtr?
{=40|lipsum}
– Technicky to funguje, ale filtry jsou určeny k transformaci vstupní hodnoty. Zde je40
argument, nikoli hodnota, která se transformuje. To působí sémanticky nesprávně. - Jako funkce?
{lipsum(40)}
– Toto je nejpřirozenější řešení! Funkce přijímají argumenty a vracejí hodnoty, což je ideální pro použití v libovolném výrazu:{var $text = lipsum(40)}
.
Obecné doporučení: Používejte funkce pro výpočty/generování, filtry pro transformaci a tagy pro nové jazykové konstrukce nebo složité značky. Průchody používejte pro manipulaci s AST a loadery pro získávání šablon.
Přímá registrace
Pro pomocné nástroje specifické pro projekt nebo rychlá rozšíření umožňuje Latte přímou registraci filtrů a
funkcí do objektu Latte\Engine
.
Pro registraci filtru použijte metodu addFilter()
. Prvním argumentem vaší filtrační funkce bude hodnota
před znakem |
a následující argumenty jsou ty, které se předávají za dvojtečkou :
.
$latte = new Latte\Engine;
// Definice filtru (volatelný objekt: funkce, statická metoda atd.)
$myTruncate = fn(string $s, int $length = 50) => mb_substr($s, 0, $length);
// Registrace
$latte->addFilter('truncate', $myTruncate);
// Použití v šabloně: {$text|truncate} nebo {$text|truncate:100}
Můžete také zaregistrovat Filter Loader, funkci, která dynamicky poskytuje volatelné objekty filtrů podle požadovaného názvu:
$latte->addFilterLoader(fn(string $name) => /* vrátí volatelný objekt nebo null */);
Pro registraci funkce použitelné ve výrazech šablony použijte addFunction()
.
$latte = new Latte\Engine;
// Definice funkce
$isWeekend = fn(DateTimeInterface $date) => $date->format('N') >= 6;
// Registrace
$latte->addFunction('isWeekend', $isWeekend);
// Použití v šabloně: {if isWeekend($myDate)}Víkend!{/if}
Více informací najdete v části Vytváření vlastních filtrů a Funkcí.
Robustní způsob: Latte Extension
Zatímco přímá registrace je jednoduchá, standardním a doporučeným způsobem, jak zabalit a distribuovat rozšíření Latte, je prostřednictvím tříd Extension. Extension slouží jako centrální konfigurační bod pro registraci více tagů, filtrů, funkcí, kompilačních průchodů a dalších prvků.
Proč používat Extensions?
- Organizace: Udržuje související rozšíření (tagy, filtry atd. pro konkrétní funkci) pohromadě v jedné třídě.
- Znovupoužitelnost a sdílení: Snadno zabalíte svá rozšíření pro použití v jiných projektech nebo pro sdílení s komunitou (např. přes Composer).
- Plná síla: Vlastní tagy a kompilační průchody lze registrovat pouze prostřednictvím Extensions.
Registrace Extension
Extension se registruje v Latte pomocí metody addExtension()
(nebo prostřednictvím konfiguračního souboru):
$latte = new Latte\Engine;
$latte->addExtension(new MyProjectExtension);
Pokud zaregistrujete více rozšíření a ta definují stejně pojmenované tagy, filtry nebo funkce, má přednost naposledy přidané rozšíření. To také znamená, že vaše rozšíření mohou přepsat nativní tagy/filtry/funkce.
Kdykoli provedete změnu ve třídě a není vypnuté automatické obnovení, Latte automaticky překompiluje vaše šablony.
Vytvoření Extension
Pro vytvoření vlastního rozšíření potřebujete vytvořit třídu, která dědí z Latte\Extension. Pro představu, jak takové rozšíření vypadá, podívejte se na vestavěné CoreExtension.
Podívejme se na metody, které můžete implementovat:
beforeCompile (Latte\Engine $engine): void
Volá se před kompilací šablony. Metodu lze použít například pro inicializace související s kompilací.
getTags(): array
Volá se při kompilaci šablony. Vrací asociativní pole název tagu ⇒ volatelný objekt, což jsou funkce pro parsování tagů. Více informací.
public function getTags(): array
{
return [
'foo' => FooNode::create(...),
'bar' => BarNode::create(...),
'n:baz' => NBazNode::create(...),
// ...
];
}
Tag n:baz
představuje čistý n:atribut, tedy tag,
který lze zapsat pouze jako atribut.
U tagů foo
a bar
Latte automaticky rozpozná, zda jde o párové tagy, a pokud ano, lze je
automaticky zapisovat pomocí n:atributů, včetně variant s předponami n:inner-foo
a n:tag-foo
.
Pořadí vykonávání takových n:atributů je určeno jejich pořadím v poli vráceném metodou getTags()
.
Takže n:foo
je vždy proveden před n:bar
, i když jsou atributy v HTML tagu uvedeny v opačném
pořadí jako <div n:bar="..." n:foo="...">
.
Pokud potřebujete určit pořadí n:atributů napříč více rozšířeními, použijte pomocnou metodu order()
,
kde parametr before
xor after
určuje, které tagy jsou řazeny před nebo za tagem.
public function getTags(): array
{
return [
'foo' => self::order(FooNode::create(...), before: 'bar'),
'bar' => self::order(BarNode::create(...), after: ['block', 'snippet']),
];
}
getPasses(): array
Volá se při kompilaci šablony. Vrací asociativní pole název průchodu ⇒ volatelný objekt, což jsou funkce představující tzv. kompilační průchody, které procházejí a upravují AST.
I zde lze použít pomocnou metodu order()
. Hodnota parametrů before
nebo after
může
být *
s významem před/po všech.
public function getPasses(): array
{
return [
'optimize' => Passes::optimizePass(...),
'sandbox' => self::order($this->sandboxPass(...), before: '*'),
// ...
];
}
beforeRender (Latte\Engine $engine): void
Volá se před každým vykreslením šablony. Metoda může být použita například k inicializaci proměnných používaných během vykreslování.
getFilters(): array
Volá se před vykreslením šablony. Vrací filtry jako asociativní pole název filtru ⇒ volatelný objekt. Více informací.
public function getFilters(): array
{
return [
'batch' => $this->batchFilter(...),
'trim' => $this->trimFilter(...),
// ...
];
}
getFunctions(): array
Volá se před vykreslením šablony. Vrací funkce jako asociativní pole název funkce ⇒ volatelný objekt. Více informací.
public function getFunctions(): array
{
return [
'clamp' => $this->clampFunction(...),
'divisibleBy' => $this->divisibleByFunction(...),
// ...
];
}
getProviders(): array
Volá se před vykreslením šablony. Vrací pole poskytovatelů, což jsou obvykle objekty, které používají tagy za běhu.
Přistupuje se k nim přes $this->global->...
. Více informací.
public function getProviders(): array
{
return [
'myFoo' => $this->foo,
'myBar' => $this->bar,
// ...
];
}
getCacheKey (Latte\Engine $engine): mixed
Volá se před vykreslením šablony. Návratová hodnota se stává součástí klíče, jehož hash je obsažen v názvu souboru kompilované šablony. Pro různé návratové hodnoty tedy Latte vygeneruje různé cache soubory.