Création de fonctions personnalisées

Ajoutez facilement des fonctions d'aide personnalisées aux templates Latte. Appelez la logique PHP directement dans les expressions pour les calculs, l'accès aux services ou la génération de contenu dynamique, ce qui maintient vos templates propres et performants.

Que sont les fonctions ?

Les fonctions dans Latte vous permettent d'étendre l'ensemble des fonctions qui peuvent être appelées dans les expressions des templates ({...}). Vous pouvez les considérer comme des fonctions PHP personnalisées disponibles uniquement à l'intérieur de vos templates Latte. Cela apporte plusieurs avantages :

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

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

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

Pas de pollution de l'espace global : Contrairement à la définition d'une fonction globale réelle 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 PHP avec des assistants spécifiques aux templates.

Intégration avec la logique de l'application : L'appelable PHP derrière une fonction Latte peut être n'importe quoi – une fonction anonyme, une méthode statique ou une méthode d'instance. Cela signifie que vos fonctions dans les templates peuvent facilement accéder aux services de l'application, aux bases de données, à la configuration ou à toute autre logique nécessaire en capturant des variables (dans le cas de fonctions anonymes) ou en utilisant l'injection de dépendances (dans le cas d'objets). L'exemple hasPermission ci-dessus le démontre clairement, car il appelle probablement un service d'autorisation en arrière-plan.

Remplacement des fonctions natives (facultatif) : Vous pouvez même définir une fonction Latte avec le même nom qu'une fonction PHP native. Dans le template, votre propre version sera appelée à la place de la fonction originale. Cela peut être utile pour fournir un comportement spécifique au template ou assurer un traitement cohérent (par exemple, s'assurer que strlen est toujours compatible avec les caractères multi-octets). Utilisez cette fonctionnalité avec prudence pour éviter toute confusion.

Par défaut, Latte autorise l'appel de toutes les fonctions PHP natives (sauf si elles sont restreintes par le Sandbox). Les fonctions personnalisées étendent cette bibliothèque intégrée avec les besoins spécifiques de votre projet.

Si vous ne transformez qu'une seule valeur, il peut être plus approprié d'utiliser un filtre personnalisé.

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 spécifiez le nom de la fonction (tel qu'il apparaîtra dans le template) et l'appelable PHP correspondant.

$latte = new Latte\Engine;

// Fonction d'aide 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 à l'appelable PHP dans le même ordre. Les fonctionnalités PHP telles que les indications de type, les valeurs par défaut et les paramètres variables (...) fonctionnent comme prévu.

Enregistrement via une extension

Pour une meilleure organisation et réutilisabilité, enregistrez les fonctions dans une extension Latte. Cette approche est recommandée pour les applications plus complexes ou les bibliothèques partagées.

namespace App\Latte;

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

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

	public function getFunctions(): array
	{
		// Enregistrement des 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 DIC)
$extension = $container->getByType(App\Latte\MyLatteExtension::class);
$latte = new Latte\Engine;
$latte->addExtension($extension);

Cette approche illustre comment les fonctions définies dans Latte peuvent être soutenues par des méthodes d'objets, qui peuvent avoir leurs propres dépendances gérées par le conteneur d'injection de dépendances de votre application ou une factory. Cela maintient la logique de vos templates connectée au cœur de l'application tout en préservant une organisation claire.

Fonctions utilisant une classe avec attributs

Tout comme les filtres, les fonctions peuvent être définies comme des 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 sera disponible comme {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écouvrira et enregistrera automatiquement les méthodes marquées de 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)}

Fonctions contextuelles ?

Contrairement aux filtres, il n'existe pas de concept direct de “fonctions contextuelles” qui recevraient un objet similaire à FilterInfo. Les fonctions opèrent au sein d'expressions et n'ont généralement pas besoin d'un accès direct au contexte de rendu ou aux informations sur le type de contenu de la même manière que les filtres appliqués aux blocs.

version: 3.0