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}
saun: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.