Un moteur de template efficace : PHP
Introduction
N'oubliez pas que PHP est au départ un moteur de templates pour Perl. Aujourd'hui on a réalisè des surcouches ce qui d'un point de vue historique est une hérésie (et ce n'est pas Rasmus qui me contredira, je vous assure…).
Que ce soit clair, l'usage d'un moteur de template en tant que surcouche PHP (tel que Smarty, PHPLib, etc…) a deux avantages :
Le premier point est indéniable, sauf qu'il est vrai aussi si on n'utilise que PHP pour peu qu'on suive de bonnes pratiques. Le second a un intérêt très discutable : franchement vos templates vous les utilisez pour plusieurs sites réalisés dans plusieurs langages ? De plus je n'ai pas connaissance d'un moteur de template implémentè dans plusieurs langages, et tombe donc a l'eau de fait.
Par contre, l'ajout d'une surcouche implique forcément une perte notable de performances.
Alors pourquoi ne pas utiliser PHP en tant que tel ?
Je vous présente donc le plus petit moteur de template en PHP implémentant :
Le code
La syntaxe des templates
Variable :
Boucle :
Condition :
Appel de fonction :
Utilisation du moteur
Instanciation :
Ajout d'une variable :
Utilisation en mode output_buffering :
Dans ce mode, la variable “contents” sera automatiquement définie par la valeur du buffer au moment de l'appel a display().
Utilisation en mode normal :
Dans ce mode la variable “contents” sera automatiquement définie a la valeur du paramètre.
Exemple
Fichier template :
Utilisation en mode output_buffering :
Utilisation équivalente en mode direct :
Resultat :
Conclusion
Vous allez me dire : “mais c'est que du php ton truc ?”.
Ben oui… PHP offre tous les outils nécessaires pour séparer la présentation du code de façon efficace, et lisible. Pour cela il suffit d'utiliser les syntaxes abrégées (attention aux prologues XML avec les short_tags), et d'avoir de bonnes habitudes. La définition d'une classe simple pour “cadrer” un peu cette utilisation est une bonne habitude car elle restreint les variables accessibles a celle que l'on a définies (pas de vilaines globales). On ne souffre aucune perte de performance, et il suffit de créer une classe fille pour ajouter des fonctionnalités (typiquement : mise en cache, compression gzip).
Note : Depuis PHP 5 & >, par mesure de sécurité, les short_tags sont désactivés par défaut. Pensez donc soit à les activer, soit à utiliser le code :
au lieu du code :
Certes, c'est moins confortable mais que voulez vous
Composé par naholyr
— Adrien Giboire (adrien.giboire@gmail.com) 2008/02/17 09:17 - Ajout de la note & mise à jour PHP 5 en doublon du code PHP 4
proposition de niahoo
Voici ma propre implémentation du moteur de template.
Le fichier de template est passé lors de l'exécution et non lors de l'instanciation et le résultat est retourné sous forme de chaîne plutôt que d'être affiché directement.
Introduction
N'oubliez pas que PHP est au départ un moteur de templates pour Perl. Aujourd'hui on a réalisè des surcouches ce qui d'un point de vue historique est une hérésie (et ce n'est pas Rasmus qui me contredira, je vous assure…).
Que ce soit clair, l'usage d'un moteur de template en tant que surcouche PHP (tel que Smarty, PHPLib, etc…) a deux avantages :
- séparation du code et de la présentation.
- possibilité de passer d'un langage à un autre pour peu que le moteur soit implémentè dans les deux langages (par exemple s'il existe une version de Smarty pour Perl, on peut donc utiliser un template Smarty dans un script Perl).
Le premier point est indéniable, sauf qu'il est vrai aussi si on n'utilise que PHP pour peu qu'on suive de bonnes pratiques. Le second a un intérêt très discutable : franchement vos templates vous les utilisez pour plusieurs sites réalisés dans plusieurs langages ? De plus je n'ai pas connaissance d'un moteur de template implémentè dans plusieurs langages, et tombe donc a l'eau de fait.
Par contre, l'ajout d'une surcouche implique forcément une perte notable de performances.
Alors pourquoi ne pas utiliser PHP en tant que tel ?
Je vous présente donc le plus petit moteur de template en PHP implémentant :
- appels de fonctions
- affichage de variables
- blocs conditionnels
- boucles
Le code
class Template
{
var $file;
var $vars = array();
function Template($tpl) {
$this->file = $tpl;
}
function start() {
ob_start();
}
function set($var, $val) {
$this->vars[$var] = $val;
}
function display($contents = null) {
extract($this->vars);
if ($contents === null) {
$contents = ob_get_contents();
ob_end_clean();
}
include $this->file;
}
}
class Template
{
private $_file;
private $_vars = array();
public function __construct($tpl) {
$this->_file = $tpl;
}
public function start() {
ob_start();
}
public function set($var, $val) {
$this->_vars[$var] = $val;
}
public function display($contents = null) {
extract($this->_vars);
if ($contents === null) {
$contents = ob_get_contents();
ob_end_clean();
}
include $this->_file;
}
}
La syntaxe des templates
Variable :
<?=$variable?>
Boucle :
<?foreach($tableau as $element):?> ... <?endforeach?>
Condition :
<?if($condition):?> ... <?endif?>
Appel de fonction :
<?fonction(parametres)?>
Utilisation du moteur
Instanciation :
$template =& new Template("Fichier Template");
$template = new Template("Fichier Template");
Ajout d'une variable :
$template->set("nom", valeur);
Utilisation en mode output_buffering :
$template->start();
...
$template->display();
Dans ce mode, la variable “contents” sera automatiquement définie par la valeur du buffer au moment de l'appel a display().
Utilisation en mode normal :
$template->display("Contenu");
Dans ce mode la variable “contents” sera automatiquement définie a la valeur du paramètre.
Exemple
Fichier template :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html>
<head>
<title><?=$title?></title>
</head>
<body>
<p><?=$contents?></p>
<ul>
<?foreach($animaux as $animal):?>
<li><?=$animal?>
<?endforeach?>
</ul>
</body>
Utilisation en mode output_buffering :
$template =& new Template("MonTemplate.tpl");
$template->set('title', 'Mon Titre');
$template->set('animaux', array('chien', 'chat', 'souris'));
$template->start();
echo "Contenu de ma page";
$template->display();
$template = new Template("MonTemplate.tpl");
$template->set('title', 'Mon Titre');
$template->set('animaux', array('chien', 'chat', 'souris'));
$template->start();
echo "Contenu de ma page";
$template->display();
Utilisation équivalente en mode direct :
$template =& new Template("MonTemplate.tpl");
$template->set('title', 'Mon Titre');
$template->set('animaux', array('chien', 'chat', 'souris'));
$template->display("Contenu de ma page");
Resultat :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Strict//EN">
<html>
<head>
<title>Mon titre</title>
</head>
<body>
<p>Contenu de ma page</p>
<ul>
<li>chien
<li>chat
<li>souris
</ul>
</body>
Conclusion
Vous allez me dire : “mais c'est que du php ton truc ?”.
Ben oui… PHP offre tous les outils nécessaires pour séparer la présentation du code de façon efficace, et lisible. Pour cela il suffit d'utiliser les syntaxes abrégées (attention aux prologues XML avec les short_tags), et d'avoir de bonnes habitudes. La définition d'une classe simple pour “cadrer” un peu cette utilisation est une bonne habitude car elle restreint les variables accessibles a celle que l'on a définies (pas de vilaines globales). On ne souffre aucune perte de performance, et il suffit de créer une classe fille pour ajouter des fonctionnalités (typiquement : mise en cache, compression gzip).
Note : Depuis PHP 5 & >, par mesure de sécurité, les short_tags sont désactivés par défaut. Pensez donc soit à les activer, soit à utiliser le code :
<?php echo $variableTemplate ?>
au lieu du code :
<?= $variableTemplate ?>
Certes, c'est moins confortable mais que voulez vous
Composé par naholyr
— Adrien Giboire (adrien.giboire@gmail.com) 2008/02/17 09:17 - Ajout de la note & mise à jour PHP 5 en doublon du code PHP 4
proposition de niahoo
Voici ma propre implémentation du moteur de template.
Le fichier de template est passé lors de l'exécution et non lors de l'instanciation et le résultat est retourné sous forme de chaîne plutôt que d'être affiché directement.
<?php
class PHPTemplate {
var $vars = array();
function set($var, $val) {
$this->vars[$var] = $val;
}
function process($file) {
ob_start();
extract($this->vars);
require $file;
return ob_get_clean();
}
}