Mélanger et trier des éléments hétérogénes

Voici une boucle pour faire un affichage trié et mélangé de différents types d’éléments SPIP.

Principe Général

Nous allons afficher un mélange d’articles et de rubriques.

Le problème pour réussir un affichage trié de rubriques et d’articles, c’est qu’on ne peut pas faire une boucle qui sélectionne en même temps les deux. On peut soit faire une boucle ARTICLES soit une boucle RUBRIQUES.

On est donc obligé de faire l’affichage dans deux boucles différentes, ce qui complique un peu l’affichage des deux types d’éléments dans une même liste selon un certain ordre.

Voici une boucle qui offre une solution pour faire un affichage trié par date :

<BOUCLE_rubriques(RUBRIQUES) {par date} {inverse}>

<BOUCLE_articles(ARTICLES) {par date} {inverse} {doublons} {date>#DATE}>
Article: #DATE #TITRE<br>
</BOUCLE_articles>
Rubrique: #DATE #TITRE<br>

</BOUCLE_rubriques>

<BOUCLE_article_fin(ARTICLES) {par date} {inverse} {doublons}>
Article: #DATE #TITRE<br>
</BOUCLE_article_fin>

qui nous donnera un affichage du genre :

Rub: 2005-07-21 16:55:59 Blog
Art: 2005-07-21 16:39:54 And you, where are you?
Art: 2005-07-08 17:12:38 Il reste des politiciens de génie (au moins 1)
Art: 2005-07-04 16:33:58 Déménagement
Rub: 2005-07-01 16:08:12 Computing
Rub: 2005-07-01 16:08:12 Out There
Art: 2005-07-01 16:08:12 Easy Personal Podcasting
Art: 2005-07-01 15:38:30 Ecole Polytechnique de ???

La solution est en fait assez simple à comprendre :

  1. on commence par boucler sur toutes les rubriques (BOUCLE_rubriques)
  2. pour chaque rubrique, on regarde s’il y a des articles qui devraient être affichés avant, grâce au critère {date>#DATE}
  3. on affiche ensuite la rubrique
  4. une fois qu’on a parcouru toutes les rubriques, on affiche le reste des articles. Ceux qui sont plus vieux que toutes les rubriques du site.

Le critère {doublons} permet de ne pas afficher plusieurs fois le même article.

D’autres tris

On peut évidemment utiliser d’autres tris que le tri par date, il faut alors penser à modifier les critères en conséquence.

Par exemple, si on trie avec des numéros dans les titres, il faut remplacer :

  • {par date} {inverse} par {par num titre}
  • {date>#DATE} par {titre<#TITRE}

Subtilité avec les id_rubrique

Il faut bien faire attention, cette boucle affiche tous les articles et les rubriques du site. Si on voulait afficher seulement les articles et sous-rubriques de la rubrique du contexte, il faudrait se méfier du piège avec le critère id_rubrique de la boucle _articles.

En effet, imaginons qu’on soit dans un squelette entouré d’une boucle principale :

<BOUCLE_principale(RUBRIQUES) {id_rubrique}>

si on mettait juste {id_rubrique} dans la boucle _articles, on ne sélectionnerait pas les articles de la rubrique sélectionnée par la boucle _principale, mais les articles de la rubrique sélectionnée par la boucle _rubriques.

Il faudra donc utiliser le critère : {id_rubrique = #_principale:ID_RUBRIQUE} qui spécifie que l’on doit bien prendre les articles de la rubrique principale.

On aurait donc :

<BOUCLE_principale(RUBRIQUES) {id_rubrique}>

...

<BOUCLE_rubriques(RUBRIQUES) {id_parent} {par date} {inverse}>

<BOUCLE_articles(ARTICLES) {id_rubrique=#_principale:ID_RUBRIQUE} {par date} {inverse} {doublons} {date>#DATE}>
Article: #DATE #TITRE<br>
</BOUCLE_articles>
Rubrique: #DATE #TITRE<br>

</BOUCLE_rubriques>

<BOUCLE_article_fin(ARTICLES) {id_rubrique} {par date} {doublons}>
Article: #DATE #TITRE<br>
</BOUCLE_article_fin>

...

</BOUCLE_principale>

D’autres mélanges

Remarquez que cette méthode peut facilement s’appliquer à d’autres types d’éléments de SPIP. On peut tout aussi bien mélanger brèves et articles par exemple :

<BOUCLE_breves(BREVES) {par date} {inverse}>

<BOUCLE_articles(ARTICLES) {par date} {inverse} {doublons} {date>#DATE}>
Article: #DATE #TITRE<br>
</BOUCLE_articles>
Rubrique: #DATE #TITRE<br>

</BOUCLE_breves>

<BOUCLE_article_fin(ARTICLES) {par date} {inverse} {doublons}>
Article: #DATE #TITRE<br>
</BOUCLE_article_fin>

On peut même aller plus loin et mélanger 3 types d’éléments :

<BOUCLE_rubriques(RUBRIQUES) {par date} {inverse}>
<BOUCLE_articles(ARTICLES) {par date} {inverse} {doublons} {date>#DATE} {lang}>
<BOUCLE_breves(BREVES) {par date} {inverse} {doublons} {date>#DATE} {lang}>
Brev: #DATE #TITRE<br>
</BOUCLE_breves>

Art: #DATE #TITRE<br>
</BOUCLE_articles>

<BOUCLE_breves2(BREVES) {par date} {inverse} {doublons} {date>#DATE} {lang}>
Brev: #DATE #TITRE<br>
</BOUCLE_breves2>

Rub: #DATE #TITRE<br>

</BOUCLE_rubriques>

<BOUCLE_article_fin(ARTICLES) {par date} {inverse} {doublons} {lang}>
<BOUCLE_breves_fin1(BREVES) {par date} {inverse} {doublons} {date>#DATE} {lang}>
Brev: #DATE #TITRE<br>
</BOUCLE_breves_fin1>
Art: #DATE #TITRE<br>
</BOUCLE_article_fin>

<BOUCLE_breves_fin2(BREVES) {par date} {inverse} {doublons} {date>#DATE} {lang}>
Brev: #DATE #TITRE<br>
</BOUCLE_breves_fin2>

On mélange ici des articles, des brèves et des rubriques. On a donc ajouté des boucles brèves, qui sont considérées après toutes les autres.

On a donc :

  1. la boucle _breves dans la boucle _articles qui trouve toutes les brèves plus jeunes que l’article actuel,
  2. la boucle _breves2 dans la boucle _rubriques qui trouve toutes les brèves plus jeunes que la rubrique mais plus vieilles que tous les articles plus jeunes,
  3. la boucle _breves_fin1 dans la boucle _article_fin qui trouve toutes les brèves plus jeune que les articles plus vieux que toute rubrique,
  4. la boucle _breves_fin2 qui trouve les brèves plus vielles que tous les articles et que toutes les rubriques.

C’est pas beau tout ca ?

Discussion

12 discussions

  • mokland

    super contrib ! merci beaucoup !
    ça m’a permis de faire en 5 minutes ce qui m’aurait valu des heures de réflexion et des maux de crane ;p

    Répondre à ce message

  • 1

    Bonjour et merci pour cette contrib que j’ai longtemps cherché

    J’ai deux boucles imbriquées (qui fonctionne, ça me semble toujours incroyable) de la forme :

    <BOUCLE_site_yoh(SITES) {!par date}{syndication=non}>  
     
                             <BOUCLE_syndic_articles_yoh(SYNDIC_ARTICLES) {age_relatif<0}  {!par date}{doublons}>
                     
                 
              <div class="texte"><a href="#URL_ARTICLE" ><b>[(#TITRE|supprimer_numero)]</b></a></div>    
             
       
                              </BOUCLE_syndic_articles_yoh>  
                           
              <div class="texte"><a href="#URL_SITE" ><b>[(#_site_yoh:NOM_SITE|supprimer_numero)]</b></a></div>    
             
           </BOUCLE_site_yoh>

    Cela liste, par date, les sites référencés non-syndiqués avec les articles_syndiqués de manière indifférencié.

    J’aimerai paginer cette liste mais je bloque depuis 2 jours dessus.

    Je n’arrive pas à faire comprendre à la balise #PAGINATION qu’il lui faut additionner les articles_syndiqués avec les sites non-syndiqués avant de faire son job.

    Si quelqu’un a une idée de piste, je suis preneur :)

    Merci d’avance

    • Après pas mal de recherche, pagination impossible.

      J’ai donc afficher les résultats par age<30jrs puis avec l’aide de boutons par mois.

      Cela marche :)

    Répondre à ce message

  • <BOUCLE_articles(ARTICLES) {id_rubrique} [{par num titre}{inverse}][!{par date}{inverse}] {pagination}>

    Voilà ce que j’utilise pour allier le numéro et la date dans l’ordre (inverse pour les numéros).

    Répondre à ce message

  • Jean Baptiste Pressac

    Je me permet de signaler que si vous voulez utiliser cette boucle pour effectuer des tris avec des numéros dans les titres et que vous utilisez le filtre supprimer_numero pour faire disparaitre le numéro, vous devez faire suivre d’une astérisque la balise #TITRE du filtre {titre<#TITRE*} comme évoqué sur le forum. La boucle devient donc :

    <BOUCLE_rubriques(RUBRIQUES) {par num titre}>
         <BOUCLE_articles(ARTICLES) {par num titre} {doublons} {titre<#TITRE*}>
              Article: #TITRE<br>
         </BOUCLE_articles>
         Rubrique: #TITRE<br>
    </BOUCLE_rubriques>
    
    <BOUCLE_article_fin(ARTICLES) {par num titre}{doublons}>
         Article: #TITRE<br>
    </BOUCLE_article_fin>

    Répondre à ce message

  • C’est beau. Bravo et merci infiniment pour cette contribution fort utile.

    Répondre à ce message

  • Moi je m’en sers systématiquement dans le « backend » pour construire un flux RSS qui diffuse à la fois les brèves et les articles.

    Répondre à ce message

  • Félicitations, ça marche à merveille.

    Répondre à ce message

  • Bonjour,

    excellente l’idée, j’ai voulu la tester mais hélas, elle n’a pas fonctionné pour mon cas.

    en fait je souhaiterais afficher l’arborescence d’une rubrique et trier ses éléments par ordre alphabétique, et ceux-ci de manière récursive.

    ex :

    • rub
      • art 1.
      • rub 2.
        • art 2.1
        • art 2.2
        • rub 2.3
          • ...
      • art 3.

    j’ai donc voulu utiliser cet algo, (car il s’agit bien d’un algo), et l’adapter pour qu’il fonctionne de manière récursive.

    j’ai alors constaté deux problèmes :
    -  le premier se situe au niveau de la condition id_rubrique=#_principal:ID_RUBRIQUE
    -  le second a déjà été mentionné, il s’agit de la condition titre<#TITRE qui ne fonctionne pas visiblement, d’ autant que dans mon cas il faudrai plutôt utiliser num titre<#TITRE, mais cela ne fonctionne pas évidemment

    voici une partie de mon code :

    <B_rubriques>
    <ul>
    <?php $rub_recursive = #ID_RUBRIQUE ; ?>
    <BOUCLE_rubriques(RUBRIQUES) {id_parent} {par titre}>
    
    	<B_articles>
    	<BOUCLE_articles(ARTICLES) {id_rubrique=<?=$rub_recursive?>} {par titre} {doublons} {titre<#TITRE}>
    	<li>#TITRE</li>
    	</BOUCLE_articles>
    	</B_articles>
    	
            <li>#TITRE</li>
    
    	<BOUCLE_sous_rubriques(BOUCLE_rubriques)></BOUCLE_sous_rubriques>
    
    	<B_article_fin>
    	<BOUCLE_article_fin(ARTICLES) {id_rubrique=<?=$rub_recursive?>} {par titre} {doublons}>
    	<li>#TITRE</li>
    	</BOUCLE_article_fin>
    	</B_article_fin>
    				
    </BOUCLE_rubriques>
    </ul>
    </B_rubriques>

    si quelqu’un voit où je me suis trompé, ou a une solution alternative, je suis intéréssé.

    d’autant plus que je pense que ce morceau de code, s’il fonctionne sera d’une grande utilité pour beaucoup de monde.

    Merci

    Répondre à ce message

  • Vraiment chouette !
    -  Merci ;-)

    Répondre à ce message

  • Cà fait des lustres que je cherche une solution pour ordonner les articles et les sous rubriques d’une rubrique en même temps. Un problème se pose si on souhaite trier par autre chose qu’une date. Si tu peux me trouver une soluce ...

    J’ai déjà commencé avec ton exemple mais çà me paraît pas viable, sachant que le critère {titre<#TITRE} pour la sous-boucle article semble ne pas marcher et que de toutes façons il faudrait prendre en charge le numéro dans le titre (qui sert à ordonner) comme on le fait pour le tri {par num titre}.

    Mon code :

    <BOUCLE_principale(RUBRIQUES) {id_rubrique}>
    
    <BOUCLE_rubriques(RUBRIQUES) {id_parent} {par num titre}>
    <BOUCLE_articles(ARTICLES) {id_rubrique=#_principale:ID_RUBRIQUE} {par num titre} {doublons} {titre<#TITRE}>
    <li class="mission"><a href="#URL_ARTICLE" [title="(#DESCRIPTIF|textebrut|entites_html)"]>#TITRE</a></li>
    </BOUCLE_articles>
    <li class="mission"><a href="#URL_RUBRIQUE" [title="(#DESCRIPTIF|textebrut|entites_html)"]>#TITRE</a></li>
    </BOUCLE_rubriques>
    
    <BOUCLE_article_fin(ARTICLES) {id_rubrique} {par num titre} {doublons}>
    <li class="mission"><a href="#URL_ARTICLE" [title="(#DESCRIPTIF|textebrut|entites_html)"]>#TITRE</a></li>
    </BOUCLE_article_fin>
    
    </BOUCLE_principale>

    Répondre à ce message

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