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.

Notes

[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).

Discussion

Aucune discussion

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom