Chargeurs de modèles

Les chargeurs sont le mécanisme utilisé par Latte pour récupérer le code source de vos modèles. Le plus souvent, les modèles sont des fichiers stockés sur le disque, mais le système de chargeur flexible de Latte vous permet de les charger depuis pratiquement n'importe où, ou même de les générer dynamiquement.

Qu'est-ce qu'un chargeur ?

Généralement, lorsque vous travaillez avec des modèles, vous pensez à des fichiers .latte résidant dans la structure de répertoire de votre projet. Ceci est géré par le FileLoader par défaut de Latte. Cependant, la connexion entre un nom de modèle (comme 'main.latte' ou 'components/card.latte') et son contenu de code source réel n'a pas besoin d'être une correspondance directe de chemin de fichier.

C'est là qu'interviennent les chargeurs. Un chargeur est un objet chargé de prendre le nom d'un modèle (une chaîne d'identification) et de fournir à Latte son code source. Latte s'appuie entièrement sur le chargeur configuré pour cette tâche. Cela s'applique non seulement au modèle initial demandé via $latte->render('main.latte') mais aussi à tous les modèles référencés à l'intérieur en utilisant des balises comme {include ...}, {layout ...}, {embed ...}, ou {import ...}.

Pourquoi utiliser un chargeur personnalisé ?

  • Chargement à partir de sources alternatives:** Récupérer des modèles stockés dans une base de données, un cache (comme Redis ou Memcached), un système de contrôle de version (comme Git, sur la base d'un commit spécifique), ou générés dynamiquement.
  • Mettre en place des conventions de nommage personnalisées:** Vous pouvez vouloir utiliser des alias plus courts pour les modèles ou mettre en place une logique de chemin de recherche spécifique (par exemple, rechercher d'abord dans un répertoire de thème, puis revenir à un répertoire par défaut).
  • Ajouter de la sécurité ou un contrôle d'accès:** Un chargeur personnalisé pourrait vérifier les permissions de l'utilisateur avant de charger certains modèles.
  • Prétraitement:** Bien que généralement déconseillé( il est préférable d'utiliserles passes du compilateur ), un chargeur pourrait théoriquement prétraiter le contenu des modèles avant de le transmettre à Latte.

Vous configurez le chargeur pour votre instance Latte\Engine en utilisant la méthode setLoader():

$latte = new Latte\Engine;

// Utiliser le FileLoader par défaut pour les fichiers dans '/path/to/templates'
$loader = new Latte\Loaders\FileLoader('/path/to/templates');
$latte->setLoader($loader);

Un chargeur doit implémenter l'interface Latte\Loader.

Chargeurs intégrés

Latte fournit plusieurs chargeurs standard :

FileLoader

C'est le chargeur par défaut utilisé par Latte\Engine si aucun autre chargeur n'est spécifié. Il charge les modèles directement à partir du système de fichiers.

Vous pouvez éventuellement définir un répertoire racine pour restreindre l'accès :

use Latte\Loaders\FileLoader;

// L'exemple suivant ne permet de charger que les modèles se trouvant dans /var/www/html/templates
$loader = new FileLoader('/var/www/html/templates');
$latte->setLoader($loader);

// $latte->render('../../../../etc/passwd'); // Ceci lèverait une exception

// Rendre le modèle situé dans /var/www/html/templates/pages/contact.latte
$latte->render('pages/contact.latte');

Il résout les noms de modèles par rapport au modèle actuel lors de l'utilisation de balises telles que {include} ou {layout}, à moins qu'un chemin d'accès absolu ne soit indiqué.

Chargeur de chaînes

Ce chargeur récupère le contenu des modèles à partir d'un tableau associatif dont les clés sont les noms des modèles (identifiants) et les valeurs sont les chaînes du code source du modèle. Il est particulièrement utile pour les tests ou les petites applications où les modèles peuvent être stockés dans le code PHP lui-même.

use Latte\Loaders\StringLoader;

$loader = new StringLoader([
	'main.latte' => 'Hello {$name}, include is below:{include helper.latte}',
	'helper.latte' => '{var $x = 10}Included content: {$x}',
	// Ajouter d'autres modèles si nécessaire
]);

$latte->setLoader($loader);

$latte->render('main.latte', ['name' => 'World']);
// Résultats: Hello World, l'inclusion est ci-dessous:Contenu inclus: 10

Si vous n'avez besoin de rendre qu'un seul modèle directement à partir d'une chaîne sans avoir besoin d'inclure ou d'hériter d'autres modèles nommés, vous pouvez passer la chaîne directement à render() ou à renderToString() lorsque vous utilisez StringLoader sans tableau :

$loader = new StringLoader;
$latte->setLoader($loader);

$templateString = 'Hello {$name}!';
$output = $latte->renderToString($templateString, ['name' => 'Alice']);
// $output contient 'Hello Alice !

Création d'un chargeur personnalisé

Pour créer votre propre chargeur (par exemple, pour charger des modèles à partir d'une base de données, d'un cache, d'un contrôle de version ou d'une autre source), vous devez créer une classe qui implémente l'interface Latte\Loader.

Voyons ce que chaque méthode doit faire.

getContent (string $name)string

Il s'agit de la méthode principale du chargeur. Sa responsabilité est de récupérer et de renvoyer le contenu complet du code source du modèle identifié par $name (tel que transmis à $latte->render() ou renvoyé par getReferredName()).

Si le modèle ne peut être trouvé ou accédé, cette méthode doit lancer un Latte\RuntimeException.

public function getContent(string $name): string
{
	// Exemple: Récupération d'une mémoire interne hypothétique
	$content = $this->storage->read($name);
	if ($content === null) {
		throw new Latte\RuntimeException("Template '$name' cannot be loaded.");
	}
	return $content;
}

getReferredName (string $name, string $referringName)string

Cette méthode gère la résolution des noms de modèles utilisés dans des balises telles que {include}, {layout}, etc. Lorsque Latte rencontre, par exemple, {include 'partial.latte'} à l'intérieur de main.latte, il appelle cette méthode avec $name = 'partial.latte' et $referringName = 'main.latte'.

La tâche de la méthode est de résoudre $name en un identifiant canonique (par exemple, un chemin absolu, une clé de base de données unique), qui sera utilisé lors de l'appel d'autres méthodes du chargeur, sur la base du contexte fourni par $referringName.

public function getReferredName(string $name, string $referringName): string
{
	return ...;
}

getUniqueId (string $name)string

Latte utilise le cache des modèles compilés pour des raisons de performance. Chaque fichier de modèle compilé a besoin d'un nom unique dérivé de l'identifiant du modèle source. Cette méthode fournit une chaîne qui identifie de manière unique le modèle $name.

Pour les modèles basés sur des fichiers, le chemin absolu peut convenir. Pour les modèles de base de données, la combinaison d'un préfixe et de l'identifiant de la base de données est courante.

public function getUniqueId(string $name): string
{
	return ...;
}

Exemple : Chargeur de base de données simple

Cet exemple montre la structure de base d'un chargeur récupérant des modèles stockés dans une table de base de données nommée templates avec les colonnes name (identifiant unique), content et updated_at.

use Latte;

class DatabaseLoader implements Latte\Loader
{
	public function __construct(
		private \PDO $db,
	) {
	}

	public function getContent(string $name): string
	{
		$stmt = $this->db->prepare('SELECT content FROM templates WHERE name = ?');
		$stmt->execute([$name]);
		$content = $stmt->fetchColumn();
		if ($content === false) {
			throw new Latte\RuntimeException("Template '$name' not found in database.");
		}
		return $content;
	}

	// Cet exemple simple suppose que les noms des modèles ("page d'accueil", "article", etc.)
	// sont des identifiants uniques et que les modèles ne se référencent pas les uns les autres de manière relative.
	public function getReferredName(string $name, string $referringName): string
	{
		return $name;
	}

	public function getUniqueId(string $name): string
	{
		// L'utilisation d'un préfixe et du nom lui-même est unique et suffisante ici
		return 'db_' . $name;
	}
}

// Utilisation:
$pdo = new \PDO(/* connection details */);
$loader = new DatabaseLoader($pdo);
$latte->setLoader($loader);
$latte->render('homepage'); // Charge le modèle portant le nom "page d'accueil" dans la base de données.

Les chargeurs personnalisés vous donnent un contrôle total sur la provenance de vos modèles Latte, ce qui permet de les intégrer à divers systèmes de stockage et flux de travail.

version: 3.0