Je n'ai jamais rencontré de langage de template aussi intéressant que celui de SPIP. La plupart des langages existants, comme Smarty par exemple, sont conçus pour afficher un contenu qui est déjà déterminé. Avec les squelettes SPIP, le contenu est demandé par le template lui-même, via un langage de boucles qui mixe PHP et mySQL. Le langage de boucles de SPIP est vraiment très proche du SQL et c'est aussi ça qui rends son utilisation intéressante, c'est un peu comme faire du SQL en français directement dans le template.
J'ai déjà par le passé réimplementé le langage de SPIP dans une classe php3 (c'était en 2003), c'était très intéressant car la classe n'était qu'un wrapper mySQL, elle allait directement chercher le contenu demandé par le template. Cependant c'était pas mal bugué et quand même relativement lent. Et surtout attaquer directement la base de données comme ça c'est pas très secure...
Je me suis donc un peu repenché sur l'idée et j'ai commencé à coder il y a deux jours un objet PHP5 très flexible, qu'on étends selon ses besoins et ses envies, qui parse un squelette. Normalement cet objet est pas trop mal conçu et permet donc des choses très intéressantes. Bon déjà on peux adapter le language à ses besoins (les types de boucles peuvent être définis comme on le sent, les critères également), on peux même renommer les noms des tags et des critères. Mais ensuite, c'est du tout objet, et adapter le parseur de squelette à son projet devient donc un plaisir :)
Prenons un exemple simple, vraiment très simple, on n'autorise un seul type de boucle, la boucle ARTICLE, le code suivant nous suffira :
require_once '../class.miniskel.php';
class mySkel extends miniSkel
{
protected function processLoopType_article($criterias, $content)
{
$articles = array(
array(
'title' => 'Chinese Soup',
'text' => 'this is a french recipe of the soupe chinoise',
),
array(
'title' => 'Flamenkuche',
'text' => 'This is delicious !',
)
);
$out = '';
foreach ($articles as $art)
{
$out .= $this->parseVariables($content, $art);
}
return $out;
}
}
$skel = new mySkel;
$skel->display('simple_example.tpl');
Et ouais c'est difficile de faire plus simple ! Bon après on peux mettre ce qu'on veux dans la méthode processLoopType_article, là on renvoie juste un tableau fixe et on ne tient pas compte des critères, mais on peux très bien faire qq chose de plus élaboré. Ca montre la facilité d'adapter le système de squelettes à votre application. On vois également ici que l'objet miniSkel définit des conventions permettant de base simples permettant d'étendre l'objet facilement, mais il est tout aussi facile de redéfinir ces conventions pour faire un peu ce qu'on veux.
J'ai codé trois petits exemples qui vont avec la class miniSkel. Le premier est celui que je viens de montrer, le second est une petite application (un mini CMS) utilisant une base SQLite pour stocker des articles et les afficher via la boucle de type ARTICLE, pour montrer la flexibilité et la proximité du langage avec les requêtes SQL. Le dernier enfin, est un peu plus avancé puisqu'il s'agit d'un compileur de template, comme pour smarty, il va transformer le langage du template en langage PHP, ce qui permet ensuite un traitement bien plus rapide. Ce compileur est évidemment un peu basique, mais il est fonctionne très bien et je l'ai codé en 2 ou 3 heures...
Ce compileur montre la flexibilité et la puissance de l'objet miniSkel. En théorie on pourrait même construire un parseur de squelettes SPIP à 90% compatible avec les squelettes existants, en très peu de temps.
Voilà c'est encore en alpha, ça va sûrement évoluer et y'a probablement encore des bugs (me les signaler merci !), mais si ça vous intéresse vous pouvez aller voir ici :
http://svn.kd2.org/svn/misc/libs/miniskel/
Vous trouverez la classe miniSkel ainsi qu'un répertoire contenant les 3 exemples et leur templates. Attention PHP5 nécessaire, on fait de l'objet ici :)
Le code est déjà largement documenté, mais vous trouverez aussi un README qui vous dira ce qui n'est pas encore implémenté et ce qui ne relève pas de la compétence de miniSkel.