Usage du filtre « unique » pour classer des articles

Objectif : Classer les articles d’une rubrique par date, chaque année étant dans un cadre

La boucle citée en exemple dans la doc du filtre unique produit une longue liste d’articles difficile à cadrer s’il y a beaucoup d’articles

Voici la boucle proposée

<B_archive>
  <div>
  <div class="muette"><ul class="muette"><li class="muette"><ul class="muette">
    <BOUCLE_archive(ARTICLES) {id_rubrique} {par date} {inverse}>
      [</ul></li></ul></div><div class="encart archives"><p class="titre">(#DATE|annee|unique)</p><ul><li><ul>]
        [</ul></li><li>(#DATE|affdate{'Y-m'}|unique|nom_mois)<ul>]
          <li><a href="#URL_ARTICLE" title="commentaire">#TITRE</a></li>
    </BOUCLE_archive>
      </ul></li></ul></div>
   </div>  
</B_archive>

Vu ainsi la boucle n’est pas évidente à comprendre. Voici le cheminement de sa construction

-  Afficher une liste d’article avec l’année en titre (assez semblable à l’exemple de la doc)

    <BOUCLE_archive(ARTICLES) {id_rubrique} {par date} {inverse}>
      [<p class="titre">(#DATE|annee|unique)</p>]
          <a href="#URL_ARTICLE" title="commentaire">#TITRE</a><br />
    </BOUCLE_archive>

-  Mettre chaque année dans un cadre (étape 1)

<BOUCLE_archive(ARTICLES) {id_rubrique} {par date} {inverse}>
  [<div class="encart archives"><p class="titre">(#DATE|annee|unique)</p>]
      <a href="#URL_ARTICLE" title="commentaire">#TITRE</a><br />
</BOUCLE_archive>

L’encart ouvert dans la partie optionnelle avant de la date provoque une erreur de parité des balises. Il faut fermer ce div avant une nouvelle année et en fin de boucle

-  Mettre chaque année dans un cadre (étape 2)

<BOUCLE_archive(ARTICLES) {id_rubrique} {par date} {inverse}>
     v-- (ferme la balise encart à chaque changement d'année)
     v
  [</div><div class="encart archives"><p class="titre">(#DATE|annee|unique)</p>]
      <a href="#URL_ARTICLE" title="commentaire">#TITRE</a><br />
</BOUCLE_archive>
     v-- (ferme la balise encart à la fin)
     v         
  </div>
</B_archive>

La balise fermante introduite avant la date n’a pas de balise ouvrante au premier passage dans la boucle. Il faut l’ouvrir dans la partie optionnelle avant de la boucle. Cela va créer un groupe de balise vide avec une class=« muette » qui interdit l’affichage par le butineur.

-  Mettre chaque année dans un cadre (étape 3)

<B_archive>
  <div class="muette">
    <BOUCLE_archive(ARTICLES) {id_rubrique} {par date} {inverse}>
         v-- (ferme la balise encart à chaque changement d'année
         v    et la balise introduite dans la partie avant de laboucle)
         v
      [</div><div class="encart archives"><p class="titre">(#DATE|annee|unique)</p>]
          <a href="#URL_ARTICLE" title="commentaire">#TITRE</a><br />
    </BOUCLE_archive>
         v-- (ferme la balise encart à la fin)
         v         
  </div>
</B_archive>

En itérant ainsi pour chaque phase on obtient la boucle proposée.

Articles listés par date
Utilisation du filtre UNIQUE pour classer les articles par date

Voici le code généré (nettoyé et indenté) pour la visualisation proposée ci dessus et visible sur le site d’étude castorsmag

<div class="muette"><ul class="muette"><li class="muette"><ul class="muette"></ul></li></ul></div>

<div class="encart archives">
  <p class="titre">2005</p>
  <ul>
    <li><ul></ul></li>
    <li>avril
      <ul>
        <li><a href="article.php?id_article=45" >Pour test</a></li>
      </ul>
    </li>
  </ul>
</div>

<div class="encart archives">
  <p class="titre">2004</p>
  <ul>
    <li><ul></ul></li>
    <li>décembre
      <ul>
        <li><a href="article.php?id_article=20" >Les encadrements</a></li>
        <li><a href="article.php?id_article=21" >Déco au naturel</a></li>
      </ul>
    </li>
    <li>avril
      <ul>
        <li><a href="article.php?id_article=46" >test novembre</a></li>
      </ul>
    </li>
  </ul>
</div>

Pour information les styles utilisés

.muette {display: none;}

.encart    {
    border-color: #9E9E9E;
    background-color: #F7F7E7;
    color: #9E9E9E;
    border-width: 1px;
    border-style: solid;
    padding: 0.5em;
    margin: 0.3em;
    margin-top:    1em;
}

.archives {
    float: left;
    font-size: 0.7em;
}

.archives ul {
  padding-left: 1em;
  list-style: none; /* impératif pour supprimer tous les petits points */
}

.titre    {
    font-weight: 600;
    text-align: center;
}

Aller plus loin

Eviter les blocs vides

Dans la version actuel de la boucle archive, on se retrouve avec des blocs de balises qui ne servent pas :
<div class="muette"><ul class="muette"><li class="muette"><ul class="muette"></ul></li></ul></div>

Dans un navigateur qui supporte les css, ce n’est pas un problème. Mais quand on veut être accessible ou lisible par des navigateurs en mode texte, c’est moins sympathique.

Voici donc une version de la boucle qui évite cela :

<BOUCLE_archive(ARTICLES) {par date} {inverse} {id_rubrique}>

[(#COMPTEUR_BOUCLE|>{1}|?{' ',''})
[</ul>(#DATE|affdate{'Y-m'}|unique{mois_ferme}|?{' ',''})</li>]
]
[(#COMPTEUR_BOUCLE|=={1}|?{' ',''}) 
[(#DATE|affdate{'Y-m'}|unique{mois_ferme}|?{'',''})]
]

[(#COMPTEUR_BOUCLE|>{1}|?{' ',''})
[</ul></div>(#DATE|annee|unique{ferme_annee}|?{' ',''})]
]
[(#COMPTEUR_BOUCLE|=={1}|?{' ',''}) 
[(#DATE|annee|unique{ferme_annee}|?{'',''})]
]

[<div class="encart archives">
<p class="titre">
(#DATE|annee|unique{annee})
</p>
<ul>
]

[<li>(#DATE|affdate{'Y-m'}|unique{mois}|nom_mois)<ul>]

<li><a href="#URL_ARTICLE" title="commentaire">#TITRE</a></li>

</BOUCLE_archive>
</ul></li>
</ul></div>
</B_archive>

La boucle commence par 2 tests pour fermer les balises du mois :

  1. le premier vérifie qu’on n’est pas au début de la boucle, puisqu’il n’y a pas besoin de fermer les balises dans ce cas là,
  2. le deuxième si l’on est au début de la boucle, fait croire que l’on a bien fermé les balises, mais n’affiche rien en fait.

Ensuite, la boucle est à peut prêt similaire, on ouvre les div et ul pour l’année et le mois si nécessaire grâce au filtre |unique et on affiche toujours le titre de l’article.

Dans le code optionnel après la boucle on ferme une fois toutes les balises des blocs puisqu’on est sûr d’avoir affiché au moins un article, donc au moins une année et un mois.

Une autre écriture de la boucle est possible en faisant un test sur le compteur de la boucle.

<BOUCLE_archive(ARTICLES) {id_rubrique} {par date} {inverse}>
  [
    [(#COMPTEUR_BOUCLE|>{1}|?{'</ul></li></ul></div>',''})]
      <div class="encart archive">
      <p class="titre">(#DATE|annee|unique)</p>
      <ul>
    ]
    [
      [(#DATE|annee|unique{nouvelle}|?{'','</ul></li>'})]
        <li>(#DATE|affdate{'Y-m'}|unique|nom_mois)
         <ul>
    ]
          <li><a href="#URL_ARTICLE" title="commentaire">#TITRE</a></li>
</BOUCLE_archive>
  </ul></li></ul></div>
</B_archive>

Avant d’afficher l’année si nécessaire, on passe par un test pour savoir si on n’est pas dans le premier passage [(#COMPTEUR_BOUCLE|>{1}|?{'</ul></li></ul></div>',''})] on ferme alors le mois et l’année qui précedent.

Avant d’afficher le mois si nécessaire, on teste si on vient d’ouvrir une nouvelle année [(#DATE|annee|unique{nouvelle}|?{'','</ul></li>'})] sinon on ferme le mois précédent

Les archives d’un certain mois, d’une certaine année

Le critère de la boucle _archive présenté affiche les archives pour une certaine rubrique. On pourrait vouloir plutôt afficher des archives pour certaines dates.

On peut pour cela, ajouter un critère {date == ^[(#ENV{mois,.})]}. Celui ci va limiter l’affichage aux articles ayant des dates suivants une certaine expression régulière passé dans l’url.

Ainsi, si on met :
-   ?mois=2005-04-22 alors on n’aura que les articles du 22 Avril 2005,
-   ?mois=2005-04 donnera tous les articles d’Avril 2005,
-   ?mois=2005 donnera tous les articles de 2005,
-   ?mois=200 donnera tous les articles des années 2000 (2001, 2002, ...),
-   ?mois=.*-12- donnera tous les articles de tous les mois de Décembre,
-  etc...

Pour simplifier ce genre d’écriture, on peut ajouter un filtre dans mes_fonctions :

function ajoute_date($date,$var = 'mois') {
  $url = $GLOBALS["clean_link"]->getUrl();
  $mois = $_GET[$var];
  $url = preg_replace('/[?&]'.preg_quote($var).'='.preg_quote($mois).'/','',$url);
  return quote_amp($url.(strpos($url,'?')?'&':'?')."$var=$date");
}

Ce filtre va ajouter la variable mois de la date sur laquelle on l’applique dans l’url de la page actuelle et retourner cette url. On peut alors écrire la boucle :

<BOUCLE_archive(ARTICLES) {date == ^(#ENV{mois,.})} {par date} {inverse}>
[(#COMPTEUR_BOUCLE|>{1}|?{' ',''})
[</ul>(#DATE|affdate{'Y-m'}|unique{mois_ferme}|?{' ',''})</li>]
]
[(#COMPTEUR_BOUCLE|=={1}|?{' ',''}) 
[(#DATE|affdate{'Y-m'}|unique{mois_ferme}|noop)]
]

[(#COMPTEUR_BOUCLE|>{1}|?{' ',''})
[</ul></div>(#DATE|annee|unique{ferme_annee}|?{' ',''})]
]
[(#COMPTEUR_BOUCLE|=={1}|?{' ',''}) 
[(#DATE|annee|unique{ferme_annee}|noop)]
]

[<div class="encart archives">
<p class="titre">
<a href="[(#DATE|annee|ajoute_date)]">(#DATE|annee|unique{annee})</a>
</p>
<ul>
]

[<li><a href="[(#DATE|affdate{'Y-m'}|ajoute_date)]">(#DATE|affdate{'Y-m'}|unique{mois}|nom_mois)</a><ul>]

<li><a href="#URL_ARTICLE" title="commentaire">#TITRE</a></li>

</BOUCLE_archive>
</ul></li>
</ul></div>
</B_archive>

Pour avoir des liens sur les noms de mois et d’année qui retourneront une liste d’article pour ce mois ou cette année.

Cette boucle remplace très avantageusement une boucle récursive qui faisait le même travail sous la version 1.7.2 Voir les articles Calendrier des articles et Une liste d’articles triés par mois

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