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} vagy n: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 a 40 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.

verzió: 3.0