Création de fonctions personnalisées

Ajoutez facilement vos propres fonctions utilitaires aux templates Latte. Appelez de la logique PHP directement dans les expressions pour effectuer des calculs, accéder à des services ou générer du contenu dynamique, tout en gardant vos templates propres et puissants.

Que sont les fonctions ?

Les fonctions de Latte vous permettent d'étendre l'ensemble des fonctions appelables dans les expressions des templates ({...}). Voyez-les comme des fonctions PHP personnalisées disponibles uniquement à l'intérieur de vos templates Latte. Cela présente plusieurs avantages :

Commodité : vous pouvez définir une logique utilitaire (calculs, formatage, accès aux données de l'application) et l'appeler avec une syntaxe de fonction simple et familière directement dans le template, exactement comme vous appelleriez strlen() ou date() en PHP.

{var $userInitials = initials($userName)} {* par ex. 'J. D.' *}

{if hasPermission('article', 'edit')}
    <a href="...">Edit</a>
{/if}

Pas de pollution de la portée globale : contrairement à la définition d'une véritable fonction globale en PHP, les fonctions Latte n'existent que dans le contexte du rendu du template. Vous n'avez pas besoin d'encombrer l'espace de noms global de PHP avec des utilitaires propres aux templates.

Intégration avec la logique applicative : le callable PHP derrière une fonction Latte peut être n'importe quoi : une closure, une méthode statique ou une méthode d'instance. Vos fonctions de template peuvent donc accéder facilement aux services de l'application, aux bases de données, à la configuration ou à toute autre logique nécessaire, en capturant des variables (dans les closures) ou par injection de dépendances (dans les objets). L'exemple hasPermission ci-dessus l'illustre clairement : il appelle vraisemblablement un service d'autorisation en arrière-plan.

Redéfinition des fonctions natives (facultatif) : vous pouvez même définir une fonction Latte portant le même nom qu'une fonction PHP native. Dans le template, c'est votre version qui sera appelée. Cela peut servir à fournir un comportement propre aux templates ou à garantir un traitement cohérent (par exemple rendre strlen toujours compatible multi-octets). Utilisez cette possibilité avec prudence pour éviter la confusion.

Par défaut, Latte autorise l'appel de toutes les fonctions PHP natives (sauf restriction par le Sandbox). Les fonctions personnalisées complètent cette bibliothèque intégrée avec les besoins propres à votre projet.

Si vous ne transformez qu'une seule valeur, un filtre personnalisé sera sans doute plus idiomatique.

Création et enregistrement de fonctions

Comme pour les filtres, il existe plusieurs façons de définir et d'enregistrer des fonctions personnalisées.

Enregistrement direct via addFunction()

La méthode la plus simple consiste à utiliser addFunction() sur l'objet Latte\Engine. Vous indiquez le nom de la fonction (tel qu'il apparaîtra dans le template) et le callable PHP correspondant.

$latte = new Latte\Engine;

// Fonction utilitaire simple
$latte->addFunction('initials', function (string $name): string {
	preg_match_all('#\b\w#u', $name, $m);
	return implode('. ', $m[0]) . '.';
});

Utilisation dans le template :

{var $userInitials = initials($userName)}

Les arguments de la fonction dans le template sont passés directement au callable PHP, dans le même ordre. Les fonctionnalités de PHP comme les déclarations de type, les valeurs par défaut et les paramètres variadiques (...) fonctionnent comme prévu.

Enregistrement via une extension

Pour une meilleure organisation et une meilleure réutilisabilité, enregistrez les fonctions dans une extension Latte. C'est l'approche recommandée pour les applications non triviales et les bibliothèques partagées.

namespace App\Templating;

use Latte\Extension;
use Nette\Security\Authorizator;

class MyLatteExtension extends Extension
{
	public function __construct(
		// On suppose que le service Authorizator existe
		private Authorizator $authorizator,
	) {
	}

	public function getFunctions(): array
	{
		// Enregistre les méthodes comme fonctions Latte
		return [
			'hasPermission' => $this->hasPermission(...),
		];
	}

	public function hasPermission(string $resource, string $action): bool
	{
		return $this->authorizator->isAllowed($resource, $action);
	}
}

// Enregistrement (en supposant que $container contient le conteneur DI)
$extension = $container->getByType(MyLatteExtension::class);
$latte = new Latte\Engine;
$latte->addExtension($extension);

Cette approche montre clairement comment les fonctions définies dans Latte peuvent s'appuyer sur des méthodes d'objets qui, à leur tour, peuvent avoir leurs propres dépendances gérées par le conteneur d'injection de dépendances ou par une factory de votre application. La logique de vos templates reste ainsi reliée au cœur de l'application, sans rien perdre en organisation.

Fonctions utilisant une classe avec attributs

Comme les filtres, les fonctions peuvent être définies sous forme de méthodes dans votre classe de paramètres de template, à l'aide de l'attribut #[Latte\Attributes\TemplateFunction].

use Latte\Attributes\TemplateFunction;

class TemplateParameters
{
	public function __construct(
		public string $userName,
		// autres paramètres...
	) {}

	// Cette méthode devient disponible en tant que {initials(...)} dans le template
	#[TemplateFunction]
	public function initials(string $name): string
	{
		preg_match_all('#\b\w#u', $name, $m);
		return implode('. ', $m[0]) . '.';
	}
}

// Passage de l'objet au template
$params = new TemplateParameters(userName: 'John Doe', /* ... */);
$latte->render('template.latte', $params);

Latte découvre et enregistre automatiquement les méthodes marquées par cet attribut lorsque l'objet de paramètres est passé au template. Le nom de la fonction dans le template correspond au nom de la méthode.

{* Utilisation de la fonction définie dans la classe de paramètres *}
{var $inits = initials($userName)}

Des fonctions contextuelles ?

Contrairement aux filtres, les fonctions ne reçoivent pas d'objet FilterInfo. Une fonction peut toutefois accéder au contexte du template : si son premier paramètre est typé Latte\Runtime\Template, Latte lui passe automatiquement l'objet template courant. C'est exactement ainsi que sont implémentées les fonctions intégrées hasBlock() et hasTemplate().

version: 3.x