Hyla_Tpl : Un nouveau moteur de template, successeur de celui de la phpLib
Introduction
Pour les besoins de la nouvelle version du gestionnaire de fichiers en ligne Hyla, j'ai cherché des solutions pour remplacer le veillissant moteur de template (de gabarit ou de modèle en bon français) de la PhpLib qui lui à rendu, tout de même, de bons services et ce, depuis les toutes premières version de Hyla...
Le moteur de la PhpLib dispose de nombreux avantages, simplicité des modèles : pas de code (foreach, if, etc...) respectant ainsi la logique qui veut que les graphistes ne touchent pas une brindille de code, les blocs sont en fait des commentaires, ils apparaissent donc cachés aux graphistes travaillant sur le modèle.
Mais ce moteur de template souffre de 2 grosses lacunes :
- Sa complexité de mise en oeuvre du côté php, on arrive très vite à du code relativement lourd : il est très verbeux.
- Plus aucun support depuis bien longtemps, il lui manque donc des fonctionnalités qui sont, pourtant, devenues courantes.
Mais pourquoi réécrire un nouveau moteur de modèle alors qu'il en existe beaucoup qui fonctionnent parfaitement bien ?
- Je souhaite garder un maximum de compatibilité avec les modèles existants déjà dans Hyla
- Aucun des moteurs de gabarits que j'ai vu ne me convient, en général, ils sont beaucoup trop lourd pour ce qu'Hyla en fera.
En gros, garder la simplicité de la vue avec quelques nouveautés et améliorer le contrôleur.
Les modèles
Nouveautés pour les variables
Pour le moteur de modèle de la phpLib, tout ce qui est entre 2 accolades (avec des caractères valides) est une variable, ainsi, {TOTO} et {ma_variable} sont des variables, Hyla apporte une petite différence, ainsi, est considéré comme variable tout ce qui est entre accolades et commence par un caractère dollar $ : « » et « » sont des variables mais ce n'est pas tout, Hyla apporte 5 nouveaux concepts au sujet des variables :
1. Tableaux et objets dans les variables
Il est possible de spécifier des tableaux ou des objets aux variables depuis le code php à l'aide de la fonction setVar, on y accède dans le gabarit de la manière suivante : « », on accède au contenu des tableaux et des objets de la même manière (avec le point : .) cachant ainsi l'implémentation à la vue.
Exemple :
Code php :
$user = array('name' => 'leonardo', 'age' => 67);
$tpl->setVar('user', $user);
Dans le gabarit :
<strong></strong>
<em></em>
2. Les fonctions appliquées aux variables
Avant affichage de la variable dans le modèle, il est possible d'envoyer son contenu dans des fonctions.
Exemple :
Dans le gabarit :
<strong></strong>
Dans l'exemple ci-dessous, le contenu de la variable sera envoyé à la fonction toupper qui se chargera de mettre tous les caractères en majuscules.
3. Les fonctions simples
Un autre type de variable permet d'appeler une fonction directement, son utilisation est simple : « », exemple : « » inclura le fichier nommé fichier.tpl à la place du bloc lui même, voilà, c'est aussi simple que cela...
4. La traduction
Les variables à traduire sous la forme « i speak english » (commençant par un _). Hyla récuperera le contenu de la variable (« i speak english ») et l'enverra à une fonction définie afin de procéder à une traduction : « i speak english » sera ainsi remplacée par « je parle français » , il est même possible de cumuler la traduction et les fonctions, ainsi, l'exemple suivant « i speak english|trim|toupper » retournera « JE PARLE FRANÇAIS »
5. Les commentaires
Il est possible de placer des commentaires dans les gabarits cette manière : « ».
Pourquoi ce nommage ? J'ai essayé de rester logique, le « $ » utilisé pour les variables dans bash ou encore php, le « _ » fait référence à la fonction gettext permettant la localisation d'applications, le « ! » qui ordonne l'exécution d'une fonction et enfin le « # » utilisé dans beaucoup de langage pour indiquer que la ligne courante est un commentaire.
Nouveautés pour les blocs
Concernant les blocs, une grosse nouveauté fait son apparition : le bloc ELSE qui sera affiché uniquement si le bloc du même nom ne s'affiche pas.
Le gros avantage d'utiliser les blocs ELSE est que vous gagnez en lisibilité dans le code car justement, il y a moins de code...
Le reste étant compatible avec les anciens modèles de la phpLib, un exemple vaut mieux que ...blablabla, voici :
<table>
<tr>
<td>Name</td>
</tr>
<!-- BEGIN line -->
<tr>
<td>>/td>
</tr>
<!-- ELSE line -->
<tr>
<td>No data !</td>
</tr>
<!-- END line -->
</table>
Comme vous le voyez, le principe des blocs est le même :
- Le bloc line possède un bloc ELSE : si line n'est pas appelé, le contenu du bloc else sera alors affiché
- Le contenu de la variable $user sera remplacée par le retour à l'appel de la fonction ucfirst (il est possible de mettre autant de fonction que l'on veut, ex: « ) »
- « No data ! » sera remplacé par « Pas de données ! »
- Le contenu du fichier toto.tpl sera ajouté à la fin du modèle
Bien entendu, il est possible d'imbriquer une multitudes de blocs les uns dans les autres...
Il est possible de travailler simultanémnent avec plusieurs fichiers de gabarits, de plusieurs manières :
- Un appel à setCurrentFile permet de spécifier le fichier gabarit courant, notez que le dernier fichier déclaré grâce à la méthode importFile est désigné fichier courant
- Utilisez la syntaxe suivante : « identifiant_du_fichier:nom_du_bloc » dans l'appel à la méthode render
Côté php
Et voici ce que cela donne du côté du code php :
<?php
require 'tpl.class.php';
$t = new Tpl();
$t->importFile('tata.tpl');
$data = array('pif', 'paf', 'pouf');
foreach ($data as $name) {
$t->setVar('user', $name);
$t->render('line');
}
echo $t->render();
?>
Vous remarquerez qu'il n'est pas utile de déclarer à l'avance les blocs et c'est une très bonne chose, on gagne entre autre en simplicité !
Et les performances ?
C'est bien gentil de rajouter toutes ces fonctionnalités mais si c'est pour que ce soit plus lent que l'original, c'est pas terrible...
Ce nouveau moteur est plus de 10 fois plus rapide que celui de la phpLib (ce dernier étant considéré comme le plus rapide des moteurs « non compilés ») et jusqu'à 20 fois plus rapide en utilisant les spécificités du nouveau moteur (notamment les fonctions).
Le pic d'occupation mémoire est moindre à rendu final identique.
Vous êtes donc gagnant sur toute la ligne en utilisant ce nouveau moteur de modèle si vous utilisez celui de la PhpLib.
API
Le constructeur n'attends qu'un paramètre qui est le dossier oû sont stockés les gabarits, par défaut, c'est le dossier courant.
Voici les méthodes publiques, classées par catégories avec la liste des arguments qu'elles contiennent.
Gestion des fichiers
- importFile : Importe un fichier de modèles
- Id du fichier
- Nom du fichier
- Le chemin du fichier si il n'est pas inclu dans le chemin défini dans le constructeur
- setCurrentFile : Si vous travaillez avec plusieurs modèles, il peut être utile de spécifier celui courant
- Le nouveau fichier courant
Gestion des variables
- setVar : Déclare le contenu d'une variable
- Le nom de la variable
- La valeur de la variable
- setVars : Déclare le contenu de plusieurs variables à l'aide d'un tableau
- Tableau de variable sous la forme : array('var1' => 'value1', 'var2' => 'value2')
- removeUnknowVar : Spécifie si vous désirez voir les variables sans valeur du modèles s'afficher ou non
- true ou false
Gestion des blocs
- render : Procède au rendu d'un bloc et retourne ce dernier
- Le nom du bloc voulu
- Tableau de variable (attention, paramètre peut être amené à disparaitre dans les futures version)
Gestion des fonctions
- registerFunction : Ajoute une fonction utilisateur
- Le nom de la fonction qui sera utilisé dans le modèle
- Le nom de la fonction
- getFunctionList : Renvoie la liste des fontions
- Si true, renvoie également la liste des fonctions utilisateurs (créées avec registerFunction)
Divers
- setL10nCallback : Spécifie la fonction à appeler à chaque fois que le moteur trouve une variable du type XXX
- Spécifie la fonction de callback pour la traduction
Téléchargement
Le code source est bien sûr libre et est sous license GPL.
Pour le téléchargement, téléchargez l'annexe de ce billet, il inclu la classe Hyla_Tpl, une version autonome (standalone si vous préférez, c'est à dire indépendante de Hyla, le gestionnaire de fichiers) ainsi qu'un fichier php et ces gabarits d'exemples.
Attention, cliquez sur le lien suivant pour télécharger la toute dernière version de Hyla_Tpl.