Les différents modes d’inclusion de SPIP

, par Maïeul

Suite à une remarque de Tetue après mon article sur les pratiques de développements avec SPIP et à une question d’un théologien sur twitter, je fais ici un point sur les deux modes d’inclusion de squelettes dans SPIP.

Rappel : principe de l’inclusion

Inclure un squelette A dans un squelette B, c’est dire à B de reprendre le contenu du squelette A à l’endroit de l’inclusion.

L’interêt d’une telle pratique est de mettre en commun des morceaux de codes utilisés par plusieurs squelettes. Le cas le plus classique étant l’affichage du menu, mais plus le temps passe, plus le devellopeur SPIP aguerri aura tendance à multiplier les inclusions, voyant qu’il utilise beaucoup de code en commun.

Le principe des squelettes Z pousse à l’extrême cette idée d’inclusion / mutualisation du code.

Mais attention : il ne faut pas croire qu’on imite ainsi un « copier-coller » de B dans A.

Ainsi si je met dans le squelette A :

XXX<INCLURE{fond=B}>XXX

et dans le squelette B

YYY

Cela ne revient pas au même que mettre dans A :

XXXYYYXXX

Pourquoi ? Parce qu’il faut considérer que le contexte de chaque squelette est indépendant. Par contexte, j’entend l’ensemble des paramètres techniques qui lui sont passés, par exemple un numéro d’article. Ce contexte est récupérable via la balise #ENV et sert à l’interprétation des critères de boucles de premier niveaux. J’explique plus en détails cette notion de contexte dans un article sur contrib.

<INCLURE> ou #INCLURE ?

Il existe deux modes principaux d’inclusion :

  1. <INCLURE{fond=B}>
  2. #INCLURE{fond=B}

Historiquement, le premier modèle est apparu d’abord. Quelle est la différence technique entre les deux ? Soit un squelette A appelant un squelette B.

  1. Dans le cas d’une inclusion avec INCLURE le squelette B possède son propre cache. Lorsque le squelette A est appelé, il produit son cache à lui. Le résultat du cache de A est retourné au navigateur, et c’est à ce moment là que le cache du squelette B est inséré.
  2. Dans le cas d’une inclusion avec #INCLURE, il n’existe pas de cache du squelette B. Le morceau de PHP / HTML lié à l’interprétation par SPIP du squelette B est mis directement dans le cache du squelette A.

Puisqu’il paraît qu’il faut mettre des schémas, voici un schéma qui tente d’expliquer cette différence [1].

<INCLURE> ou #INCLURE ?
Inclusion statique ou inclusion dynamique ?

Conséquences techniques

  1. Du point de vue de la taille des caches :
    1. <INCLURE> produit plus de fichiers de cache, mais moins gros.
    2. #INCLURE produit des fichiers de cache plus gros, mais en moindre quantité.
  2. Du point de vue de la durée des caches :
    1. <INCLURE> permet d’avoir un squelette fils n’ayant pas la même durée de cache que le squelette père.
    2. #INCLURE ne permet pas cela, puisque le squelette fils n’a pas vraiment de cache propre.
  3. Du point de vue des techniques SPIP applicables :
    1. On peut pas filtrer le résultat d’une inclusion par <INCLURE> [2].
    2. Par contre avec #INCLURE on peut appliquer un filtre [(#INCLURE{fond=B}|filtre)].
    3. Dans tout les cas on peut utiliser AJAX.
  4. Du point de vue de la performance j’avoue ne pas trop savoir. Avoir un cache propre (<INCLURE>) permet d’avoir une vrai mutualisation des caches, dont un gain en terme de requête SQL, en revanche on a une perte de temps au moment où le cache de B est « reinjecté » dans le fichier A renvoyé à l’internaute. C’est donc au développeur de juger au cas par cas, mais il me semble que dans 90 % des cas, il vaut mieux utiliser <INCLURE>.

Et #MODELE

On peut aussi utiliser #MODELE. Pour ce faire, il faut que le fichier inclu se situe dans le dossier modeles.

Techniquement, faire

#MODELE{B}

revient, à peu de chose près, à la même chose que faire #INCLURE{fond=modeles/B}. Une différence toutefois : dans le cas de #MODELE l’identifiant de l’objet courant est automatiquement passé en paramètre.

Exemple, j’ai un squelette modeles/B.html :

<BOUCLE_article(ARTICLES){id_article}>
#ID_ARTICLE #TITRE
</BOUCLE_article>

Dans mon squelette A, je cherche à appeler ce squelette pour tout les articles d’une rubrique.

Je peux faire soit :

<BOUCLE_articles(ARTICLES){id_rubrique}>
#MODELE{B}
</BOUCLE_articles>

soit :

<BOUCLE_articles(ARTICLES){id_rubrique}>
#INCLURE{fond=modeles/B,id_article}
</BOUCLE_articles>

Personnellement je n’aime pas trop #MODELE, je trouve qu’il induit une confusion. Le seul cas où l’emploi de modèle est justifiable, c’est lorsque l’on souhaite permettre à un auteur d’inclure un tel morceau dans son article, en utilisant :

<B|id_article=xxx>

Par exemple le plugin Gravatar propose un modèle gravatar, que l’on peut appeler :

  1. soit dans un squelette #MODELE{gravatar}{id_auteur}.
  2. soit dans un article <gravatar|id_auteur=42>.

On consultera la documentation sur les modèles pour plus de détails.

P.-S.

Pour aider à y voir plus clair dans les différents squelettes inclus, on utilisera la fonction var_mode=inclure.

Notes

[1Toute suggestion d’amélioration est la bienvenue.

[2Une solution pour contourner ce problème est de mettre #FILTRE{nom du filtre} dans le squelette inclus.