tags cloud

sans boucle de comptage, avec le plugin CFG

Attention, cette contribution est EN CHANTIER : elle n’est peut-être pas fonctionnelle.

Affichage d’un nuage de mots clés, la taille de chaque mot est proportionnelle au nombre d’éléments qui lui sont associés. Le score de chaque mot est récupéré à partir des comptages déjà effectués par le squelette mot.

-  0-0-

-  Ajouts dans le squelette mots
-  Affichage du nuage
-  Personnalisation du nuage
-  Paramétrage avec CFG
-  Exemples

Il y a quelques jours j’ai proposé une boucle qui me permet d’afficher un nuage - Nuage de mots-clés tout en SPIP.

Écrite uniquement en SPIP et avec une structure html très simple, elle présente l’avantage d’être très facilement intégrable à un squelette et à son habillage, et également d’être intégralement mise en cache entre les recalculs.

Mais comme on me l’a fait très judicieusement remarquer, c’est par contre au moment du recalcul qu’elle n’est pas vraiment économique puisqu’elle compte tous les éléments associés à chaque mot-clé, et pour un site avec beaucoup d’éléments et beaucoup de mots-clés, ça représente beaucoup de requêtes sql et beaucoup de calculs.

Il fallait donc trouver une solution pour répartir la charge de travail dans le temps, et si possible ré-utiliser les calculs faits à d’autres endroits dans le site.

C’est chose faite avec la version présentée ici. Le nuage à l’arrivée est absolument identique.

L’affichage du nuage a besoin pour fonctionner :

  • de connaître le score de chaque mot, calculé en fonction du nombre d’éléments qui lui sont associés (articles, rubriques et sites)
  • de connaître les scores minimums et maximums pour calculer le coefficient qui permettra de calculer la taille de chaque mot en fonction de son score.

Dans la première version présentée sur spip-contrib, le calcul du nuage reposait sur deux boucles :

  • une boucle de comptage qui calcule tous les scores et extrait les extrêmes
  • une boucle d’affichage qui génère la liste de mots et style chacun en fonction des valeurs calculées par la première boucle.

En fait, le calcul fait par la première boucle est déjà effectué pour l’affichage des pages associées aux mots-clés.

Il suffit donc de dire au squelette mot.html que, chaque fois qu’il recalcule la page d’un mot donné, au passage il mette de côté le nombre d’éléments associés à ce mot, tant qu’il y est vu qu’il les compte de toutes façons.

Pour pouvoir réutiliser ce score dans le squelette du nuage, complètement indépendamment du squelette mots, j’ai utilisé les fonctions du plugin CFG qui permettent de stocker des variables dans la base de données et de les récupérer ensuite.

La boucle du squelette nuage se contente donc ensuite de récupérer les scores, de calculer la taille et d’afficher les mots, mais elle ne compte rien. Le calcul des scores, quant à lui, est réparti entre les recalculs des différentes pages du squelette mots, le travail est donc bien réparti dans le temps puisque chacune de ces pages à une durée de vie propre dans le cache.

Il est bien sûr nécessaire d’avoir installé et activé le plugin CFG.

Lire aussi
-  Références du plugin CFG sur Spip-Contrib

Ajouts dans le squelette mots

Dans tout squelette mot bien constitué, on trouve normalement une boucle qui compte les éléments associés à un mot, et qui ressemblera plus ou moins à ça :

<B_articles_associes><ul><BOUCLE_articles_associes (ARTICLES){id_mot}>
	<li><a href="#URL_ARTICLE">#TITRE</a>[ - (#SOUSTITRE)]</li></BOUCLE_articles_associes>
</ul></B_articles_associes>

Cette boucle génère une liste non-ordonnée des articles associés au mot portant l’id_mot du contexte (en général celui de la boucle englobante mot_principal dont l’id est récupéré dans l’URL).

De la même manière on trouvera des boucles pour lister les rubriques et les sites associés à ce mot.

<B_rubriques_associees><ul><BOUCLE_rubriques_associees (RUBRIQUES){id_mot}>
	<li><a href="#URL_RUBRIQUE">#TITRE</a></li></BOUCLE_rubriques_associees>
</ul></B_rubriques_associees>

<B_sites_associes><ul><BOUCLE_sites_associes (SITES){id_mot}>
	<li><a href="#URL_SITE">#NOM_SITE</a></li></BOUCLE_sites_associes>
</ul></B_sites_associes>

Il faut récupérer le total de chacune de ces boucles et le traiter pour le transformer en score.

Stockage de chaque total dans une variable

En se servant de la balise #SET{variable, valeur}, on stocke la balise #GRAND_TOTAL de chaque boucle (ou #TOTAL_BOUCLE si les résultats ne sont pas paginés).

<B_articles_associes><ul><BOUCLE_articles_associes (ARTICLES){id_mot}>
	<li><a href="#URL_ARTICLE">#TITRE</a>[ - (#SOUSTITRE)]</li></BOUCLE_articles_associes>
</ul>#SET{articles,#GRAND_TOTAL}</B_articles_associes>

<B_rubriques_associees><ul><BOUCLE_rubriques_associees (RUBRIQUES){id_mot}>
	<li><a href="#URL_RUBRIQUE">#TITRE</a></li></BOUCLE_rubriques_associees>
</ul>#SET{rubriques,#GRAND_TOTAL}</B_rubriques_associees>

<B_sites_associes><ul><BOUCLE_sites_associes (SITES){id_mot}>
	<li><a href="#URL_SITE">#NOM_SITE</a></li></BOUCLE_sites_associes>
</ul>#SET{sites,#GRAND_TOTAL}</B_sites_associes>

Notez que la balise #SET doit se trouver hors de la boucle qu’elle compte (pour ne pas être itérée), mais dans la partie optionnelle après pour pouvoir récupérer la balise de comptage : soit entre </BOUCLE_xxx> et </B_xxx>.

Traitement des variables : calcul et stockage du score

Pour calculer et stocker le score de chaque mot, on utilise une fonction php (à ajouter au fichier mes_fonctions.php qu’il faut créer au besoin si aucune fonction n’est déjà définie)

On envoie le résultat à la fonction nuage_score() en ajoutant dans le squelette mot.html la balise suivante, après les boucles présentées plus haut :

[(#ID_MOT|nuage_score{#GET{rubriques},#GET{articles},#GET{sites}})]

Voici la fonction nuage_score()à ajouter à mes_fonctions.php :

function nuage_score($sent, $rub='0', $art='0', $lnk='0') {
	$valeur_rubrique = 2;
	$valeur_article = 1;
	$valeur_site = 0.25;
	$score = ($valeur_rubrique * $rub + $valeur_article * $art + $valeur_site * $lnk);
	ecrire_config('nuage/scores/' .$sent, $score);
	$max = lire_config('nuage/scores/max');
	$min = lire_config('nuage/scores/min');
	if ($max < $score){
		ecrire_config('nuage/scores/max', $score);
	};
	if ($min > $score) {
		ecrire_config('nuage/scores/min', $score);
	};
	return "";
};

Le score est calculé de la manière suivante :

  • 2 points sont donnés pour chaque rubrique associée à ce mot clé,
  • 1 point pour chaque article associé et
  • 1/4 de point pour chaque site associé.

Remarques
Ces valeurs sont complètement arbitraires et peuvent bien évidemment être modifiées.

Le calcul du score de chaque mot utilise les boucles du squelette mot.html correspondant, et n’est pas recalculé tant que ces pages ne sont pas mises à jour. Si par exemple la page d’un mot-clé n’est jamais affichée, le score de ce mot-clé n’est pas mis à jour non plus. Par contre, chaque fois qu’une page du squelette mot.html est recalculée, le nuage est mis à jour sur l’ensemble des pages où il est affiché, à condition de bien utiliser des inclusions indépendantes (sans le #).

Affichage du nuage

La structure de base du nuage est minimaliste, il s’agit d’une simple liste non ordonnée des mots-clés.

<ul>
	<li><a href="url_mot1">titre_mot1</a></li>
	<li><a href="url_mot1">titre_mot1</a></li>
	...etc.
	<li><a href="url_motn">titre_motn</a></li>
</ul>

La taille de chaque mot clé est définie par un peu de css en ligne, soit pour chaque ligne :

<li><a href="url_motn" style="font-size:taille_motn">titre_motn</a></li>

On peut pour chaque mot récupérer le score qui est enregistré dans la base de données. Néanmoins, pour calculer la taille on ne peut appliquer un coefficient fixe. En effet, si on souhaite que le mot ayant le score le plus bas et celui ayant le score maximum aient toujours la même taille, quel que soit son score, il faudra tenir compte de ces valeurs pour calculer le coefficient.

Au début de la boucle, on récupère les valeurs min et max qu’on stocke dans des variables SPIP :

#SET{min,#CONFIG{nuage/scores/min}}#SET{max,#CONFIG{nuage/scores/max}}

On récupère le score de chaque mot avec la balise #CONFIG{nuage/scores/#ID_MOT}

Pour calculer la taille de chaque mot, on filtre le score en transmettant les valeurs min et max à une nouvelle fonction.

Balise d’affichage de la taille :

[(#CONFIG{nuage/scores/#ID_MOT}|nuage_taille{#GET{min},#GET{max}})]

La fonction nuage_taille() est également à ajouter au fichier mes_fonctions.php

function nuage_taille ($sent, $min='0', $max='1')
{
if ($sent <> "0") {
	$base = 0.85;
	$ecart = 1.5;
	$taille = ($sent - $min) / ($max - $min) * $ecart + $base;
	$taille = round ($taille, 2);
	return $taille;
	}
};

Ce qui donne pour le fichier nuage.html

#CACHE{3600*12}
#SET{min,#CONFIG{nuage/scores/min}}#SET{max,#CONFIG{nuage/scores/max}}<B_lesmots><ul><BOUCLE_lesmots (MOTS)>[
	<li><a style="font-size:(#CONFIG{nuage/scores/#ID_MOT}|taille_mot{#GET{min},#GET{max}})em;" href="#URL_MOT">#TITRE</a></li>] </BOUCLE_lesmots>
</ul></B_lesmots>

Personnalisation du nuage

CSS
On peut faire passer une classe en paramètres à l’appel de l’inclusion du squelette pour appliquer des attributs css aux balises de la boucle. Ou plus simplement en stylant à partir de l’élément parent. On peut donc afficher le même fichier inclus dans différents contextes avec différents rendus.

Paramètres du score
Les valeurs des éléments associés aux mots-clés sont définies dans la fonction nuage_score()

$valeur_rubrique = 2;
$valeur_article = 1;
$valeur_site = 0.25;

Ces valeurs numériques peuvent être changées, ou rendues paramétrables dans l’espace privé à partir d’un formulaire CFG.

Paramètres de la taille
Les valeurs de base de la taille d’affichage des mots-clés en fonction de leur score sont définies dans la fonction nuage_taille()

$base = 0.85;
$ecart = 1.5;

La base représente la taille du plus petit mot-clé, l’écart ce qui la sépare de la taille du plus grand. Ces valeurs numériques peuvent être changées, ou rendues paramétrables dans l’espace privé à partir d’un formulaire CFG.

Tri des mots-clés

Par défaut, aucun critère n’est précisé pour définir l’ordre d’affichage des mots clés ou en exclure certains, on peut bien sûr en ajouter.

  • <BOUCLE_lesmots (MOTS){par type, titre}> pour classer les mots par groupe et alphabétiquement dans un groupe.
  • <BOUCLE_lesmots (MOTS){type!==^_}> est très pratique : tous les mots provenant de groupes dont le nom commence par un underscore « _ » sont exclus. Si on utilise des mots-clés non sémantiques qu’on souhaite exclure du nuage, il suffit de les placer dans un groupe dont le nom commence par « _ », par exemple « _administration ».

Paramétrage avec CFG

Les paramètres de calcul du score, ainsi que ceux de l’affichage, peuvent être paramétrés dans le fichier mes_fonctions.php. Ils peuvent également être modifiés dans l’espace privé au moyen d’un formulaire CFG, qui stockera les valeurs choisies dans la base de données.

Mise en place du formulaire
Enregistrer dans le dossier fonds du squelette ou du dossier plugins/cfg le fichier cfg_nuage.html

<!-- titre=Nuage - paramétrage du nuage de mots-clés-->
<!-- descriptif=Permet de définir la taille des mots du nuage de mots clés et les modalités de calcul du score des mots--> 
<!-- nom=nuage -->
<!-- casier=settings -->

<form method="post" action="#SELF"><div>[(#ENV{_cfg_}|form_hidden)]

<fieldset>
	<legend>Tailles des mots</legend>
	<p><label for id="base">Taille du plus petit mot-clé</label></p>
	<p><input type="text" name="base" value="#ENV{base}" />em</p>
	<p><label for id="ecart">Ecart jusqu'au plus grand mot-clé</label></p>
	<p><input type="text" name="ecart" value="#ENV{ecart}" />em</p>
</fieldset>

<fieldset>
	<legend>Calcul du score</legend>
	<p><label for id="rub">Rubriques</label></p>
	<p><input type="text" name="rub" value="#ENV{rub}" />pts</p>
	<p><label for id="art">Articles</label></p>
	<p><input type="text" name="art" value="#ENV{art}" />pts</p>
	<p><label for id="lnk">Sites</label></p>
	<p><input type="text" name="lnk" value="#ENV{lnk}" />pts</p>
</fieldset>

<p><input type="submit" name="_cfg_ok" value="<:OK:>" />
<input type="submit" name="_cfg_delete" value="<:Supprimer:>" /></p>

</div></form>

On accède ensuite au formulaire par l’espace privé.

Récupération des valeurs du formulaire

La fonction nuage_score() peut désormais récupérer les valeurs saisies dans le formulaire plutôt que des valeurs fixes.

function nuage_score($sent, $rub='0', $art='0', $lnk='0') {
	$valeur_rubrique = lire_config('nuage/settings/rub');
	$valeur_article = lire_config('nuage/settings/art');
	$valeur_site = lire_config('nuage/settings/lnk');
	$score = ($valeur_rubrique * $rub + $valeur_article * $art + $valeur_site * $lnk);
	ecrire_config('nuage/scores/' .$sent, $score);
	$max = lire_config('nuage/scores/max');
	$min = lire_config('nuage/scores/min');
	if ($max < $score){
		ecrire_config('nuage/scores/max', $score);
	};
	if ($min > $score) {
		ecrire_config('nuage/scores/min', $score);
	};
	return "";
};

Les paramètres base et écart sont communs à tous les mots du nuage, on les récupèrera donc une seule fois avant le début de la boucle, et on les passe en paramètres à la boucle nuage_taille en même temps que le minimum et le maximum.

Le squelette nuage.html doit donc être modifié comme ceci :

#CACHE{3600*12}
#SET{min,#CONFIG{nuage/scores/min}}#SET{max,#CONFIG{nuage/scores/max}}#SET{base,#CONFIG{nuage/settings/base}}#SET{ecart,#CONFIG{nuage/settings/ecart}}<B_lesmots><ul><BOUCLE_lesmots (MOTS)>[
	<li><a style="font-size:(#CONFIG{nuage/scores/#ID_MOT}|taille_mot{#GET{min},#GET{max},#GET{base},#GET{ecart}})em;" href="#URL_MOT">#TITRE</a></li>] </BOUCLE_lesmots>
</ul></B_lesmots>

Et la fonction nuage_taille() doit également être modifiée pour utiliser les variables qu’on lui fait passer :

function nuage_taille ($sent, $min='0', $max='1', $base=1, $ecart=1.5)
{
if ($sent <> "0") {
	$taille = ($sent - $min) / ($max - $min) * $ecart + $base;
	$taille = round ($taille, 2);
	return $taille;
	}
};

Exemples

Ce nuage est utilisé sur les sites suivants :
-  Another teacher’s website
-  OpenEnglishWeb

Help wanted

Je ne comprends pas grand chose à ce qui se passe sous le capot de spip, et je n’ai aucune certitude quant au bien-fondé de certains choix que j’ai dû faire. Il doit y avoir très très moyen d’optimiser l’écriture des scores et des paramètres dans la base de données, et je suis preneur de toute indication et de tout conseil sur ce sujet. Merci !

Discussion

2 discussions

  • hello

    je ne crois pas que cette contrib marche mieux ou moins bien que le plugin nuage. elle fait moins de choses en tout cas (pas de prise en compte de la popularité par exemple), mais elle est très économe en ressources.

    pour l’intégration au code il y a :

    -  des fonctions à ajouter au fichier mes_fonctions.php (nuage_score et nuage_taille)
    -  des balises à ajouter dans le squelette mots.html
    -  un fichier nuage.html à ajouter au dossier des squelettes de ton site
    -  une inclusion à ajouter dans les squelettes pour afficher le nuage
    -  la feuille de style à adapter pour intégrer le nuage à l’habillage
    -  éventuellement, un formulaire CFG à ajouter dans le dossier fonds

    Tout est à copier-coller depuis l’article, avec deux possibilités : avec formulaire CFG ou sans.

    Il est clair que ça n’est pas aussi simple que d’installer un plugin...

    Mais quoi qu’il en soit tu as raison, ça n’est pas super clair, je vais regrouper les snipets de code dans un zip et les proposer à télécharger.

    Répondre à ce message

  • Bonjour k3utchi,

    Merci pour cette contrib, je trouve que ton nuage de mots-clés marche mieux que les deux autres contribs dans le même genre trouvées sur spip-contrib ;-)

    Par contre, étant débutant sur Spip, je ne m’y retrouve plus trop dans cette nouvelle page !

    Pourrais-tu STP préciser simplement quel est le code final à intégrer sur nos sites et à quel endroit ?

    MERCI !

    Répondre à ce message

Ajouter un commentaire

Qui êtes-vous ?

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

Dernière modification de cette page le 4 octobre 2011