Créer des balises personnalisées pour SPIP - Les balises dynamiques

Cet article est la traduction libre d’un article de Thomas Sutton publié sur son blog passingcuriosity en mars 2009 (article original).

La plupart des sites web modernes propose aujourd’hui du contenu dynamique : depuis les listes d’utilisateur « actuellement en ligne » à la publicité ciblée, en passant par les widgets de données temps réel, le dynamisme est bien le slogan d’accroche du Web 2.0.

Pour ajouter des éléments dynamiques de ce genre à votre site SPIP, vous n’aurez qu’à user de sa capacité d’utilisation des balises dynamiques (ou à ajouter des rustines en PHP, mais alors quel est l’intérêt d’un squelette ?).
Dans cet article je vais décrire les balises dynamiques de SPIP et expliquer comment en créer des personnelles.

Les balises dynamiques de SPIP

SPIP est assez complexe et sa conception et mise en œuvre rendent très coûteuse la génération des pages.
Pour que le coût de cette génération ne le rende pas complètement inutilisable, SPIP intègre un mécanisme de cache pour servir plus rapidement les demandes. Si ce processus, qui permet de générer et d’afficher une page, est un peu plus complexe dans SPIP que dans la plupart des systèmes, heureusement il ne l’est pas trop :

Brièvement, et en simplifiant, ce processus se présente comme suit :

  • Parser le squelette à travers un arbre de syntaxe abstraite (AST)
  • Évaluer la partie statique de l’AST
  • Générer le code PHP pour le calcul des parties dynamiques au moment de l’exécution
  • Mettre en cache ce code pour les requêtes futures
  • Évaluer ce code et envoyer [1] le source HTML au client.

<?php

// traitement de la balise #EXEMPLE_DYNAMIQUE.
function balise_EXEMPLE_DYNAMIQUE ($p) {
  
$args = array();
  return 
calculer_balise_dynamique $p,  //  le nœud AST pour la balise
                    
'EXEMPLE_DYNAMIQUE',  //  le nom de la balise
                                   
$args  //  les éléments utilisables de
                                    
);    //  l'environnement
}

// déterminer les paramètres de la balise statique #EXEMPLE_DYNAMIQUE.
// les arguments de la balise et les filtres appliqués à celle-ci
// sont transmis en tant qu'arguments de cette fonction. 
function  balise_EXEMPLE_DYNAMIQUE_stat ($args$filtres) {
  
// calcul de la date et l'heure ... 
  
$maintenant date ('Y-m-d H:i:s'); 
  
// retourne les arguments à passer aux appels dynamiques... 
  
return array($maintenant);
}

// calcul des valeurs dynamiques à retourner.
// le tableau des valeurs retourné par balise_EXEMPLE_DYNAMIQUE_stat
// est passé dans les arguments. 
function  balise_EXEMPLE_DYNAMIQUE_dyn ($autrefois) {
  
// Déterminer l'heure actuelle. 
  
$maintenant date('Y-m-d H:i:s');
  
// Retourner un message contenant la valeur de balise_EXEMPLE_DYNAMIQUE_stat
  // et la valeur que nous venons de générer. 
  
$s "Page générée le : $autrefois <br /> Maintenant : $maintenant"
  return 
$s;
}

?>

Explications :
lorsque nous utilisons #EXEMPLE_DYNAMIQUE dans un squelette, SPIP rassemble toutes les valeurs que nous avons demandées dans $args (rien dans l’exemple ci-dessus), et les transmet à balise_EXEMPLE_DYNAMIQUE_stat ; puis, à partir du tableau retourné par cet appel, une portion de code est générée (par exemple : "balise_EXEMPLE_DYNAMIQUE_dyn('2008-12-01 22:22:22')" qui s’insére dans le code PHP généré par l’AST.

Ajout d’une interface utilisateur

Étant donné le mal que ses développeurs se sont donné pour permettre à SPIP d’être si facile à personnaliser, il serait ridicule que les retours des balises dynamiques soient limités à l’affichage d’une chaîne de caractères.
Heureusement, ils ne le sont pas.

Les balises dynamiques peuvent aussi renvoyer un tableau de données utilisables pour trouver, analyser et retourner un squelette avec du contenu dynamique.
Plutôt que de modifier le code qui implémente une balise, les web-masters peuvent simplement créer un nouveau squelette dans leur dossier squelettes/ qui surchargera celui par défaut, produisant ainsi les résultats qu’ils désirent.

Lors de l’utilisation de cette fonctionnalité, la fonction balise_xxxxx_dyn() retourne un tableau contenant trois éléments :

  • le nom du squelette à évaluer ;
  • le temps durant lequel le résultat peut être mis en cache [2] ;
  • le tableau des données de l’environnement (#ENV) à passer au squelette.

L’exemple précédent, modifié pour être utilisé dans un squelette, peut alors ressembler à ceci :
<?php

function  balise_EXEMPLE_DYNAMIQUE_dyn($then) {
  
$now date('Y-m-d H:i:s'); 
  
$env = array(
               
'autrefois'  => $autrefois,
               
'maintenant' => $maintenant
              
);
  return array(
'formulaires/dynamic_exemple'0$env);
}

?>

Avec un modèle nommé squelettes/formulaires/dynamic_exemple.html rédigé ainsi :

Page générée le : #ENV(autrefois) <br />
Maintenant : #ENV(maintenant)

Notes

[1SPIP a également fait une deuxième mise en cache ici, mais nous allons l’ignorer pour le moment...

[2Ceci est pour la deuxième mise en cache (voir note 1)