Templating avec Cheetah
Cheetah est un moteur de Templating écrit en Python. Il est simple d'utilisation et rapide. Je l'utilise notamment pour créer des pages HTML. Des nombreux framework web l'utilisent dont notamment l'excellent web.py, qui permet de rendre les templates directement pour peu que Cheetah soit installé.
Je ne vais pas m'étendre sur les fonctionnalité basiques de Cheetah, vous trouverez de très bonnes introductions sur le sujet sur cette page. Ici on va plutôt aborder des techniques un peu avancées pour les problématiques liées aux pages HTML.
La problématique principale du Templating HTML c'est qu'il faut permettre de générer dynamiquement les pages sans avoir à chaque fois à recopier tout le design.
Une première approche consiste à créer 2 fichiers :
header
<html> <head> <title>titre</title> </head> <body>
footer
</body> </html>
Puis on crée le fichier contenant le corps de notre page
page.tmpl
#include "header" tada! #include "footer"
Et enfin pour finir on appelle Cheetah pour rendre la page :
PYTHONPATH=. cheetah fill page.tmpl
(le
PYTHONPATH
permet de dire à Cheetah ou il
doit aller chercher ses fichiers templates). Cela produit un
fichier page.html
qui contient :
<html> <head> <title>titre</title> </head> <body> tada! </body> </html>
Cette approche a l'avantage d'être très simple à mettre en oeuvre. Apparemment elle est utilisée dans pas mal de cas. Toutefois elle n'est pas très puissante. Les possibilités offertes sont plus que limitées. Par exemple si l'on souhaite avoir une page de base puis rajouter des menus sur certaines catégories de pages, on est obligé d'inclure à la main les menus dans chaque pages.
Heureusement Cheetah gère l'héritage entre templates. Voici comment ça se passe. Soit le fichier suivant :
base.tmpl
#def title: mon titre a moi <html> <head> <title>$title</title> </head> <body> $content </body> </html>
Dans ce cas, on a un template de base qui a 2
paramètres : $title
et
$content
. $title
étant
déjà défini dans base.tmpl
il
n'est pas obligatoire de le redéfinir dans les templates
fils. En revanche $content
doit
être défini dans chacun des templates qui
étendent base.tmpl
. Par exemple :
page1.tmpl
#extends base #block content Ca rox cheetah! <a href='/'>test</a> #end block
Ici on définit le bloque content, qui
remplacera $content
dans base.tmpl
.
On lance donc PYTHONPATH=. cheetah fill -p
page1.tmpl
et on obtient :
<html> <head> <title>mon titre a moi</title> </head> <body> Ca rox cheetah! <a href='/'>test</a></body> </html>
Ensuite si l'on souhaite créer une autre page qui va elle redéfinir le titre c'est très simple :
page2.tmpl
#extends base #def title: un autre titre #block content Ca rox cheetah! <a href='/'>test</a> #end block
Notez bien qu'ici def
et block
sont utilisé pour faire la même chose. Ces deux
syntaxes sont équivalentes (voir la documentation de
Cheetah pour plus d'informations).
Et maintenant on se heurte à un petit
problème, si l'on souhait rajouter un menu à la
page, il va falloir utiliser la variable $content
,
et du coup on ne peut plus utiliser cette variable dans les
pages qui descendent ce template avec un menu ...
Pour éviter ce genre de problème on peut
définir des bloques autour des zones qui sont
susceptibles d'être modifiées par d'autres
templates. Ainsi on modifie base.tmpl
comme ceci
:
#def title: mon titre a moi <html> <head> #block head <title>$title</title> #end block head </head> <body> #block body $content #end block body </body> </html>
Ainsi, quand vous souhaitez redéfinir certaines parties de votre page, il suffit d'utiliser les bloques que vous avez définis avant. Ainsi les anciens bloques seront remplacés.
Par exemple, si on souhaitait rajouter un menu dans la page précédente il suffirait de faire :
menu.tmpl
#extends base #block body <body> <div class='menu'> <ul> <li>menu1</li> <li>menu2</li> </ul> </div> $content#slurp </body> #end block
Et hop! maintenant toutes les pages qui descendent de
menu.tmpl
contiendront le menu. Ce n'est pas
révolutionnaire dans le concept. Mais c'est bien
sympathique quand même!