Cet page décrit brièvement les gabarits de la PHPLIB et leur usage en général. Il s'agît de notes que j'ai prises lorsque je les
ai utilisées. Je discute aussi la façon dont je les utilise dans mes pages Web ainsi que d'une limitation que j'ai observée.
Lorsque j'ai commencé à programmer pour le Web, j'ai utilisé les éditeurs Multi-Edit et FrontPage pour coder et rédiger pages Web où le code PHP, les balises HTML et la rédaction du texte étaient entremêlés à l'intérieur d'un même fichier portant l'extension .php et qui devenait très difficile à lire ou à éditer.
Ma solution à ce problème a été la séparation du code PHP du code HTML au moyen de gabarits. Avec ces gabarits, le code PHP se retrouve dans un fichier est complètement séparé de la mise en page et du code HTML qui se retrouve dans un autre fichier comme illustré à la Figure 1. De cette façon, deux fichiers portant le même nom sont nécessaires:
- un fichier PHP contenant le script PHP qui effectue le travail de récupération et de traitement des données; et  Â
- un fichier de mise en page HTML contenant les balises, des blocs et des champs de remplacement où seront insérées les données générées par le script.
L'avantage évident est de pouvoir travailler uniquement sur la mise en page, sans modifier quoi que ce soit dans le code php et inversement, ou de diviser efficacement le travail à faire: le programmeur s'occupant uniquement de la partie scripting, et le rédacteur, de la mise en page.
Il existe de nombreux moteurs de gabarits disponibles pour le PHP. J'ai effectué quelques recherches et j'ai trouvé la bibliothèque PHPLIB qui, dans mon cas, était déjà utilisée pour les menus PHPLayersMenu 3.2.0 utilisés sur mon site. Sans aller beaucoup plus loin dans mes recherches, je l'ai choisie pour mon site.Â
La PHPLIB
La bibliothèque PHPLIB est un ensemble de classes qui complète les fonctionnalités du langage PHP. Elle comporte plusieurs classes:
- La classe "DB_Sql" permet de gérer les connexions à la base de données. Elle apporte un lot de fonctions dédiées au maniement des données. Plusieurs autres classes de la Phplib se reposent sur elle.
- Le rôle de la classe "Session" est évident, elle nécessite l'utilisation de la classe "DB_Sql".
- La classe "Auth" est utilisée pour authentifier un utilisateur propre à une session.
- La classe "Perm" ajoute la dimension de "droits" sur une session authentifiée. En toute logique cette classe se repose sur "Auth", "Session" et "DB_Sql".
- Cart" permet de gérer un panier électronique, nécessite la classe "Session" pour fonctionner.
- Toutes les classes ne sont cependant pas interdépendantes les unes des autres : "Menu" est une classe indépendante permettant la génération de menus de navigation.
- La classe "Template" est celle qui nous intéresse ici et nous allons la développer.Â
Notons que la classe Template comme la classe Menu peut être utilisée indépendamment des autres classes de la bibliothèque. C'est ce que nous faisons ici.
Gabarits de la PHPLIB
La classe Template permet de séparer le code HTML dans un fichier externe (gabarit) qui est complètement exempt de code PHP mais contient toutefois des champs de remplacement ou des blocs qui peuvent être remplacés par des chaînes de caractères  de longueur arbitraire. Son utilisation est relativement simple. Pour chaque page, on doit définir deux fichiers, l'un avec l'extension .php qui contient le code PHP et l'autre avec l'extension .html (ça pourrait être n'importe quelle extension) qui sert de gabarit et qui exclut tout code PHP (qui, de toute façon ne s'exécuterait pas).
Voici une utilisation typique des gabarits de la PHPLIB:
include "template.inc"; // inclusion du code source template.inc
$tpl = new Template(); // création de l'objet Template
$tpl->set_file('main', 'xxx.html'); // définit le gabarit à utiliser
$abc = 'quelque chose';
$tpl->set_var('ABC', $abc); // définit la variable ABC
...
$tpl->pparse('out', 'main'); // transmet le gabarit au fureteur
Comme on le voit dans le code qui précède, les étapes suivantes ont été suivies:
- Inclusion du code source de template.inc qui contient le code source de la classe Template;. Dans le cas où le fichier ne se trouve pas dans le même répertoire que le fichier .php, il faut inclure le parcours menant à "template.inc".
- Comme cette classe est orientée-objet, on crée ensuite l'objet Template. Cet appel exécute le constructeur de la classe qui initialise les variables-membres $Root définissant la racine la racine du gabarit et $unknowns définissant le traitement des variables non définies. Une fois que la classe Template est instanciée;
- Il faut maintenant déterminer le nom du gabarits qui sera utilisés. C'est le rôle de la méthode set_file(), où, dans le cas présent, le fichier gabarit xxx.html  qui contient le texte et les balises HTML se retrouve dans le même répertoire que le fichier .php appelant;
- L'énoncé suivant assigne à la variable $abc la valeur 'quelque chose' et cette variable est associée au champ de remplacement ABC au moyen de la méthode set_var(). De cette manière, on attribue dynamiquement à chaque  champ de remplacement du gabarit la valeur de la variable gabarit ABC; et
- Finalement, l'exécution de la méthode pparse() transmet le gabarit ainsi formé au fureteur.
Considérons maintenant le détail de la syntaxe de chacune de ces méthodes:
- set_file(string $varname, string $filename) -  Cette méthode utilise deux arguments et définit un fichier appelé $filename qui constitue la valeur initiale de la variable $varname. Le fichier n'est pas chargé avant que ça soit nécessaire.
- set_var($varname, $value = "", $append = false) - Cette méthode définit la valeur d'une variable.Â
- parse(string $target, string $varname, [boolean $append]) - Cette méthode substitue les valeurs de toutes les variables dans la variable appelés $varname et les assigne ou les ajoute à la variable $target.Â
- pparse(string $target, string $varname, [boolean $append]) - Le nom de cette méthode est un diminutif pour print $this->parse(...).
La définition d'une variable dans le fichier gabarit au moyen des accolades { ... } ne sera interprété comme champ de remplacement que si le texte entre les accolades ne contient pas d'espace. Par exemple, l'expression sera reconnu comme un champ de remplacement où TEXTE sera remplacé par la valeur qui lui est assigné par la méthode set_var() ou complètement supprimé s'il n'est pas défini alors que l'expression {LE TEXTE} contenant un espace sera reconnu comme littéral et reproduit tel quel par le fureteur.Â
Dans ce qui précède, j'ai dû définir comme suit
$tpl->set_var('TEXTE', '{TEXTE}');
dans le fichier .php pour qu'il apparaisse correctement dans cette page.
Utilisation des blocs
La classe Template de la PHPLIB devient beaucoup plus intéressante lorsqu'on y introduit le concept des blocs. Pour les utiliser, les étapes suivantes sont nécessaires:
- dans le gabarit, on définit un bloc en utilisant les balises suivantes:
-
... <!--BEGIN bloc--> «contenu du bloc» <!--END bloc--> ...
- dans le code PHP, on utilise la syntaxe suivante:
-
include "template.inc"; // inclusion du code source template.inc $tpl = new Template(); // création de l'objet Template $tpl->set_file('main', 'xxx.html'); // définit le gabarit à utiliser $abc = 'quelque chose'; $tpl->set_var('ABC', $abc); // définit la variable ABC ... $tpl->set_block('main', 'bloc', 'bloc_parsed'); ... ... «traitement du bloc»
...
$tpl->parse('bloc_parsed', 'bloc', true); ... ... $tpl->pparse('out', 'main'); // transmet le gabarit au fureteur
Quelle est la signification de tout cela? Lorsque dans le code PHP, on utilise la méthode set_block(), tout le contenu du bloc situé entre les balises <!-- BEGIN bloc --> et <!-- END bloc --> dans le code du gabarit est retiré du gabarit et placé dans la variable bloc. Après le traitement du bloc, l'appel à la méthode parse() place le résultat du traitement du bloc dans la variable bloc_parsed.  Lors de l'appel à la méthode pparse(),  le gabarit complet, incluant le bloc, est transmis au fureteur.
La définition du bloc s'effectue à l'aide de la méthode set_block(string $parent, string $varname, [string $name = ""]) où
- $parent - est une chaîne de caractères contenant le nom du gabarit parent;
- $varname - est une chaîne de caractères contenant le nom du bloc à extraire du gabarit parent;
- $name - (facultatif) est une chaîne de caractères contenant le nom de la variable dans laquelle le bloc est stocké.
Blocs imbriqués
Les blocs peuvent être imbriqués mais on doit extraire les blocs en commençant par les blocs internes. Le code qui suit donne les instructions du code PHP pour la réalisation d'une liste de chapitres et de sections dans un livre.
Fichier PHP - Test.php
Le fichier Test.php doit être appelé. Il crée l'objet Template et définit le fichier Test.html comme gabarit. Deux blocs imbriqués sont ensuite définis (le bloc interne doit être défini avant le bloc externe) et effectue ensuite les boucles du programme.
include("template.inc"); // inclusion du fichier template.inc
$tpl = new Template(); // création de l'objet Template
$tpl-> set_file ('tp', 'Test3.html'); // définition du fichier gabarit
$tpl-> set_block('tp', 'sect', 'sect_parsed'); // définition du bloc interne
$tpl-> set_block('tp', 'chapt', 'chapt_parsed'); // définition du bloc externe
for ($i = 1 $i < 3; $i++) // boucle externe
{
$tpl->set_var('sect_parsed', ''); // vider le contenant sect_parsed
for ($j = 1; $j < 6; $j++) // boucle interne
{
$tpl->set_var('J', $j); // la valeur de $j est assignée à J
$tpl->parse('sect_parsed', 'sect', true); // on ajoute le résultat du bloc au contenant sect_parsed
}
$tpl->set_var('I', $i); // la valeur de $i est assignée à J
// on ajoute le résultat du bloc externe au contenant chapt_parsed
$tpl->parse('chapt_parsed', 'chapt', true);
}
$tpl->pparse('out', 'tp'); // le gabarit complet est transmis au fureteur
Lors de l'exécution de la boucle externe, le contenant sect_parse est vidé puis et ensuite empli lors de l'exécution de la boucle interne. Ce
contenant est ensuite
Fichier gabarit -Test.html
Le code qui suit donne le fichier gabarit:
<h1&Test&/h1>;
<!-- BEGIN chapt -->
<h2>Chapître {I}</h2>
<!-- BEGIN sect -->
<h3>Section {J}</h3>
<!-- END sect -->
<!-- END chapt -->
Lors de l'exécution du fichier .php, les valeurs de $i et $j sont insérées dans les champs de remplacement {I} et {J} du fichier gabarit lors de la transmission du gabarit au fureteur.
Discussion
Presque toutes mes pages Web utilisent les gabarits de la PHPLIB. En fait, mon squelette de page .html est le suivant:
<body>
<!-- BEGIN texte -->
<div> class=">title">Blank</div>
<>p>...</p>
<!-- END texte -->
</body>
mais lorsque je sauvegarde le fichier avec nVu, HTML Tidy modifie le contenu afin d'en faire du HTML correct. Il ajoute une entête et un bas de page avec les balises requises pour optimiser le code HTML, avec le résultat suivant:
<!DOCTYPE html">
<html lang="fr-ca">
<head>
<title></title>
</head>
<body>
<!-- BEGIN texte -->
<div class="title">Blank</div>
<p>...</p>
<!-- END texte -->
</body>
</html>
La seule raison pour laquelle j'utilise le bloc "texte" est d'éliminer ces entêtes et bas de page du rendu de la page.
À quelques exceptions près, cette façon de faire fonctionne bien mais il y a des exceptions. Je me suis aperçu que template.inc génère des erreurs lorsque la dimension d'un bloc dépasse une certaine limite. Ce problème est relié à l'usage de la fonction PHP preg_match_all() dans la méthode set_block(). En effet, preg_match_all() semble avoir une limitation sur la dimension de la chaîne utilisée. Cette limite est de 65539 octets.
Conclusion
En utilisant les gabarits, je suis maintenant capable d'utiliser l'éditeur Multi-Edit 2006 pour éditer le code PHP et l'éditeur N|vu pour la rédaction et la mise en page. La caractéristique de N!vu (soutenu par HTML Tidy) qui consiste à optimiser le code HTML afin de le rendre conforme avec les règles du W3C et de le rendre plus facilement lisible en l'indentant et en le nettoyant, ne modifie plus le formattage du code PHP.
[Nouveau]Â Cette remarque ne tient plus aujourd'hui puisque j'ai cessé d'utiliser Nvu et que j'utilise maintenant Dreamweaver pour éditer le code et la rédaction de mes page Web.
Dans ce qui précède, j'ai rédigé le plus proprement possible les notes que j'ai prises lorsque j'ai voulu utiliser les gabarits sur mon site. Il ne s'agit pas là d'un traitement en profondeur du sujet mais j'espère que ce texte pourra aider quelqu'un. Afin d'aider toute personne voulant en savoir plus, j'ai inclus quelques références intéressantes.
Références
- "Découverte des principaux moteurs de templates en PHP" par Guillaure Rossolini;
- "Templates, the PHPLIB way" par David Orr;