Creare funzioni personalizzate
Aggiungete facilmente le vostre funzioni di supporto ai template Latte. Richiamate la logica PHP direttamente nelle espressioni per eseguire calcoli, accedere ai servizi o generare contenuti dinamici, mantenendo i template puliti ed espressivi.
Cosa sono le funzioni?
Le funzioni di Latte permettono di ampliare l'insieme delle funzioni richiamabili nelle espressioni del template
({...}). Consideratele come funzioni PHP personalizzate disponibili solo all'interno dei vostri template
Latte. Questo porta diversi vantaggi:
Comodità: potete definire logica di supporto (calcoli, formattazione, accesso ai dati dell'applicazione) e richiamarla
nel template con una sintassi di funzione semplice e familiare, esattamente come chiamereste strlen() o
date() in PHP.
{var $userInitials = initials($userName)} {* per esempio 'J. D.' *}
{if hasPermission('article', 'edit')}
<a href="...">Modifica</a>
{/if}
Nessun inquinamento dello spazio globale: a differenza di una vera funzione globale in PHP, le funzioni di Latte esistono solo nel contesto del rendering del template. Non dovete ingombrare il namespace globale di PHP con funzioni di supporto specifiche dei template.
Integrazione con la logica applicativa: il callable PHP dietro a una funzione di Latte può essere qualsiasi cosa: una
closure, un metodo statico o un metodo di istanza. Questo significa che le funzioni dei vostri template possono accedere
facilmente ai servizi dell'applicazione, ai database, alla configurazione o a qualsiasi altra logica necessaria, catturando
variabili (nelle closure) oppure tramite dependency injection (negli oggetti). L'esempio hasPermission qui sopra lo
mostra chiaramente: con ogni probabilità chiama un servizio di autorizzazione in background.
Sovrascrivere funzioni native (facoltativo): potete perfino definire una funzione Latte con lo stesso nome di una
funzione nativa di PHP. Nel template verrà chiamata la vostra versione personalizzata. Può essere utile per fornire un
comportamento specifico dei template o per garantire una gestione coerente (per esempio rendere strlen sempre sicuro
sui caratteri multibyte). Usate questa possibilità con cautela, per non creare confusione.
Per impostazione predefinita Latte consente di chiamare tutte le funzioni native di PHP (a meno che non le limiti la Sandbox). Le funzioni personalizzate integrano questa libreria predefinita con le esigenze specifiche del vostro progetto.
Se state trasformando un singolo valore, un filtro personalizzato è probabilmente più idiomatico.
Creare e registrare le funzioni
Come per i filtri, ci sono diversi modi di definire e registrare funzioni personalizzate.
Registrazione diretta con addFunction()
Il metodo più semplice è usare addFunction() sull'oggetto Latte\Engine. Indicate il nome della
funzione (così come comparirà nel template) e il corrispondente callable PHP.
$latte = new Latte\Engine;
// semplice funzione di supporto
$latte->addFunction('initials', function (string $name): string {
preg_match_all('#\b\w#u', $name, $m);
return implode('. ', $m[0]) . '.';
});
Uso nel template:
{var $userInitials = initials($userName)}
Gli argomenti della funzione nel template vengono passati direttamente al callable PHP nello stesso ordine. Le funzionalità di
PHP come le dichiarazioni di tipo, i valori predefiniti e i parametri variadici (...) funzionano come previsto.
Registrazione tramite estensione
Per una migliore organizzazione e riusabilità, registrate le funzioni all'interno di un'estensione di Latte. È l'approccio consigliato per le applicazioni non banali e per le librerie condivise.
namespace App\Templating;
use Latte\Extension;
use Nette\Security\Authorizator;
class MyLatteExtension extends Extension
{
public function __construct(
// si presume che il servizio Authorizator esista
private Authorizator $authorizator,
) {
}
public function getFunctions(): array
{
// registra i metodi come funzioni di Latte
return [
'hasPermission' => $this->hasPermission(...),
];
}
public function hasPermission(string $resource, string $action): bool
{
return $this->authorizator->isAllowed($resource, $action);
}
}
// registrazione (si presume che $container contenga il container DI)
$extension = $container->getByType(MyLatteExtension::class);
$latte = new Latte\Engine;
$latte->addExtension($extension);
Questo approccio mostra chiaramente come le funzioni definite in Latte possano essere sostenute da metodi di oggetti che, a loro volta, possono avere dipendenze gestite dal container di dependency injection o dalla factory della vostra applicazione. In questo modo la logica dei template resta collegata al cuore dell'applicazione senza perdere in organizzazione.
Funzioni tramite una classe con attributi
Proprio come i filtri, le funzioni possono essere definite come metodi della vostra classe dei parametri del template usando l'attributo
#[Latte\Attributes\TemplateFunction].
use Latte\Attributes\TemplateFunction;
class TemplateParameters
{
public function __construct(
public string $userName,
// altri parametri...
) {}
// questo metodo diventa disponibile nel template come {initials(...)}
#[TemplateFunction]
public function initials(string $name): string
{
preg_match_all('#\b\w#u', $name, $m);
return implode('. ', $m[0]) . '.';
}
}
// passa l'oggetto al template
$params = new TemplateParameters(userName: 'John Doe', /* ... */);
$latte->render('template.latte', $params);
Latte individua e registra automaticamente i metodi contrassegnati con questo attributo quando l'oggetto dei parametri viene passato al template. Il nome della funzione nel template corrisponde al nome del metodo.
{* usa la funzione definita nella classe dei parametri *}
{var $inits = initials($userName)}
Funzioni contestuali?
A differenza dei filtri, le funzioni non ricevono un oggetto FilterInfo. Una funzione può però ottenere accesso
al contesto del template: se il suo primo parametro è dichiarato di tipo Latte\Runtime\Template, Latte le passa
automaticamente l'oggetto del template corrente. È esattamente così che sono implementate le funzioni integrate
hasBlock() e hasTemplate().