Extinderea Latte

Latte este proiectat având în vedere extensibilitatea. Deși setul său standard de tag-uri, filtre și funcții acoperă multe cazuri de utilizare, adesea trebuie să adăugați logica specifică proprie sau instrumente auxiliare. Această pagină oferă o prezentare generală a modurilor în care puteți extinde Latte pentru a se potrivi perfect cerințelor proiectului dvs. – de la simple ajutoare la sintaxe noi complexe.

Modalități de extindere a Latte

Iată o prezentare rapidă a principalelor moduri în care puteți personaliza și extinde Latte:

  • Filtre personalizate: Pentru formatarea sau transformarea datelor direct în ieșirea șablonului (de ex. {$var|myFilter}). Ideal pentru sarcini precum formatarea datelor, modificarea textului sau aplicarea unei escapări specifice. Le puteți utiliza și pentru a modifica blocuri mai mari de conținut HTML, înfășurând conținutul într-un {block} anonim și aplicând un filtru personalizat pe acesta.
  • Funcții personalizate: Pentru adăugarea unei logici reutilizabile care poate fi apelată în cadrul expresiilor din șablon (de ex. {myFunction($arg1, $arg2)}). Utile pentru calcule, accesarea funcțiilor auxiliare ale aplicației sau generarea unor mici porțiuni de conținut.
  • Tag-uri personalizate: Pentru crearea unor construcții lingvistice complet noi ({mytag}...{/mytag} sau n:mytag). Tag-urile oferă cele mai multe posibilități, permit definirea structurilor personalizate, controlul parsării șablonului și implementarea unei logici complexe de randare.
  • Pași de compilare: Funcții care modifică arborele sintactic abstract (AST) al șablonului după parsare, dar înainte de generarea codului PHP. Se utilizează pentru optimizări avansate, verificări de securitate (cum ar fi Sandbox) sau modificări automate ale codului.
  • Loadere personalizate: Pentru modificarea modului în care Latte caută și încarcă fișierele de șabloane (de ex. încărcarea din baza de date, stocare criptată etc.).

Alegerea metodei corecte de extindere este crucială. Înainte de a crea un tag complex, luați în considerare dacă un filtru sau o funcție mai simplă nu ar fi suficientă. Să ilustrăm acest lucru cu un exemplu: implementarea unui generator Lorem ipsum care primește ca argument numărul de cuvinte de generat.

  • Ca tag? {lipsum 40} – Posibil, dar tag-urile sunt mai potrivite pentru structuri de control sau generarea de marcaje complexe. Tag-urile nu pot fi utilizate direct în expresii.
  • Ca filtru? {=40|lipsum} – Tehnic funcționează, dar filtrele sunt destinate transformării valorii de intrare. Aici, 40 este un argument, nu o valoare care se transformă. Acest lucru pare semantic incorect.
  • Ca funcție? {lipsum(40)} – Aceasta este soluția cea mai naturală! Funcțiile acceptă argumente și returnează valori, ceea ce este ideal pentru utilizarea în orice expresie: {var $text = lipsum(40)}.

Recomandare generală: Utilizați funcții pentru calcule/generare, filtre pentru transformare și tag-uri pentru construcții lingvistice noi sau marcaje complexe. Utilizați trecerile de compilare pentru manipularea AST și loaderele pentru obținerea șabloanelor.

Înregistrare directă

Pentru instrumente auxiliare specifice proiectului sau extensii rapide, Latte permite înregistrarea directă a filtrelor și funcțiilor în obiectul Latte\Engine.

Pentru a înregistra un filtru, utilizați metoda addFilter(). Primul argument al funcției dvs. de filtrare va fi valoarea dinaintea caracterului |, iar argumentele următoare sunt cele care sunt transmise după două puncte :.

$latte = new Latte\Engine;

// Definirea filtrului (obiect apelabil: funcție, metodă statică etc.)
$myTruncate = fn(string $s, int $length = 50) => mb_substr($s, 0, $length);

// Înregistrare
$latte->addFilter('truncate', $myTruncate);

// Utilizare în șablon: {$text|truncate} sau {$text|truncate:100}

Puteți înregistra și un Filter Loader, o funcție care furnizează dinamic obiecte apelabile de filtre în funcție de numele solicitat:

$latte->addFilterLoader(fn(string $name) => /* returnează un obiect apelabil sau null */);

Pentru a înregistra o funcție utilizabilă în expresiile șablonului, utilizați addFunction().

$latte = new Latte\Engine;

// Definirea funcției
$isWeekend = fn(DateTimeInterface $date) => $date->format('N') >= 6;

// Înregistrare
$latte->addFunction('isWeekend', $isWeekend);

// Utilizare în șablon: {if isWeekend($myDate)}Weekend!{/if}

Mai multe informații găsiți în secțiunile Crearea filtrelor personalizate și Funcțiilor.

Metoda robustă: Latte Extension

În timp ce înregistrarea directă este simplă, metoda standard și recomandată pentru împachetarea și distribuirea extensiilor Latte este prin intermediul claselor Extension. Extension servește ca un punct central de configurare pentru înregistrarea mai multor tag-uri, filtre, funcții, treceri de compilare și alte elemente.

De ce să folosiți Extensions?

  • Organizare: Menține extensiile conexe (tag-uri, filtre etc. pentru o funcționalitate specifică) împreună într-o singură clasă.
  • Reutilizabilitate și partajare: Împachetați ușor extensiile dvs. pentru utilizare în alte proiecte sau pentru partajare cu comunitatea (de ex. prin Composer).
  • Putere deplină: Tag-urile personalizate și trecerile de compilare pot fi înregistrate doar prin intermediul Extensions.

Înregistrarea unei Extension

O Extension se înregistrează în Latte folosind metoda addExtension() (sau prin intermediul fișierului de configurare):

$latte = new Latte\Engine;
$latte->addExtension(new MyProjectExtension);

Dacă înregistrați mai multe extensii și acestea definesc tag-uri, filtre sau funcții cu același nume, extensia adăugată ultima are prioritate. Acest lucru înseamnă, de asemenea, că extensiile dvs. pot suprascrie tag-urile/filtrele/funcțiile native.

Oricând efectuați o modificare într-o clasă și reîmprospătarea automată nu este dezactivată, Latte va recompila automat șabloanele dvs.

Crearea unei Extension

Pentru a crea propria extensie, trebuie să creați o clasă care moștenește din Latte\Extension. Pentru a vă face o idee despre cum arată o astfel de extensie, consultați CoreExtension.php încorporată.

Să aruncăm o privire la metodele pe care le puteți implementa:

beforeCompile (Latte\Engine $engine)void

Apelată înainte de compilarea șablonului. Metoda poate fi utilizată, de exemplu, pentru inițializări legate de compilare.

getTags(): array

Apelată la compilarea șablonului. Returnează un array asociativ nume tag ⇒ obiect apelabil, care sunt funcții pentru parsarea tag-urilor. Mai multe informații.

public function getTags(): array
{
	return [
		'foo' => FooNode::create(...),
		'bar' => BarNode::create(...),
		'n:baz' => NBazNode::create(...),
		// ...
	];
}

Tag-ul n:baz reprezintă un n:atribut pur, adică un tag care poate fi scris doar ca atribut.

Pentru tag-urile foo și bar, Latte recunoaște automat dacă sunt tag-uri pereche și, dacă da, pot fi scrise automat folosind n:atribute, inclusiv variante cu prefixele n:inner-foo și n:tag-foo.

Ordinea de execuție a acestor n:atribute este determinată de ordinea lor în array-ul returnat de metoda getTags(). Astfel, n:foo este întotdeauna executat înainte de n:bar, chiar dacă atributele din tag-ul HTML sunt listate în ordine inversă, ca <div n:bar="..." n:foo="...">.

Dacă trebuie să specificați ordinea n:atributelor între mai multe extensii, utilizați metoda auxiliară order(), unde parametrul before xor after specifică ce tag-uri sunt ordonate înainte sau după tag.

public function getTags(): array
{
	return [
		'foo' => self::order(FooNode::create(...), before: 'bar'),
		'bar' => self::order(BarNode::create(...), after: ['block', 'snippet']),
	];
}

getPasses(): array

Apelată la compilarea șablonului. Returnează un array asociativ nume trecere ⇒ obiect apelabil, care sunt funcții reprezentând așa-numitele treceri de compilare, care parcurg și modifică AST-ul.

Și aici se poate utiliza metoda auxiliară order(). Valoarea parametrilor before sau after poate fi * cu semnificația înainte/după toate.

public function getPasses(): array
{
	return [
		'optimize' => Passes::optimizePass(...),
		'sandbox' => self::order($this->sandboxPass(...), before: '*'),
		// ...
	];
}

beforeRender (Latte\Engine $engine)void

Apelată înainte de fiecare randare a șablonului. Metoda poate fi utilizată, de exemplu, pentru a inițializa variabilele utilizate în timpul randării.

getFilters(): array

Apelată înainte de randarea șablonului. Returnează filtrele ca un array asociativ nume filtru ⇒ obiect apelabil. Mai multe informații.

public function getFilters(): array
{
	return [
		'batch' => $this->batchFilter(...),
		'trim' => $this->trimFilter(...),
		// ...
	];
}

getFunctions(): array

Apelată înainte de randarea șablonului. Returnează funcțiile ca un array asociativ nume funcție ⇒ obiect apelabil. Mai multe informații.

public function getFunctions(): array
{
	return [
		'clamp' => $this->clampFunction(...),
		'divisibleBy' => $this->divisibleByFunction(...),
		// ...
	];
}

getProviders(): array

Apelată înainte de randarea șablonului. Returnează un array de furnizori, care sunt de obicei obiecte utilizate de tag-uri în timpul rulării. Se accesează prin $this->global->.... Mai multe informații.

public function getProviders(): array
{
	return [
		'myFoo' => $this->foo,
		'myBar' => $this->bar,
		// ...
	];
}

getCacheKey (Latte\Engine $engine)mixed

Apelată înainte de randarea șablonului. Valoarea returnată devine parte a cheii, al cărei hash este inclus în numele fișierului șablonului compilat. Prin urmare, pentru valori returnate diferite, Latte va genera fișiere cache diferite.

versiune: 3.0