Squelettes "Z-core" sous SPIP 3 - astuces

Langage et développement
Frameworks

| par Teddy Payet | 4

Il n’est plus nécessaire, je pense, de présenter l’architecture des squelettes sous la nomenclature "Z". Beaucoup l’utilise aujourd’hui, moi le premier.

Préambule

Le plugin Z-core est l’héritage du plugin Zpip développé par Matthieu Marcillaud, Cédric Morin, Romy Têtue et un collectif SPIP. Z-core est le moteur offrant le découpage des squelettes. Il ne fournit pas de squelettes. C’est à nous ou au plugin choisi de fournir les pages qui vont bien.
C’est rapide et efficace. Il faut savoir aussi que les noms de blocs/zones ont changé par rapport à Zpip. Presque que chaque zone correspond à un répertoire.
C’est un peu complexe à appréhender au départ. Mais c’est un aspect "vite oublié" au profit de son efficacité.

Remarque

L’un des premiers jeux de squelettes offerts à la communauté SPIP utilisant cette mécanique zcore est le plugin "SPIP-r" développé par Cédric.
Toute la doc sur ce site : http://spipr.nursit.com/

Problématique

Il arrive parfois que l’on désire que la page sommaire ait sa propre architecture, différente du reste des pages classiques.
On pourrait ajouter des balises conditionnelles si on se trouve sur un #ENV{type-page}|=={sommaire} mais ça risque de faire lourd si votre mise en page est complexe.

Voici le code initial de structure.html fournit par Zcore :

[(#VAL{_Z_DOCTYPE}|defined|?{#VAL{_Z_DOCTYPE}|constant}|sinon{<!DOCTYPE HTML>})][
(#SET{class,[page_(#ENV{type-page,page})[ #ENV{type-page,page}_(#ENV{composition,''})]][ composition_(#ENV{composition})]})][
(#REM) http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/]
<!--[if lt IE 7 ]> <html class="[(#GET{class})][ (#LANG_DIR)][ (#LANG)] no-js ie ie6 lte9 lte8 lte7" xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR"> <![endif]-->
<!--[if IE 7 ]>    <html class="[(#GET{class})][ (#LANG_DIR)][ (#LANG)] no-js ie ie7 lte9 lte8 lte7" xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR"> <![endif]-->
<!--[if IE 8 ]>    <html class="[(#GET{class})][ (#LANG_DIR)][ (#LANG)] no-js ie ie8 lte9 lte8" xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR"> <![endif]-->
<!--[if IE 9 ]>    <html class="[(#GET{class})][ (#LANG_DIR)][ (#LANG)] no-js ie ie9 lte9" xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!-->
<html class="[(#GET{class})][ (#LANG_DIR)][ (#LANG)] no-js" xmlns="http://www.w3.org/1999/xhtml" xml:lang="#LANG" lang="#LANG" dir="#LANG_DIR">
<!--<![endif]-->
        <head>
                <script type='text/javascript'>/*<![CDATA[*/(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement);/*]]>*/</script>[

                (#REM) Debut du head particulier a chaque page
                pour inserer un title, des css particulieres(mais surchargees), ou des js *inline*
                ]<INCLURE{fond=head/#ENV{type-page},env}>[

                (#REM) Partie commune a toutes les pages, sans env
                ]<INCLURE{fond=inclure/head}>[

                (#REM) Fin du head particulier a chaque page, pour inserer des js specifiques par exemple
                pour inserer des js *externes*
                ]<INCLURE{fond=head_js/#ENV{type-page},env}>
        </head>
        <INCLURE{fond=body,env}>
</html>

Zcore renvoie vers un body.html unique pour tout le monde.
Comment dire à Zcore/SPIP qu’on veut une mise en page particulière pour le sommaire ?

Astuce

Pour cela, on peut très facilement ajouter 2 ou 3 lignes de codes pour que SPIP sélectionne le body.html approprié pour le sommaire.
Comme dit plus haut et vu dans le code initial, Z-core envoie une variable d’environnement nommé type-page.
Une page sommaire.html aura pour variable type-page=sommaire. Pour un article, nous aurons type-page=article, rubrique type-page=rubrique, etc.

Le code magique

Pour se faire, on va remplacer <INCLURE{fond=body,env} /> par ceci :

#SET{body,body}
[(#CHEMIN{body_#ENV{type-page}.html}|?{#SET{body,body_#ENV{type-page}},#SET{body,#GET{body}}})]
[(#CHEMIN{body_#ENV{type-page}-#ENV{composition}.html}|?{#SET{body,body_#ENV{type-page}-#ENV{composition}},#SET{body,#GET{body}}})]
<INCLURE{fond=#GET{body},env} />

Explications

  • On initialise une variable body avec pour valeur par défaut "body".
  • Grâce à la première balise #CHEMIN [1], on va chercher l’existence d’un body_sommaire.html. Mais avec ce code, on va aussi regarder si body_article.html, body_rubrique.html ou autre existent. Sinon, on garde body.html par défaut.
  • La deuxième balise #CHEMIN va plus loin en regardant s’il existe une composition en plus de notre type de page. Soit pour une composition "ma_super_compo" pour mon article, Zcore/SPIP regardera l’existence de body_article-ma_super_compo.html. Si elle n’existe pas, on garde la valeur précédente de la variable "body".

Erratum du 17/01/2014

Attention
Il n’est pas nécessaire de faire tout cela. Rendons justice en pointant vers l’article de la doc expliquant cela : http://spipr.nursit.com/framework-z...

Grâce au message de Valéry dans le forum ci dessous, j’ai fouillé un peu plus dans le code de z-core et il s’avère qu’il n’est pas nécessaire d’utiliser le code ci-dessus pour le body.html
Z-core va détecter "naturellement" et sans artifice la présence de body-rubrique.html ou body-rubrique-ma_compo.html.

Mais le code ci-dessous est toujours d’actualité :

Aller plus loin

On pourrait étendre ce principe sur les zones de découpage dans notre body.html.
En effet, on pourrait avoir besoin pour un aside, d’une composition de rubrique particulière, un autre contenu que celui donner par aside/rubrique.html. Pour cela, ajouter en début de votre fichier body.html le code suivant :

[(#SET{html,#ENV{type-page}})]
[(#SET{html2,#ENV{type-page}-#ENV{composition}})]

On instancie 2 valeurs :

  • "html" qui contient le type de page ;
  • "html2" contient le type de page et la composition associée.

A la place de <INCLURE{fond=aside/#ENV{type-page},env} /> de body.html, mettre <INCLURE{fond=aside/#GET{aside},env} />.
Et la ligne juste au dessus, mettre ce code :

[(#CHEMIN{aside/#GET{html2}.html}|?{#SET{aside,#GET{html2}},#SET{aside,#GET{html}}})]

L’astuce est donc la même que plus haut. Pour une composition "ma_super_compo" pour une rubrique, on va chercher l’existence de aside/rubrique-ma_super_compo.html, sinon on prend aside/rubrique.html.

Et voilà !
A vous de tester si cette mécanique vous convient ou pas ! Pour ma part c’est testé et approuvé !