Introduction au framework Smarty

Smarty est un moteur de template pour le langage PHP. Il vous permet de séparer davantage votre logique métier (logique applicative) et la présentation, en supprimant autant que possible le code PHP de vos vues. Certains développeurs et frameworks préfèrent ne pas utiliser un moteur de templates, d’autres au contraire ne préfèrent pas avoir un simple code PHP dans leurs vues.

Ces deux points de vue sont légitimes et compréhensibles, et à la fin, c’est surtout une question de goût. Quoi qu’il en soit, ce n’est jamais une mauvaise idée que d’essayer un nouveau concept avant de décider de l’utiliser ou non.

C’est ce qu’un tutoriel permet de faire, et je vais ainsi vous présenter le framework de template Smarty.

Etape 0 : À quoi s’attendre

À la fin de ce tutoriel, vous aurez une idée de base sur la façon dont Smarty fonctionne. Vous serez capable de charger les fichiers de template, passer des variables à ceux-ci, utiliser un « layout », et écrire vos propres modificateurs. Tout cela sera accompli en utilisant une classe qui encapsule un ensemble de fonction non orientée objet (wrapper, en anglais) supplémentaire, que vous pouvez intégrer facilement dans vos projets existants.

Étape 1 : Configuration du projet

Pour ce tutoriel, le projet est très simple avec une installation très facile. En effet, nous n’allons pas développer une réelle application. Il suffit de créer un dossier pour votre projet, nommé par exemple « smarty_example » avec un fichier index.php, et un répertoire appelé lib à l’intérieur de celui-ci. En outre, créer un fichier nommé SMTemplate.php dans le répertoire lib du dossier. Ensuite, créez un dossier view au sein de votre dossier smarty_example. Ce dossier contiendra nos fichiers de template Smarty.

Avant de faire quoique ce soit, vous devez installer le framework. Heureusement, l’installation de Smarty est extrêmement simple et ne requiert pratiquement aucune configuration. Tout d’abord, téléchargez Smarty, puis extraire l’archive. Si vous le souhaitez, vous pouvez analyser toute l’archive, mais nous allons avoir seulement besoin du dossier libs pour notre application.
Renommez-le « smarty » et déplacez-le à l’intérieur du dossier lib de notre application. Smarty utilise certains dossiers supplémentaires, tels que templates_c, cache et configs à l’intérieur du dossier lib/smarty.

Votre arborescence devrait maintenant ressembler à ceci :

Introduction au framework Smarty - Arborescence

Étape 2 : Création de la classe SMTemplate

Comme pour chaque projet, chaque programmeur à sa propre idée sur l’API idéale. Afin de modifier légèrement l’API Smarty et nous permettre d’ajouter quelques fonctionnalités supplémentaires, nous allons créer une classe wrapper appelée SMTemplate, qui va prendre soin des détails Smarty pour nous. Cette démarche a un avantage : si, à un moment donné vous décidez d’utiliser une autre moteur de template vous pouvez créer un autre wrapper pour ce dernier, tout en conservant l’interface SMTemplate, et donc sans casser le code qui utilise notre classe SMTemplate.

Configuration

Avant de coder les fonctionnalités de notre classe SMTemplate, nous aurons besoin de stocker quelques détails de configuration. Vous pouvez le faire de plusieurs manières : soit en définissant les options de configuration en tant que constantes de classe, en les définissant comme des constantes dans le fichier SMTemplate.php, ou en les gardant dans un fichier de configuration séparé.

Je préfère la dernière option, je vais donc créer un fichier SMTemplate_config.php. Smarty a besoin de configuration pour le template, le template compilé, le cache et les répertoires de configuration. Le listing ci-dessous présente notre fichier de configuration :

[sourcecode language="PHP"]
<?php
/**
* Configuration de la classe SMTemplate
*/
$SMTemplate_config = array(
‘template_dir’ => ‘views/’,
‘compile_dir’ => ‘lib/smarty/templates_c/’,
‘cache_dir’ => ‘lib/smarty/cache/’,
‘config_dir’ => ‘lib/smarty/configs/’
);
?>
[/sourcecode]

Création de notre classe SMTemplate

La classe SMTemplate va charger ce fichier de configuration, et passer des options à Smarty. Avant que nous puissions transmettre les options, nous aurons besoin d’un objet de la classe Smarty. Notre classe SMTemplate peut hériter de la classe Smarty, mais je préfère utiliser une variable privée d’instance, qui va contenir l’objet Smarty. Jusqu’ici, nous avons les éléments suivants pour notre classe SMTemplate. Voici cette classe :

[sourcecode language="PHP"]
<?php
/**
* Wrapper pour Smarty
*/

require_once(‘smarty/Smarty.class.php’);
require_once(‘SMTemplate_config.php’);

class SMTemplate{
private $_smarty;

function __construct(){
$this->_smarty = new Smarty();

global $SMTemplate_config;
$this->_smarty->template_dir = $SMTemplate_config['template_dir'];
$this->_smarty->compile_dir = $SMTemplate_config['compile_dir'];
$this->_smarty->cache_dir = $SMTemplate_config['cache_dir'];
$this->_smarty->config_dir = $SMTemplate_config['config_dir'];
}
}
?>
[/sourcecode]

Templates

Comme vous pouvez le voir, notre classe est toujours assez pathétique, car il nous est impossible d’afficher quelque-chose. Nous allons résoudre ce problème en ajoutant une fonction render, qui charge un template et l’affiche :

[sourcecode language="PHP"]
<?php
function render($template){
$this->_smarty->display($template . ‘.tpl’);
}
?>
[/sourcecode]

Afin d’avoir un rendu, nous aurons besoin de créer un fichier de template, et ensuite appeler la fonction de rendu dans notre fichier index.php. Le fichier de template sera assez basique, contenant une simple page HTML. Nommez-le « home.tpl », et placez-le à l’intérieur de notre dossier view, et placez s’y le contenu suivant :

[sourcecode language="PHP"]
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Accueil</title>
</head>
<body>
<p> Bonjour à tous ! </p>
</body>
</html>
[/sourcecode]

Maintenant, tout ce qui reste à faire c’est créer un objet SMTemplate et appliquer le rendu à notre « home ». Ouvrez le fichier index.php, ajoutez les lignes suivantes, et ouvrez le lien dans votre navigateur.

[sourcecode language="PHP"]
<?php
require_once(‘lib/SMTemplate.php’);
$tpl = new SMTemplate();
$tpl->render(‘home’);
?>
[/sourcecode]

Introduction au framework Smarty - Test d'affichage Smarty

Étape 3: Attribution et formatage des variables

Si l’on ne devait pas insérer un contenu dynamique, Smarty serait assez inutile. Heureusement, nous pouvons affecter des variables à notre classe Smarty, et afficher celles-ci dans notre template. Nous pouvons également utiliser certaines fonctions Smarty pour formater nos données à l’affichage.

Passer un tableau de variables

Pour ce tutoriel on allons passer un tableau comme paramètre. Avant d’affecter les variables, nous allons éditer notre template pour recevoir des données dynamiques. Afficher un « Bonjour à tous » comme dans l’exemple ne s’avère pas très utile dans un template. Pour utiliser des donnes dynamiques, nous allons utiliser une variable pour déterminer la personne qui est connecté. Ensuite, nous allons ajouter la date du jour. Les variables peuvent être affichées en les entourant par des accolades : Bonjour, {$person} ! Aujourd'hui nous sommes le : {$date} !

Si vous actualisez la page, vous verrez que les variables n’ont pas été valuée, tout simplement car ne nous les avons pas définies. Les variables peuvent être assignées en utilisant la méthode smarty->assign. La fonction render va maintenant prendre un tableau de données facultatives comme second argument.

[sourcecode language="PHP"]
<?php
function render($template, $data = array()){
foreach($data as $key => $value){
$this->_smarty->assign($key, $value);
}
$this->_smarty->display($template . ‘.tpl’);
}
?>
[/sourcecode]

Si vous actualisez la page dans votre navigateur, vous devriez toujours avoir le même problème. Pourquoi ? Tout simplement car nous passons pas le tableau lors de l’appel à notre fonction render. Nous pouvons le faire facilement, en modifiant quelques lignes dans notre fichier index.php. Le listing ci-dessous affiche les lignes à insérer.

[sourcecode language="PHP"]
<?php
require_once(‘lib/SMTemplate.php’);

$data = array(
‘person’ => ‘BlogNT’,
‘date’ => time(),
);

$tpl = new SMTemplate();
$tpl->render(‘home’, $data);
?>
[/sourcecode]

Maintenant si vous actualisez la page, vous devriez avoir à l’écran quelque chose comme : « Bonjour, BlogNT ! Aujourd’hui nous sommes le : 1324143904 ! ». Bien sûr, cette date n’est pas vraiment ce que nous avions en tête. Elle doit être formatée, ce qui nous amène à la section suivante.

Introduction au framework Smarty - Test d'affichage Smarty avec un modificateur

Utilisation des modificateurs de variables

Smarty n’est pas seulement un moteur de template qui récupère et remplace les variables au sein d’un script. Il s’agit également d’un puissant framework, qui vous permet de gagner du temps en utilisant des modificateurs, des fonctions. Si nous voulons par exemple afficher correctement notre date, nous pouvons utiliser le modificateur de variable date_format. Pour appliquer un modificateur à une variable, il suffit de mettre un caractère pipe (« | ») et le nom du modificateur derrière lui, suivi par les arguments optionnels qui sont séparés par des virgules.

Le modificateur de variable date_format prend comme argument une chaîne qui représente le format de la date, et une date par défaut en option. Le code suivant affiche la date comme « jour et Mois » : {$date|date_format:"%d %B"}. Ceci devrait maintenant donner quelque plus correct comme « Bonjour, BlogNT ! Aujourd’hui nous sommes le : 17 December ! ».

Facile, n’est-ce pas ? Ensuite, nous allons inclure nos templates par défaut dans un « layout ».

Étape 4 : Travailler avec une mise en page

Avant de modifier notre classe SMTemplate pour autoriser les layouts, nous allons créer un premier layout. Créez un nouveau répertoire nommé layouts au sein de votre dossier smarty_example et déplacez le fichier home.tpl dans celui-ci. Renommez-le page.tpl.

Nous allons supprimer le contenu de notre précédent texte, et y insérer deux lignes horizontales (<hr>). Par la suite, notre contenu sera placé entre ces lignes.

Il existe différente façon d’insérer du contenu au sein de notre layout. Dans notre cas nous allons utiliser la fonction de Smarty fetch. Celle-ci retourne notre template comme du texte, au lieu de l’afficher. Cela signifie que nous pouvons aller chercher notre template, puis l’assigner à une variable pour une utilisation au sein de notre template. Je l’incorpore ainsi dans notre fichier .tpl : <hr /> {$__content} <hr />

Ceci conclut notre layout, nous allons donc créer quelques templates à utiliser comme contenu. Je vais créer donc créer un template « hello » qui contient la ligne « Bonjour … », ainsi d’un autre template « lorem », qui contient un peu de texte Lorem Ipsum.

Ensuite, nous allons adapter notre classe SMTemplate afin d’utiliser un layout très facilement. Nous allons d’abord mettre en place une nouvelle entrée dans la configuration pour déclarer le répertoire layouts, comme nous l’avons fait pour nos vues : 'layouts_dir' => 'layouts/'.

Puis, nous allons changer notre fonction render. Nous allons fournir un layout comme troisième paramètre optionnel, et laisser la valeur « page » par défaut. Ensuite, dans le listing ci-dessous nous allons rechercher le template passé en paramètre, et l’affecter à la variable $__content, et afficher notre layout.

[sourcecode language="PHP"]
<?php
/**
* Configuration de la classe SMTemplate
*/
$SMTemplate_config = array(
‘template_dir’ => ‘views/’,
‘layouts_dir’ => ‘layouts/’,
‘compile_dir’ => ‘lib/smarty/templates_c/’,
‘cache_dir’ => ‘lib/smarty/cache/’,
‘config_dir’ => ‘lib/smarty/configs/’
);
?>
[/sourcecode]

Il y a plusieurs choses à connaître au sujet de ce code. Tout d’abord, nous n’avons pas indiquer à Smarty où trouver nos layouts. Pour le faire, nous allons simplement, tout en incorporant la contrainte qu’une vue et un layout ne pourront avoir le même nom, ajouter notre répertoire en utilisant la fonction addTemplateDir() :

[sourcecode language="PHP"]
<?php
function __construct(){
$this->_smarty = new Smarty();

global $SMTemplate_config;
$this->_smarty->template_dir = $SMTemplate_config['template_dir'];
$this->_smarty->addTemplateDir($SMTemplate_config['layouts_dir']);
$this->_smarty->compile_dir = $SMTemplate_config['compile_dir'];
$this->_smarty->cache_dir = $SMTemplate_config['cache_dir'];
$this->_smarty->config_dir = $SMTemplate_config['config_dir'];
}
?>
[/sourcecode]

Vérifions en changeant à nouveau notre fichier index.php, et en actualisant notre page dans le navigateur.

[sourcecode language="PHP"]
<?php
require_once(‘lib/SMTemplate.php’);
$tpl = new SMTemplate();
$tpl->render(‘hello’);
?>
[/sourcecode]

Et si nous changeons notre rendu par « lorem », cela fonctionne aussi bien :

Introduction au framework Smarty - Utilisation d'un layout

Étape 5 : Création de votre propre modificateur

Il s’agit de la toute dernière partie de ce tutoriel. Dans celle-ci je vais vous présenter l’une des fonctionnalités les plus avancées de Smarty, qui fait qu’il est plus qu’un simple moteur de templates. Smarty contient un certain nombre de fonctions et modificateurs standards, mais il est aussi très facile de créer les vôtres. Voyons plus en détails le modificateur nous avons utilisé pour formater notre date : $date|date_format:"%d %B"}

L’ajout de ce modification va donner lieu à un appel à la fonction smarty_modifier_date_format(), avec comme arguments $date et notre chaîne de format. Cette fonction retourne une chaîne qui sera elle même affichée. Donc si vous voulez créer votre propre modificateur, tout ce que vous devez faire est d’écrire une fonction PHP.
À titre d’exemple, nous allons écrire un modificateur qui va mettre en majuscule toutes les consonnes et en minuscules toutes les voyelles. Autrement dit, « Lorem Ipsum » devient « LoReM IPSuM ». Pour ce faire, créez un fichier appelé modifier.loweruppercase.php dans le dossier lib/smarty/plugins. Notre modificateur prendra un seul argument, la chaîne qui doit être modifié. Nous pouvons obtenir notre résultat en définissant un tableau de voyelles, puis en transformant la chaîne reçue en un tableau, et en vérifiant si chaque lettre est dans notre tableau de voyelles. Si c’est le cas, nous transformons celle-ci en minuscule, sinon en majuscule. Les caractères modifiés sont ensuite ajoutés à une variable de résultat ($result). Le listing ci-dessous présente le code source du modificateur.

[sourcecode language="PHP"]
<?php
/**
* Smarty plugin
*
* @package Smarty
* @subpackage PluginsModifier
*/

/**
* Smarty loweruppercase modifier plugin
*
* Type: modifier<br>
* Name: loweruppercase<br>
* Purpose: turn consonants into uppercase and vowels into lowercase .
* @param string
* @return string
*/

function smarty_modifier_loweruppercase($string){
$string_array = str_split($string);
$result =  »;
$vowels = array(‘a’, ‘e’, ‘i’, ‘o’, ‘u’, ‘y’);

foreach ($string_array as $_string){
$result .= (in_array($_string, $vowels)) ? strtolower($_string) : strtoupper($_string);
}

return $result;
}
?>
[/sourcecode]

Cela devrait faire l’affaire, nous allons donc le vérifier. Modifier le template « lorem.tpl » et ajoutez un élément h1 contenant notre modificateur (loweruppercase) « Lorem Ipsum ».

Introduction au framework Smarty - Texte transformé par notre modificateur

Téléchargement

Vous pouvez télécharger la démo de l'article dans un seul fichier ZIP.

Conclusion

Bien qu’il y ait beaucoup plus à dire sur Smarty que ce que j’ai abordé dans ce tutoriel, j’espère que cela vous a fournit une vue d’ensemble sur la façon dont il était facile de travailler avec ce framework. Vous savez déjà l’essentiel de tout ce que vous devez savoir. Vous devez également être en mesure de déterminer si vous allez aimer l’idée d’utiliser ce moteur de template ou non.

Des sujets plus avancés, tels que l’utilisation des filtres et des blocs sont utiles, cependant vous pourrez toujours vous débrouiller sans eux. Vous pouvez trouver la documentation sur les fonctionnalités plus avancées sur le site de Smarty . Merci pour la lecture !

Avez-vous apprécié cet article ? Avez-vous déjà mis en œuvre Smarty dans vos projets ? En êtes-vous satisfait ?

  • Maxime MARAIS

    Pour l’étape 1, bien penser à rendre les dossier templates_c et cache accessibles en écriture par le serveur. Typiquement l’utilisateur du serveur apache ne dispose que de droits de lecture, ici il lui faut accorder des droits complémentaires (chmod est votre ami).

    Pour l’étape 2, autant créer une classe abstraite dans SMTemplate_config.php contenant la configuration et étendre cette classe abstraite dans SMTemplate (typiquement SMTemplate extends SMTemplateConfig). Ceci évitera un vilain 
    global.

    Pour l’étape 3, autant passer directement le tableau complet à Smarty sans préalablement parcourir le tableau.
    function render($template, $data = array()){        $this->_smarty->assign(‘data’, $data);        $this->_smarty->display($template . ‘.tpl’);    }
    avec le template
    Bonjour, {$data.person} ! Aujourd’hui nous sommes le : {$data.date} 
    aura le même effet, avec moins de ressources nécessaires.

    Sinon, bel présentation de Smarty que je recommande chaudement pour l’implémentation de système Modèle-Vue-Contrôleur.

    • http://www.blog-nouvelles-technologies.fr Yohann Poiron

      Merci Maxime pour ces compléments ! Effectivement tout est juste je vais ajouter tes remarques dans l’article si tu le veux bien ?

      • Maxime MARAIS

        Avec plaisir ! :)

  • PierreV

    Article très intéressant !
    Pour moi, si le but est de séparer la logique métier de la présentation, je pense que de passer par une framework (Zend,Codeigniter,etc..) est bcp plus intéressant. Enfin, ce n’est que mon avis…

  • http://www.facebook.com/akovnet Stephen Martin

    Pareil que maxime, introduction sympa et je recommande également Smarty pour le MVC. le l’ai découvert dans le cms Xoops 2.0.14 il y a quelques années et depuis je l’utilise comme moteur dans pas mal de mes projets pro et perso. Permet une maintenance rapide, une création de thèmes facile et la fenêtre de debbug rend de fières services durant la phase de dev. Et pour les jeunes développeurs la doc est dispo en français ;-)