Latte Bővítése
A Latte-t a bővíthetőséget szem előtt tartva tervezték. Bár a standard tag-, szűrő- és függvénykészlete számos felhasználási esetet lefed, gyakran szükség van saját specifikus logika vagy segédeszközök hozzáadására. Ez az oldal áttekintést nyújt a Latte bővítésének módjairól, hogy tökéletesen megfeleljen a projekt követelményeinek – az egyszerű segítőktől a komplex új szintaxisig.
A Latte bővítésének módjai
Íme egy gyors áttekintés a Latte testreszabásának és bővítésének fő módjairól:
- Egyéni szűrők: Az adatok formázására vagy
átalakítására közvetlenül a sablon kimenetében (pl.
{$var|myFilter}
). Ideális olyan feladatokhoz, mint a dátumformázás, szövegszerkesztés vagy specifikus escapelés alkalmazása. Nagyobb HTML-tartalomblokkok módosítására is használhatja őket úgy, hogy a tartalmat egy névtelen{block}
tagbe csomagolja, és egyéni szűrőt alkalmaz rá. - Egyéni függvények: Újrafelhasználható logika
hozzáadásához, amelyet a sablon kifejezésein belül lehet meghívni (pl.
{myFunction($arg1, $arg2)}
). Hasznos számításokhoz, az alkalmazás segédfüggvényeihez való hozzáféréshez vagy kisebb tartalomrészek generálásához. - Egyéni tagek: Teljesen új nyelvi konstrukciók létrehozásához
(
{mytag}...{/mytag}
vagyn:mytag
). A tagek kínálják a legtöbb lehetőséget, lehetővé teszik saját struktúrák definiálását, a sablon parzolásának vezérlését és komplex renderelési logika implementálását. - Fordítási menetek: Függvények, amelyek módosítják a sablon absztrakt szintaxisfáját (AST) a parzolás után, de a PHP kód generálása előtt. Fejlett optimalizálásokhoz, biztonsági ellenőrzésekhez (mint például a Sandbox) vagy automatikus kódmódosításokhoz használják.
- Egyéni betöltők: Annak megváltoztatásához, ahogyan a Latte megkeresi és betölti a sablonfájlokat (pl. betöltés adatbázisból, titkosított tárolóból stb.).
A megfelelő bővítési módszer kiválasztása kulcsfontosságú. Mielőtt létrehozna egy összetett taget, fontolja meg, hogy elegendő lenne-e egy egyszerűbb szűrő vagy függvény. Mutassuk be ezt egy példán: egy Lorem ipsum generátor implementálása, amely argumentumként a generálandó szavak számát fogadja el.
- Tagként?
{lipsum 40}
– Lehetséges, de a tagek inkább vezérlési struktúrákhoz vagy összetett jelölések generálásához alkalmasak. A tagek nem használhatók közvetlenül kifejezésekben. - Szűrőként?
{=40|lipsum}
– Technikailag működik, de a szűrők a bemeneti érték átalakítására szolgálnak. Itt a40
egy argumentum, nem pedig egy átalakítandó érték. Ez szemantikailag helytelennek tűnik. - Függvényként?
{lipsum(40)}
– Ez a legtermészetesebb megoldás! A függvények argumentumokat fogadnak el és értékeket adnak vissza, ami ideális bármely kifejezésben való használatra:{var $text = lipsum(40)}
.
Általános ajánlás: Használjon függvényeket számításokhoz/generáláshoz, szűrőket átalakításhoz és tageket új nyelvi konstrukciókhoz vagy összetett jelölésekhez. Használjon meneteket az AST manipulálásához és loadereket a sablonok lekéréséhez.
Közvetlen regisztráció
Projektspecifikus segédeszközökhöz vagy gyors bővítésekhez a Latte lehetővé teszi a szűrők és függvények
közvetlen regisztrálását a Latte\Engine
objektumba.
Szűrő regisztrálásához használja az addFilter()
metódust. A szűrőfüggvény első argumentuma a
|
jel előtti érték lesz, a következő argumentumok pedig azok, amelyeket a kettőspont :
után
adunk át.
$latte = new Latte\Engine;
// Szűrő definíciója (hívható objektum: függvény, statikus metódus stb.)
$myTruncate = fn(string $s, int $length = 50) => mb_substr($s, 0, $length);
// Regisztráció
$latte->addFilter('truncate', $myTruncate);
// Használat a sablonban: {$text|truncate} vagy {$text|truncate:100}
Regisztrálhat egy Szűrő Betöltőt (Filter Loader) is, egy függvényt, amely dinamikusan biztosítja a hívható szűrőobjektumokat a kért név alapján:
$latte->addFilterLoader(fn(string $name) => /* visszaad egy hívható objektumot vagy null-t */);
A sablon kifejezéseiben használható függvény regisztrálásához használja az addFunction()
metódust.
$latte = new Latte\Engine;
// Függvény definíciója
$isWeekend = fn(DateTimeInterface $date) => $date->format('N') >= 6;
// Regisztráció
$latte->addFunction('isWeekend', $isWeekend);
// Használat a sablonban: {if isWeekend($myDate)}Hétvége!{/if}
További információkért lásd az Egyéni szűrők létrehozása és Függvények részeket.
Robusztus módszer: Latte Extension
Míg a közvetlen regisztráció egyszerű, a Latte bővítmények csomagolásának és terjesztésének standard és ajánlott módja az Extension osztályokon keresztül történik. Az Extension központi konfigurációs pontként szolgál több tag, szűrő, függvény, fordítási menet és egyéb elem regisztrálásához.
Miért használjunk Extension-öket?
- Szervezettség: Összetartozó bővítményeket (tagek, szűrők stb. egy adott funkcióhoz) egy osztályban tart.
- Újrafelhasználhatóság és megosztás: Könnyen csomagolhatja bővítményeit más projektekben való használatra vagy a közösséggel való megosztásra (pl. Composer segítségével).
- Teljes erő: Az egyéni tagek és fordítási menetek csak Extension-ökön keresztül regisztrálhatók.
Extension regisztrálása
Az Extension a Latte-ban az addExtension()
metódussal regisztrálható (vagy a konfigurációs fájlon keresztül):
$latte = new Latte\Engine;
$latte->addExtension(new MyProjectExtension);
Ha több bővítményt regisztrál, és azok azonos nevű tageket, szűrőket vagy függvényeket definiálnak, az utoljára hozzáadott bővítmény élvez elsőbbséget. Ez azt is jelenti, hogy a bővítményei felülírhatják a natív tageket/szűrőket/függvényeket.
Amikor módosítást végez az osztályon, és az automatikus frissítés nincs kikapcsolva, a Latte automatikusan újrafordítja a sablonjait.
Extension létrehozása
Egyéni bővítmény létrehozásához létre kell hoznia egy osztályt, amely a Latte\Extension osztályból öröklődik. Hogy képet kapjon arról, hogyan néz ki egy ilyen bővítmény, tekintse meg a beépített CoreExtension.
Nézzük meg azokat a metódusokat, amelyeket implementálhat:
beforeCompile (Latte\Engine $engine): void
A sablon fordítása előtt hívódik meg. A metódus például a fordítással kapcsolatos inicializálásokhoz használható.
getTags(): array
A sablon fordításakor hívódik meg. Asszociatív tömböt ad vissza tag neve ⇒ hívható objektum formában, amelyek a tag parzoló függvények. További információk.
public function getTags(): array
{
return [
'foo' => FooNode::create(...),
'bar' => BarNode::create(...),
'n:baz' => NBazNode::create(...),
// ...
];
}
Az n:baz
tag egy tiszta n:attribútumot
képvisel, azaz egy olyan taget, amely csak attribútumként írható.
A foo
és bar
tagek esetében a Latte automatikusan felismeri, hogy páros tagekről van-e szó, és
ha igen, akkor automatikusan írhatók n:attribútumokkal, beleértve az n:inner-foo
és n:tag-foo
előtagú változatokat is.
Az ilyen n:attribútumok végrehajtási sorrendjét a getTags()
metódus által visszaadott tömbben elfoglalt
sorrendjük határozza meg. Tehát az n:foo
mindig az n:bar
előtt kerül végrehajtásra, még akkor
is, ha az attribútumok a HTML tagben fordított sorrendben vannak megadva, mint
<div n:bar="..." n:foo="...">
.
Ha több bővítmény között kell meghatároznia az n:attribútumok sorrendjét, használja az order()
segédmetódust, ahol a before
xor after
paraméter határozza meg, hogy mely tagek kerülnek a tag elé
vagy mögé.
public function getTags(): array
{
return [
'foo' => self::order(FooNode::create(...), before: 'bar'),
'bar' => self::order(BarNode::create(...), after: ['block', 'snippet']),
];
}
getPasses(): array
A sablon fordításakor hívódik meg. Asszociatív tömböt ad vissza menet neve ⇒ hívható objektum formában, amelyek az úgynevezett fordítási meneteket képviselik, amelyek bejárják és módosítják az AST-t.
Itt is használható az order()
segédmetódus. A before
vagy after
paraméterek
értéke lehet *
s jelentéssel: minden előtt/után.
public function getPasses(): array
{
return [
'optimize' => Passes::optimizePass(...),
'sandbox' => self::order($this->sandboxPass(...), before: '*'),
// ...
];
}
beforeRender (Latte\Engine $engine): void
Minden sablon renderelése előtt hívódik meg. A metódus például a renderelés során használt változók inicializálására használható.
getFilters(): array
A sablon renderelése előtt hívódik meg. A szűrőket asszociatív tömbként adja vissza szűrő neve ⇒ hívható objektum formában. További információk.
public function getFilters(): array
{
return [
'batch' => $this->batchFilter(...),
'trim' => $this->trimFilter(...),
// ...
];
}
getFunctions(): array
A sablon renderelése előtt hívódik meg. A függvényeket asszociatív tömbként adja vissza függvény neve ⇒ hívható objektum formában. További információk.
public function getFunctions(): array
{
return [
'clamp' => $this->clampFunction(...),
'divisibleBy' => $this->divisibleByFunction(...),
// ...
];
}
getProviders(): array
A sablon renderelése előtt hívódik meg. Szolgáltatók tömbjét adja vissza, amelyek általában olyan objektumok,
amelyeket a tagek futásidőben használnak. Hozzájuk a $this->global->...
segítségével lehet hozzáférni.
További információk.
public function getProviders(): array
{
return [
'myFoo' => $this->foo,
'myBar' => $this->bar,
// ...
];
}
getCacheKey (Latte\Engine $engine): mixed
A sablon renderelése előtt hívódik meg. A visszatérési érték a kulcs részévé válik, amelynek hash-értéke a lefordított sablonfájl nevében található. Tehát különböző visszatérési értékek esetén a Latte különböző cache fájlokat generál.