Définir le type de tri d’une rubrique avec des mots-clés

Problème et objectif

Dans certains sites sous SPIP, comme par exemple un webzine ou un blog, les rubriques et sous-rubriques ne jouent qu’un rôle de classement d’informations de nature homogène en différents groupes.

Sur d’autres sites, plus complexes, les rubriques serviront aussi à différencier la nature des éléments qui y sont rangés. Par exemple, le site d’une association mettra dans une rubrique les comptes-rendus des réunions, dans une autre une présentation de ses principaux projets, dans une troisième seront placés des articles «statiques» [1] présentant l’association, son histoire ou ses objectifs, tandis que dans une dernière rubrique on retrouvera la liste de ses membres.

Lors de leur affichage sur le site public, ces données ne doivent pas nécessairement toutes être triées selon le même ordre. Par exemple, on souhaitera classer les compte-rendus de réunion par ordre antichronologique, la rubrique de présentation sera quand à elle triée selon l’ordre arbitraire que permettent le critère {par num titre} et le filtre supprimer_numero, en numérotant les titres des articles pour préciser cet ordre. La liste des membres sera ordonnée selon l’ordre alphabétique des noms de famille ; enfin, en hésite encore sur l’ordre qu’il convient d’utiliser pour la rubrique présentant les projets et l’on souhaite donc conserver la possibilité d’en changer facilement.

La solution a priori la plus évidente que propose SPIP consiste à créer autant de squelettes qu’il est nécessaire, chaque rubrique disposant de son squelette rubrique-xx.htmlxx est son identifiant [2]. Si cette solution est entièrement suffisante dans la plupart des cas, elle présente quand même quelques inconvénients:

  • Il n’est tout d’abord pas évident, avec le système standard de SPIP, de partager un même squelette entre deux rubriques dont l’une n’est pas la sous-rubrique de l’autre [3].
  • Notamment en conséquence du point précédent, dans le cas d’un site de taille importante, aux contenus variés, l’inflation du nombre de squelettes à maintenir risque de rendre l’ensemble assez rapidement ingérable. Même en utilisant abondamment l’inclusion de morceaux de squelettes (avec <INCLURE>) pour ne pas (trop) dupliquer de code.
  • Enfin, l’usage des squelettes spécifiques aux rubriques ne permet pas de réutiliser facilement un jeu de squelette sur un nouveau site (sinon, bien sûr en renommant de façon adéquate lesdits squelettes) ni encore moins de partager un même jeu de squelettes entre deux sites en ce qu’il crée un lien regrettable entre le code des squelettes et la base de données. Nous visons plutôt ici à paramétrer les squelettes pour rendre leur usage plus générique.

Méthode

Voici donc une solution alternative au problème, dans laquelle nous allons nous contenter d’un seul squelette rubrique.html pour gérer l’ensemble des tris différents évoqués plus haut. Dans un usage un peu détourné, nous allons ici nous servir des boucles comme de structures conditionnelles.

Nous avons retenu ici trois types de tri différents ({!par date} [4], {par titre} et {par num titre}), mais il est parfaitement possible d’utiliser d’autres types de classements.

1. Première étape, créez un groupe de mots-clés que vous nommerez par exemple «Type de tri des rubriques». Entrez dans la configuration avancée du groupe de mot-clé [5] pour préciser que ce mot-clé ne portera que sur des rubriques ainsi que pour faire en sorte qu’il ne soit possible de lier à chaque rubrique qu’un seul mot de ce groupe à la fois (par la même occasion, vous pouvez aussi restreindre les droits sur ce groupe aux seuls administrateurs, ce qui évitera sans doute l’une ou l’autre surprise).

2. Dans ce groupe, créez trois mots-clés que vous nommerez respectivement (en minuscules et sans espace) : par_num_titre, par_titre et par_date_inverse. Point n’est besoin d’être grand clerc pour deviner à quoi ils vont servir. Notez que le mot par_date_inverse n’est pas nécessaire (il s’agit ici du classement par défaut) mais il servira d’utile aide-mémoire et permettra, si vous changez le type de tri par défaut, de ne pas avoir à faire de modification sur la base de données.

3. Enfin, insérer dans votre squelette rubrique.html le morceau de code que vous trouverez en à la fin de cette page. En voici la structure :

<BOUCLE_test_tri(RUBRIQUES){id_rubrique}{titre_mot=par_titre}>

[(#REM)
ici les boucles pour afficher les articles
triés par titre
]

</BOUCLE_test_tri>

   <BOUCLE_test_tri_2(RUBRIQUES){id_rubrique}{titre_mot=par_num_titre}>

   [(#REM)
   ici les boucles pour afficher les articles triés
   par num titre
   ]

   </BOUCLE_test_tri_2>

   [(#REM)
   ici les boucles pour afficher les articles triés
   par date inverse (tri par défaut)
   ]

   <//B_test_tri_2>

<//B_test_tri>

Le concept est tout simple: en plaçant deux critères potentiellement contradictoires (l’identifiant de la rubrique — lequel implique que la boucle ne peut renvoyer qu’un ou zéro résultat —, puis un des mots-clés créés plus haut), on fait jouer à des boucles spip exactement le même rôle qu’un «if { ... } else { ... }» en php.

Vous remarquerez peut-être — avec raison — qu’alors que j’introduisais mon article en prétendant réduire le code redondant, la construction utilisée ici implique la répétition d’un même morceau de code à trois reprises!

On peut facilement résoudre ce problème en plaçant le morceau de code dans un squelette séparé, nommé par exemple item.inc.html (le fichier php correspondant étant nommé item.inc.php.

Schématiquement, ce fichier item.inc.html contiendra quelque chose comme ceci :

<BOUCLE_generale(ARTICLES){id_article}>
<div>
<a href="#URL_ARTICLE">[(#TITRE|supprimer_numero)]</a>
</div>
</BOUCLE_generale>

On l’appelera (à trois reprises) dans rubrique.html :

<BOUCLE_test_tri(RUBRIQUES){id_rubrique}{titre_mot=par_titre}>

   <BOUCLE_articles_par_titre(ARTICLES){id_rubrique}{par titre}>
   <INCLURE(item.inc.php){id_article}>
   </BOUCLE_articles_par_titre>

</BOUCLE_test_tri>

   <BOUCLE_test_tri_2(RUBRIQUES){id_rubrique}{titre_mot=par_num_titre}>

      <BOUCLE_par_num_titre(ARTICLES){id_rubrique}{par num titre}>
      <INCLURE(item.inc.php){id_article}>
      </BOUCLE_par_num_titre>

   </BOUCLE_test_tri_2>

      <BOUCLE_par_date_inverse(ARTICLES){id_rubrique}{!par date}>
      <INCLURE(item.inc.php){id_article}>
      </BOUCLE_par_date_inverse>

   <//B_test_tri_2>

<//B_test_tri>

Enfin, on peut pousser la logique jusqu’au bout en modulant l’affichage du squelette item.inc.html en fonction du type de tri choisi. Prenons un exemple simple: faire en sorte que la date ne soit affichée que quand on se trouve dans un classement de type {!par date}, mais pas dans les autres — considérant que c’est là le seul endroit où il est pertinent d’afficher cette information.

Pour ce faire, nous devons passer un paramètre supplémentaire à notre squelette inclus, ce qui nous allons faire en remplaçant la première instruction d’inclusion:

<INCLURE(item.inc.php){id_article}>

par une instruction de ce type-ci :

<INCLURE(item.inc.php){id_article}{tri='par_num_titre'}>

Ensuite, comme prévu, nous affichons ou pas la date en fonction du paramètre tri passé dans l’inclusion :

[(#ENV{tri}|=={'par_date_inverse'}|?{<div>[(#DATE|affdate)]</div>,''})]

Résultat final

Au final (on a plus ajouté ici la gestion d’une liste à puce), nous obtenons donc le code suivant à inclure dans notre squelette rubrique.html :

<BOUCLE_test_tri(RUBRIQUES){id_rubrique}{titre_mot=par_titre}>

   <B_par_titre>
   <ul>
   <BOUCLE_par_titre(ARTICLES){id_rubrique}{par titre}>
   <INCLURE(item.inc.php){id_article}{tri='par_titre'}>
   </BOUCLE_par_titre>
   </ul>
   </B_par_titre>

</BOUCLE_test_tri>

   <BOUCLE_test_tri_2(RUBRIQUES){id_rubrique}{titre_mot=par_num_titre}>

      <B_par_num_titre>
      <ul>
      <BOUCLE_par_num_titre(ARTICLES){id_rubrique}{par num titre}>
      <INCLURE(item.inc.php){id_article}{tri='par_num_titre'}>
      </BOUCLE_par_num_titre>
      </ul>
      </B_par_num_titre>

   </BOUCLE_test_tri_2>

      <B_par_date_inverse>
      <ul>
      <BOUCLE_par_date_inverse(ARTICLES){id_rubrique}{!par date}>
      <INCLURE(item.inc.php){id_article}{tri='par_date_inverse'}>
      </BOUCLE_par_date_inverse>
      </ul>
      </B_par_date_inverse>

   <//B_test_tri_2>

<//B_test_tri>

Le squelette item.inc.html ressemble quand à lui finalement à ceci :

<BOUCLE_generale(ARTICLES){id_article}>
<li>
   <a href="#URL_ARTICLE">[(#TITRE|supprimer_numero)]</a>
   [(#ENV{tri}|=={'par_date_inverse'}|?{<div>[(#DATE|affdate)]</div>,''})]
</li>
</BOUCLE_generale>

Tout ceci est bien sûr à agrémenter selon votre goût; on ne fournit ici qu’un canevas assez schématique.

Un exemple de réalisation? Le site mocliege.be, malgré des données assez variées, n’utilise qu’un seul squelette pour l’affichage de toutes ses rubriques: vous pouvez le consulter à l’adresse: http://mocliege.be/layout/rubrique.html, de même que le squelette inclus: http://mocliege.be/layout/item.inc.html [6].

Bon amusement.

Footnotes

[1C’est-à-dire destinés à ne pas bouger, au contraire des rubriques dont le contenu se présente comme un flux d’informations.

[2Lire à ce sujet le paragraphe intitulé «Une interface différente dans le même site» sur la page Principe général de la documentation officielle.

[3Avec un système de type UNIX, un lien symbolique est néanmoins une manière assez rapide et afficace de procéder.

[4Equivalent à {par date}{inverse}.

[5Vous devez l’avoir préalablement activée via la configuration du site.

[6attention, toutefois, ce squelette est un peu plus complexe que ce qui est présenté ici; la partie qui nous intéresse dans le cadre de cette contrib commence à la ligne 48, avec la boucle _test_tri).

updated on 21 October 2007

Discussion

2 discussions

  • 1

    Bonjour,

    Je suis intéressé pour classer mes rubriques et sous-rubriques par numéro de titre.

    J’ai bien créer le fichier item.inc.php à la racine de Spip.
    J’ai également modifié le fichier rubrique.html comme indiqué.

    Par contre, je ne comprends pas comment faire en sorte que le numéro de la rubrique ne s’affiche pas dans le menu.
    Comment saisir le numéro de rubrique. Par exemple pour une rubrique “Contacts” en 5éme position, dois-je saisir “5-Contacts” dans le champ Titre de la rubrique.

    Y-a-t-il autre chose à modifier ?

    Merci pour vos éclairages.

    • Je maîtrise pas suffisament ce qui est décrit dans cet article par contre j’ai travaillé sur un site multilingue et je me suis posé ce problème d’afficher ou non les numéros de rubriques, je crois que tu as ta réponse chez Paris-Beyrouth avec un système de filtres.

    Reply to this message

  • 1

    je n’ai pas le fichier item.inc.php ....je suis obligé de télécharger tous le programme spip chaque fois qu’il me manque un élément d’un exemple ....ou il y a un endroit ou on peut prendre juste une page manquante......et j’en proffite pour signaler une petite erreur ds les explications....

    BOUCLE_par_num_titre(ARTICLES)id_rubriquepar num titre
    INCLURE(item.inc.php)id_article
    /BOUCLE_par_titre
    (la boucle fermante correct est /BOUCLE_par_num_titre désolée j’ai enlevé les sigles plus petit et plus grd sans quoi l’exemple de code ne passe pas)

    • Salut,

      je n’ai pas le fichier item.inc.php ...

      C’est juste un bête fichier de squelette qu’il te faut; par exempe ceci :

      <?php
      $fond = "item.inc";
      $delais = 7 * 24 * 3600;
      include("inc-public.php3");
      ?>

      je suis obligé de télécharger tous le programme spip chaque fois qu’il me manque un élément d’un exemple

      Il n’y a pas de fichier item.inc.php dans la distribution.

      BOUCLE_par_num_titre(ARTICLES)id_rubriquepar num titre INCLURE(item.inc.php)id_article /BOUCLE_par_titre (la boucle fermante correct est /BOUCLE_par_num_titre désolée

      Merci, je regarde.

      j’ai enlevé les sigles plus petit et plus grd sans quoi l’exemple de code ne passe pas)

      Il y a des raccourcis spip pour cela, en particulier <cadre></cadre> est très utile.

      FS

    Reply to this message

Comment on this article

Who are you?
  • [Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom