Framework

Moteur de templates de PHPBoost

Table des matières
La partie interface utilisateur de PHPBoost est régie par un système de templates. Le dossier présentant l'architecture technique de PHPBoost vous aidera certainement à situer cette couche et à comprendre son intérêt.

Pourquoi utiliser des templates ?



L'utilisation de fichiers templates n'est en rien obligatoire pour développer un CMS. Pourtant nous avons fait le choix d'utiliser ce principe de fonctionnement pour des raisons assez simples : PHPBoost se veut un portail entièrement personnalisable sur le plan graphique.
Il aurait été possible d'utiliser une feuille de style CSS par thème et les designs auraient pu être modifiés. Bien que ce soit le CSS qui gère la mise en forme, nous avons tout de même voulu laisser l'utilisateur pouvoir modifier la source HTML de ses pages afin notamment de déplacer les variables, ce qui n'aurait pas été possible avec du CSS. Nous avons fait le choix d'utiliser des templates, ce qui consiste à séparer complètement le PHP et le HTML. Quand on développe de façon traditionnelle le PHP permet de travailler sur le contenu des variables, mais le code HTML se trouve complètement mélangé au PHP, ce qui rend plus complexe la lecture du code. L'utilisation des templates a l'avantage de pouvoir laisser l'utilisateur modifier le code HTML de chacun de ses thèmes séparément, mais il permet en plus de clarifier le code PHP qui ne contient plus de HTML.
Rien de vaut un schéma pour comprendre comment se passe la séparation des deux parties du code.


Template signifie en français patron, à prendre dans le sens géométrique du terme. Cela correspond bien à ce qui est décrit, à savoir un dispositif de balisage pour placer les variables.

Principe de fonctionnement



Syntaxe spécifique



Le moteur de templates de PHPBoost utiliser une syntaxe qui lui est spécifique. Elle permet de symboliser des marqueurs qui seront remplacés lors du traitement par la valeur correspondante. Les paragraphes suivants permettent de détailler cette syntaxe.

Un traitement rapide



Depuis PHPBoost 3.0, le moteur de templates a subi de grosses améliorations en terme de performance. L'inteprétation des fichiers template étant assez complexe, la mise en cache permet de ne l'effectuer qu'une seule fois par fichier en sauvegardant le fichier sous sa forme interprétée (un fichier PHP). Ensuite l'affichage est très rapide car il exploite directement le moteur d'interprétation de PHP (Zend engine) qui est très performant en incluant directement le fichier PHP mis en cache.
Ainsi, l'utilisation de templates n'est pas franchement plus lourde que le mélange du HTML et du PHP dans les fichiers et procure une nettement meilleur lisibilité et maintenabilité du code source.

Utilisation du moteur de templates



Voyons maintenant comment utiliser le moteur de templates. Il est important de noter que du côté de PHP les templates sont gérés par la classe Template dont la documentation est ici.

Chargement d'un fichier



Pour charger un fichier template, il suffit d'instancier un objet Template en lui indiquant le chemin du fichier.
Exemple :
Code PHP :
$tpl = new Template('mymodule/file.tpl');

Cela chargera le fichier file.tpl du dossier templates de votre module.

Traitement d'un fichier



Il existe deux modes de traitement du fichier. Par défaut, le traitement aura pour effet d'écrire sur la sortie standard (donc ce qui sera envoyé au client) le résultat, mais il est également possible de récupérer le résultat sous forme de chaîne plutôt que de l'afficher. Le traitement se fait via la méthode parse() de la classe Template.
Exemple :
Code PHP :
//Écrit sur la sortie standard le résultat de l'interprétation du fichier
$tpl->parse();
//Renvoie le résultat de l'interprétation du fichier et le place dans $result
$result = $tpl->parse(TEMPLATE_STRING_MODE);


Variables simples



Les variables simples permettent de placer du contenu dans un fichier template.
Côté fichier template, il faut placer le nom de la variable entre accolades. Ainsi,
{NOM_DE_LA_VARIABLE}
sera remplacé par la valeur de NOM_DE_LA_VARIABLE.
Côté PHP, l'assignation d'une variable se fait via la méthode assign_vars().

L'exemple suivant montre l'utilisation de variables simples.

Fichier template :
Code TPL :
<p>{HELLO_WORLD}</p>

L'assignation dans le fichier PHP :
Code PHP :
$tpl->assign_vars(array('HELLO_WORLD' => 'Hello world!'));

Le résultat de l'interprétation donne ceci :
Code HTML :
<p>Hello world!</p>


Les boucles



Définition de boucles



Les boucles permettent de répéter une partie de code dans le template. Pour définir une boucle il faut respecter la syntaxe suivante.
Code TPL :
# START boucle # 
Code répété dans la boucle
# END boucle #


Les boucles peuvent être imbriquées. Pour définir une boucle imbriquée il faut respecter la syntaxe suivante.
Code TPL :
# START boucle1 # 
Code répété dans la boucle 1
# START boucle1.boucle2 # 
Code répété dans la boucle 2
# END boucle1.boucle2 #
# END boucle1 #


Les variables dans les boucles



Les variables dans les boucles doivent être préfixées par la liste des boucles par lesquelles elles ont été assignées, séparées par des points.
Code TPL :
# START boucle1 # 
Code répété dans la boucle 1 {boucle1.VARBOUCLE_1}
# START boucle1.boucle2 # 
Code répété dans la boucle 2 {boucle1.boucle2.VARBOUCLE_2}
        Variable de la boucle 1 affichée dans la boucle  2 : {boucle1.VARBOUCLE_1}
# END boucle1.boucle2 #
# END boucle1 #


L'assignation de boucles



Côté PHP, il faut utiliser la méthode assign_block_vars().
Prenons la boucle simple suivante :
Code TPL :
Je compte jusqu'à 3
# START boucle # 
Et {boucle.NOMBRE}
# END boucle #
Et voilà !

L'assignation correspondante sera la suivante :
Code PHP :
for ($i = 1; $i <= 3; $i++)
{
    //On assigne une itération de la boucle 'boucle' avec la variable NOMBRE
    $tpl->assign_block_vars('boucle', array('NOMBRE', $i));
}

L'interprétation de ce template donnera
Code TXT :
Je compte jusqu'à 3
Et 1
Et 2
Et 3
Et voilà !


Prenons un second exemple avec une boucle imbriquée :
Code TPL :
Classification des sports
# START categorie_sport #
   Catégorie :  {categorie_sport.NOM_CATEGORIE}
    # START categorie_sport.sport #
        Le {categorie_sport.sport.NOM_SPORT} est un {categorie_sport.NOM_CATEGORIE}
    # END categorie_sport.sport #
# END categorie_sport #

Le code PHP correspondant pourrait être :
Code PHP :
//Sports collectifs
$tpl->assign_block_vars('categorie_sport', array('NOM_CATEGORIE' => 'Sport collectif'));
//Exemples de sports collectifs
$tpl->assign_block_vars('categorie_sport.sport', array('NOM_SPORT' => 'football'));
$tpl->assign_block_vars('categorie_sport.sport', array('NOM_SPORT' => 'handball'));
$tpl->assign_block_vars('categorie_sport.sport', array('NOM_SPORT' => 'rugby'));
//Des sports de glisse
$tpl->assign_block_vars('categorie_sport', array('NOM_CATEGORIE' => 'Sport de glisse'));
//Exemples de sports de glisse
$tpl->assign_block_vars('categorie_sport.sport', array('NOM_SPORT' => 'ski'));
$tpl->assign_block_vars('categorie_sport.sport', array('NOM_SPORT' => 'snowboard'));
$tpl->assign_block_vars('categorie_sport.sport', array('NOM_SPORT' => 'surf'));


L'exécution de ce code donnerait alors :
Code TEXT :
Classification des sports
    Catégorie :  Sport collectif
        Le football est un Sport collectif
        Le handball est un Sport collectif
        Le rugby est un Sport collectif
    Catégorie :  Sport de glisse
        Le ski est un Sport de glisse
        Le snowboard est un Sport de glisse
        Le surf un Sport de glisse


Les conditions



Bien que les conditions puissent être gérées par des boucles (une boucle assignée 0 ou 1 fois est une condition), il existe également la possibilité de définir des conditions dans les templates. Pour cela, il suffit d'assigner des variables dont les valeurs sont booléennes. Par convention, on les préfixe par C_.
Voici un exemple
Code TPL :
# IF C_HOMME # 
Vous êtes un homme.
# ELSE #
Vous êtes une femme.
# ENDIF #

Code PHP :
$tpl->assign_vars(array('C_HOMME' => true));

Le code PHP ci-dessus génèrerait
Code TEXT :
Vous êtes un homme.


On peut également faire des variables dans des boucles, en voici un exemple.
Code TPL :
voici une liste de sports
# START sport #
    {sport.NOM}
    # IF sport.C_COLLECTIF #
    Attention, ce sport est un sport collectif, il faudra trouver une équipe de {sport.NOMBRE_JOUEURS} pour le pratiquer !
    # ENDIF #
# END sport #


Code PHP :
//On crée les itérations correspondantes
$tpl->assign_block_vars('sport', array(
    'NOM' => 'Football',
    'C_COLLECTIF' => true,
    'NOMBRE_JOUEURS' => 11
));
//Les deux sports suivants ne sont pas collectifs.
//On n'est pas obligé de définir la variable NOMBRE_JOUEURS
$tpl->assign_block_vars('sport', array(
    'NOM' => 'Cyclisme',
    'C_COLLECTIF' => false
));
$tpl->assign_block_vars('sport', array(
    'NOM' => 'Course à pied',
    'C_COLLECTIF' => false,
    'NOMBRE_JOUEURS' => ''
));


Vous avez compris que l'exemple donnerait :
Code TEXT :
Football
Attention, ce sport est un sport collectif, il faudra trouver une équipe de 11 pour le pratiquer !
Cyclisme
Course à pied


Les inclusions



Sur PHPBoost 3.1, il est possible d'inclure à un endroit d'un template le résultat de l'interprétation d'un autre template. sur PHPBoost 3.0, c'est aussi possible, mais la façon de le faire est largement dépréciée et nous n'expliquons donc pas comment le faire, il est cependant assez simple de contourner le problème, nous allons le voir dans l'exemple.
Voyons donc cela sur un exemple.
fichier1.tpl :
Code TPL :
Un hello world inclus d'un autre template :
# INCLUDE  hello_world #

fichier2.tpl :
Code TPL :
Bonjour tout le monde !

Côté PHP, nous avons :
Code PHP :
$tpl1 = new Template('fichier1.tpl');
$tpl2 = new Template('fichier2.tpl');
$tpl1->add_subtemplate('hello_world', $tpl2);
//Exécutons le tout ($tpl2 sera également interprété)
$tpl1->parse();

Cela donne :
Code TXT :
Un hello world inclus d'un autre template :
Bonjour tout le monde !


A noter que c'est strictement équivalent à remplacer
# INCLUDE  hello_world #
par
{HELLO_WORLD}
et à assigner
Code PHP :
$tpl1->assign_vars(array('HELLO_WORLD' => $tpl2->parse(TEMPLATE_STRING_MODE);


Emplacement des templates



Templates des modules



Pour charger un fichier, il faut utiliser le constructeur de la classe Template en utilisant un chemin de la forme suivante : mymodule/file.tpl. Cela aura pour effet de charger le fichier file.tpl de votre module se trouvant dans le dossier /mymodule/templates/.

Mais lors de la création d'un nouveau thème, il est possible qu'un template soit redéfini. Dans ce cas-là, il se trouvera dans /templates/mytheme/modules/mymodule/file.tpl. En fait, si ce dernier existe, il sera choisi en priorité, sinon celui par défaut du module sera utilisé (celui présent dans /mymodule/templates/file.tpl).

Cela a pour effet notamment que l'emplacement du thème change. Si celui-ci utilise des images qui sont également redéfinies, leur chemin ne sera pas le même que dans le thème par défaut. Pour cela, le moteur permet de connaitre où se situent les images. Dans la version 3.0 de PHPBoost, cette information est disponible avec la méthode Template::get_module_data_path(string $module) alors que pour PHPBoost 3.0, une variable template (
{PICTURES_DATA_PATH}
) est automatiquement assignée pour cela.
Il est à noter que si une image est redéfinie, elles doivent toutes l'être car la vérification n'est pas faire au cas par cas.

Templates du framework



Il est possible de redéfinir les templates du framework. Pour cela, il suffit de le redéfinir dans le dossier /templates/mytheme/framework/ en recréant l'arborescence depuis là comme par exemple /templates/mytheme/framework/menus/content/display.tpl. Toutes les pages utilisant ce thème utiliseront alors ce template plutôt que celui par défaut (dans le répertoire /templates/default/).

Il est aussi possible de redéfinir le comportement du framework au sein d'un module. Pour cela, il faut redéfinir dans l'arborescence template du module le template en recréant son arborescence. Par exemple /mymodule/templates/framework/menus/content/display.tpl sera utilisé en priorité si il existe. On peut même redéfinir l'utilisation d'un template du framework dans un module pour un thème en le plaçant ici : /templates/mytheme/modules/mymodule/framework/menus/content/display.tpl

En résumé, voici les endroits où le moteur de templates va charger le template (si un il n'est pas trouvé à un emplacement il passe au suivant, jusqu'au dernier qui existe forcément) avec le chargement suivant :
Code PHP :
$tpl = new Template('framework/menus/content/display.tpl');

  • /templates/mytheme/modules/mymodule/framework/menus/content/display.tpl
  • /mymodule/templates/framework/menus/content/display.tpl
  • /templates/mytheme/framework/menus/content/display.tpl
  • /templates/default/framework/menus/content/display.tpl (celui-ci existera quoi qu'il arrive)


Il est donc absolument possible de redéfinir l'apparence du framework et son comportement au sein même d'un module sans affecter les autres. Les possibilités de personnalisation du moteur de template permettent de spécialiser modules et thèmes de façon à pouvoir faire ce que l'on souhaite.
Cette page a été vue 2506 fois