Un affichage fonction de l’importance relative dans le site

Voici une contrib qui étend le principe de « Afficher les mots-clés en faisant varier la taille de la police » pour faire des affichages avec taille de police (ou une autre propriété) variant en fonction de l’importance relative d’un objet (article, mot clef, etc.) dans le site.

Concepts

La contrib « Afficher les mots-clés en faisant varier la taille de la police » permet d’afficher une liste de mots clefs en variant la taille de la police en fonction du nombre d’articles associés à chaque mots.

Ici, nous proposons une version générique de cette méthode qui permet, avec de simples filtres, de calculer les variations de taille de police [1]. De plus, les filtres proposés permettent d’appliquer le principe à quasiment tout élément dont on peut avoir une représentation numérique de l’importance dans le site.

On pourra ainsi :
-  mettre en valeur une rubrique en fonction du nombre d’articles qu’elle contient,
-  mettre en valeur une rubrique en fonction de la popularité des articles qu’elle contient,
-  mettre en valeur des articles en fonction du nombre de document associés,
-  etc...

Une démo qui vous sera plus parlante est disponible ici.

Les filtres

Commençons par la définition des filtres qui devront être copiés dans le fichier mes_fonctions.php3 :

/*
 *   +----------------------------------+
 *    Nom des Filtres :    noop, filtre_max, coef et repeat
 *   +----------------------------------+
 *    Date : 23 Mars 2005
 *    Auteur :  Pierre Andrews (mortimer.pa@free.fr)
 *   +-------------------------------------+
 *    Fonctions de ces filtres : ces filtres permettent
 *   de faire un affichage variant en fonction de l'importance
 *    de l'objet.  Vois la contrib pour plus d'informations.
 *   +-------------------------------------+
 *  
 * Pour toute suggestion, remarque, proposition d'ajout
 * reportez-vous au forum de l'article :
 * http://www.spip_contrib.net/article.php3?id_article=879
*/

function noop($texte) {
  return '';
}

function filtre_max($texte, $id='tout') {
  static $max = array();
  if($max[$id] < $texte) {
    $max[$id] = $texte;
  }
  return $max[$id];
}

function coef($max,$nbr,$nbrMax=6) {
  return 1+($nbr/$max*$nbrMax);
}

function repeat($nombre,$texte,$avant,$apres,$min = 0) {
  if($nombre > $min) {
    for($i=0;$i < $nombre;$i++) {
      $texte = $avant.$texte.$apres;
    }
    return $texte;
  } else
    return '';
}


-  noop mange tout ce qui lui est passé, il nous servira à faire des calculs sans rien afficher.
-  filtre_max trouve le maximum parmi les valeurs qui lui sont passées (on peut lui passer un paramètre optionnel pour pouvoir l’utiliser indépendamment plusieurs fois sur la même page),
-  coef calcule un coefficient représentant l’importance pour l’affichage. On doit l’appliquer après filtre_max et spécifier la valeur dont on veut calculer le coefficient. il prend aussi un paramètre optionnel qui spécifie la valeur maximum qui pourra être retournée,
-  repeat répète une chaîne un certain nombre de fois. On peut l’utiliser pour transformer le coefficient en une répétition de balises (voir plus bas). Il prend un paramètre optionnel spécifiant en dessous de quelle valeur il ne faut rien retourner (on peut ainsi filtrer les résultats ayant un coefficient trop petit).

Des boucles

Voici quelques exemple d’utilisation de ces filtres.

-  Le premier exemple permet d’afficher le titre des rubriques avec des tailles de police différentes en fonction du nombre d’articles qu’elles contiennent.

On défini déjà un style pour fixer les tailles de police. Plus la rubrique sera importante, plus il y aura de balises <em> autour :

UL.font_variable {
    list-style-type: none;
}

UL.font_variable> LI {
 display: inline;
}

UL.font_variable> LI EM > EM {
 font-size: 110%;
}

UL.font_variable> LI  EM > EM > EM {
 font-size: 120%;
}

UL.font_variable> LI EM > EM > EM > EM {
 font-size: 130%;
}

UL.font_variable> LI EM > EM > EM > EM > EM {
 font-size: 140%;
}

UL.font_variable> LI EM > EM > EM > EM > EM > EM {
 font-size: 150%;
}

On doit ensuite, dans le squelette, faire deux boucles :

<BOUCLE_max(RUBRIQUES)>
        <BOUCLE_max_art(ARTICLES) {id_rubrique}> </BOUCLE_max_art> [(#TOTAL_BOUCLE|filtre_max{total}|noop)]  </B_max_art>
</BOUCLE_max>

<B_aff>
<ul class='font_variable'>
<BOUCLE_aff(RUBRIQUES)>
        <BOUCLE_aff_art(ARTICLES) {id_rubrique}> </BOUCLE_aff_art> [<li>(#TOTAL_BOUCLE|filtre_max{total}|coef{#TOTAL_BOUCLE}|repeat{#_aff:TITRE,<em>,</em>})</li>] </B_aff_art>
</BOUCLE_aff>
</ul>
</B_aff>
  • _max et _max_art servent à calculer le nombre maximum d’articles qui sont contenus dans les rubriques du site. En appliquant |filtre_max{total} sur le nombre d’articles dans chaque rubrique, on va garder le plus grand nombre d’articles trouvé. |noop sert à ne pas afficher la valeur retournée par le filtre qui cherche le maximum.
  • _aff et _aff_art parcoure toutes les rubriques et calcul le coefficient d’affichage. |filtre_max{total} retourne le nombre d’articles maximal trouvé dans la première boucle. |coef{#TOTAL_BOUCLE} calcul l’importance du nombre d’articles dans cette rubrique par rapport au nombre d’articles maximum. |repeat{#_aff:TITRE,<em>,</em>} entoure le titre de la rubrique du nombre de balises <em> défini par le filtre coef

-  Le deuxième exemple utilise le même principe pour afficher les articles d’une rubrique « galerie » en fonction du nombre d’images qu’ils contiennent :

<BOUCLE_max_doc(ARTICLES) {id_rubrique in 14,18}>
    <BOUCLE_max_doc_in(DOCUMENTS) {id_article} {extension=png}> </BOUCLE_max_doc_in> [(#TOTAL_BOUCLE|filtre_max{doc}|noop)]  </B_max_doc_in>
</BOUCLE_max_doc>

<BOUCLE_aff_doc(ARTICLES) {id_rubrique in 14,18}>
    <BOUCLE_aff_doc_in(DOCUMENTS) {id_article}> </BOUCLE_aff_doc_in> [<strong style="font-size:(#TOTAL_BOUCLE|filtre_max{doc}|coef{#TOTAL_BOUCLE,250}|ceil)%;">#_aff_doc:TITRE</strong>] </B_aff_doc_in>
</BOUCLE_aff_doc>

La différence ici est que l’on utilise directement le filtre coef pour fixer la taille de la police. On passe donc un deuxième paramètre à ce filtre pour spécifier que le coefficient doit être calculé entre 0 et 250.

-  La dernière boucle d’exemple est un peu différente. Elle affiche les rubriques en fonction de la popularité de leur article le plus populaire :

<BOUCLE_max(RUBRIQUES)>
     <BOUCLE_max_art(ARTICLES) {id_rubrique} {par popularite} {inverse} {0,1}> [(#POPULARITE|filtre_max{maxi}|noop)]
     </BOUCLE_max_art_max>
</BOUCLE_max>

<B_aff>
<ul class='font_variable'>
<BOUCLE_aff(RUBRIQUES)>
    <BOUCLE_aff_art(ARTICLES) {id_rubrique} {par popularite} {inverse} {0,1}>
        [<li>(#POPULARITE|filtre_max{maxi}|coef{#POPULARITE}|repeat{#_aff:TITRE,<em>,</em>})</li>]
    </BOUCLE_aff_art>
</BOUCLE_aff>
</ul>
</B_aff>

Les boucles max_art et aff_art ne sont plus là pour calculer un total, mais pour trouver la popularité maximum. On fait donc une boucle triée par popularité croissante et l’on ne prend que le premier résultat (i.e. l’article avec la plus forte popularité).

Notes

[1En fait, n’importe quelle propriété peut être contrôlée avec ces filtres. L’exemple de la taille de la police est seulement le plus direct, mais on pourrait calculer un nom de class etc.

Le filtre coefficient ne retourne pas des valeurs très homogènes et certain affichages risquent d’être très gros par rapport à d’autre (c.f. le site de test).

Mais comme coef est un filtre, il est simple d’ajouter un filtre de lissage (sqrt ou log) après :

<strong [(#TOTAL_BOUCLE|filtre_max{doc}|coef{#TOTAL_BOUCLE,250}|sqrt|ceil)]

Discussion

4 discussions

  • Bonjour,

    Je ne suis pas familier avec le PHP, et je voulais créer un nuage de tags qui conviendrait à un site comportant peu d’articles, sans utiliser de PHP.

    Je vous propose donc la méthode que j’ai utilisée sur Fol d’ire (mes tags sont regroupés le groupe de mots-clés n°4) :

    Dans le squelette :

    <BOUCLE_nuage (MOTS) {id_groupe=4} >
    
       <BOUCLE_total (ARTICLES) {id_mot}>
       </BOUCLE_total>
          <span class="[(#TOTAL_BOUCLE|>{2}|?{'font120',''})]">
             <span class="[(#TOTAL_BOUCLE|>{5}|?{'font120',''})]">
                <span class="[(#TOTAL_BOUCLE|>{10}|?{'font120',''})]">
                   <a href="#URL_MOT">
                      [(#_nuage:TITRE) - ]
                   </a>
                </span>
             </span>
          </span>
       </B_total>
    </BOUCLE_nuage>

    Et dans le CSS :

    .font120 {
    font-size:115%;
    }
    
    .font120 span span a:link {
    color:#880000;
    }
    
    .font120 span span a:hover {
    color:#000000;
    }
    
    .font120 .font120 span a:link {
    color:#660000;
    }
    
    .font120 .font120 span a:hover {
    color:#000000;
    }
    
    .font120 .font120 .font120 a:link {
    color:#440000;
    }
    
    .font120 .font120 .font120 a:hover {
    color:#000000;
    }

    Cela servira peut-être à quelqu’un...

    Sylvano

    Répondre à ce message

  • Salut,

    Merci pour ta contrib. En Spip 1.9.1, j’ai utilisé les balises #SET et #GET pour obtenir quelque chose de similaire.

    Mon idée est, dans un squelette rubrique.html, de mettre en valeur les sous-rubriques en fonction de la popularité des articles qu’elles contiennent. Cet exemple correspond donc au dernier exemple de l’article ci-dessus. Avec un peu d’imagination, on doit pouvoir l’adapter à d’autres besoins...

    <BOUCLE_rubrique(RUBRIQUES){id_rubrique}>
    	<BOUCLE_popularite_max(ARTICLES){branche}{!par popularite}{0,1}>
    		#SET{pop_max,#POPULARITE}
    	</BOUCLE_popularite_max>
    	<BOUCLE_sous_rubriques(RUBRIQUES){id_parent}>
    	<BOUCLE_articles(ARTICLES){branche}{!par popularite}{0,1}>
    	[<span[ style="font-size: (#POPULARITE|div{#GET{pop_max}}|round{2}|plus{1})em;"]>
    	<a href="#_sous_rubriques:URL_RUBRIQUE">(#_sous_rubriques:TITRE)</a>
    	</span> ]
    	</BOUCLE_articles>
    		[<span><a href="#URL_RUBRIQUE">(#TITRE)</a></span> ]
    	<//B_articles>
    	</BOUCLE_sous_rubriques>
    </BOUCLE_rubrique>

    La BOUCLE_popularite_max sélectionne l’article le plus populaire de la branche, c’est-à-dire de la rubrique en cours et de ses sous-rubriques. Avec #SET{pop_max,#POPULARITE}, on donne à la variable pop_max, la valeur de sa #POPULARITE. pop_max a donc une valeur comprise entre 0 et 100.

    On sélectionne ensuite les sous-rubriques de la rubrique en cours avec la BOUCLE_sous_rubriques. Puis l’article le plus populaire de cette branche-là.

    On fixe une taille relative de police (<span style="font-size: ...em;">) en fonction d’un obscur calcul :
    [(#POPULARITE|div{#GET{pop_max}}|round{2}|plus{1})]

    La popularité de cet article est divisée par la popularité maximum obtenue auparavant (#GET{pop_max}), on arrondi deux chiffres après la virgule (voir fonction round() de php) et on ajoute 1.

    Avec ce calcul, un article dont la popularité serait de 0/100 aurait une taille de 1em, un article ayant une popularité de 100/100 aurait une taille de 2em.

    Notez que cette boucle n’affichera que les rubriques contenant au moins un article. Pour s’assurer que les rubriques qui ne contiennent que des documents ou des liens par exemple, s’afficheront, on ajoute un code alternatif à la BOUCLE_articles (<//B_articles>).

    Répondre à ce message

  • 2

    Cette contribution ne semble pas marcher sous Internet Explorer, alors que sous Firefox oui. Y a-t-il un moyen de « forcer » cette présentation le navigateur n°1 ?

    • Il y a deux technique pour faire la taille dans cette contrib, les em, et le font-size en %, laquelle ne marche pas exactement ??

    • Plus précisément le « list-style-type : none ; » et la taille de police sont pris en compte par Firefox (tant en % qu’en px). Sur Internet Explorer ce n’est pas le cas, on ne voit qu’une liste simple avec puces et les mots sont de tailles identiques.

    Répondre à ce message

  • Merci pour ta contribution.

    Testée sur www.instits.fr

    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