Annuaire d’auteurs avec Spip Bonux

This is an « educational contribution » which shows, with concrete example, how to develop a new functionality for SPIP.

Pour ceux qui ont besoin de présenter un annuaire des auteurs d’un site, plusieurs contributions existent dont:
-  Tri alphabétique des auteurs de Erational

Je me suis inspiré de cette contribution, à laquelle j’ai intégré l’apport de Spip Bonux quant à la gestion des tableaux (#ARRAY), notamment la balise #SET_PUSH.

J’utilise notamment le filtre proposé par Erational qui permet de rechercher la première lettre du dernier mot du champs #NOM de l’auteur. Ainsi Harry Cover sera pointé par la lettre C. J’y ai ajouté un petit filtre permettant de trier les tableaux.

Le principal apport de cette nouvelle contribution est d’ordre pédagogique et permettra peut-être à ceux qui cherchent de s’y retrouver. D’un point de vue fonctionnel, l’évolution porte sur la présentation et les fonctions par défaut:

-  navigation dans une barre alphabétique complète (façon répertoire)
-  seules les lettres comprenant des auteurs ont des liens actifs, et leur présentation peut être distinguée via CSS
-  par défaut, la barre s’active sur la première lettre comprenant des auteurs.

Tout cela est inclus dans un modèle, le fichier annuaire.html qui est appelé par la balise [(#MODELE{annuaire}{lettre=#ENV{lettre}})] ou lettre est la variable de choix, si elle existe.

Barre de navigation alphabétique
Barre de navigation alphabétique

Pour mémoire: le filtre proposé par Erational

// ---------------------------------------
// Filtre lastfirstletter
// extrait la première lettre du dernier mot et la passe en majuscules
// ex. marcel duchamp -> D
// ---------------------------------------
function lastfirstletter($texte) {

  $pos = strrpos(trim($texte), " ");
  if ($pos === false) { // pas trouvé -> 1er lettre
      $texte = $texte{0};
  } else {
      $texte = $texte{$pos+1};
  }
	// remplacement des caractères accentués
	$texte = strtr($texte, "\xA1\xAA\xBA\xBF\xC0\xC1\xC2\xC3\xC5\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD8\xD9\xDA\xDB\xDD\xE0\xE1\xE2\xE3\xE5\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF8\xF9\xFA\xFB\xFD\xFF", "!ao?AAAAACEEEEIIIIDNOOOOOUUUYaaaaaceeeeiiiidnooooouuuyy");
	$texte = strtr($texte, array("\xC4"=>"Ae", "\xC6"=>"AE", "\xD6"=>"Oe", "\xDC"=>"Ue", "\xDE"=>"TH", "\xDF"=>"ss", "\xE4"=>"ae", "\xE6"=>"ae", "\xF6"=>"oe", "\xFC"=>"ue", "\xFE"=>"th"));
	$texte = strtoupper($texte);          // tout en majuscules
	if (is_numeric($texte)) $texte = "";  // on supprime les chiffres
	return $texte;
	
} // lastfirstletter

// ajout filtre de tri de tableaux

function array_sort($tableau) {
	sort($tableau);
	return $tableau;
}

Le modele annuaire.html

Initialisation

Dans un premier temps, on va initialiser plusieurs tableaux:

  • un tableau alphabet, reprenant ... l’alphabet
  • une série de X tableaux commence_parX : tableau de chaque lettre avec les ID AUTEUR correspondant. Ex: commence_parT contient tous les auteurs dont le nom commence par T
  • un tableau comprenant les lettres utiles (permet de différencier les lettres ayant un auteur des autres) : auteurs_alpha

L’utilisation de #SET_PUSH de Spip-Bonux rend les choses particulièrement faciles.

[(#SET{alphabet, [(#VAL{ABCDEFGHIJKLMNOPQRSTUVWXYZ}|str_split)]})]

<BOUCLE_listalpha(AUTEURS){par nom}{tout}>
[(#SET_PUSH{commence_par[(#NOM|lastfirstletter)],#ID_AUTEUR})]
[(#SET_PUSH{auteurs_alpha,#NOM|lastfirstletter})]
</BOUCLE_listalpha>
#SET{mondebut,#GET{auteurs_alpha}|array_sort|table_valeur{0} }

Construction de la barre de navigation alphabétique

On balaie le tableau alphabet et pour chaque valeur, on contrôle si celle-ci est présente dans le tableau beginalpha.

  • Si c’est le cas, on pose un lien avec une balise #SELF agrémentée de la lettre pointée (variable lettre). Dans le même temps, on affecte la classe “plein” à la balise li correspondante, pour un traitement par CSS.
  • Dans le cas contraire, on affiche simplement la lettre, sans style particulier ni lien.
  • La barre utilise par defaut la première valeur du tableau beginalpha.
<B_alphabet>
<div class="alphabet">
<ul>
<BOUCLE_alphabet(POUR){tableau #GET{alphabet}}>
<li class='[(#VALEUR|=={[(#ENV{lettre,#GET{mondebut} })]}|?{on})] [(#VALEUR|in_array{#GET{auteurs_alpha}}|oui)plein]'>[(#VALEUR|in_array{#GET{auteurs_alpha}}|oui)<a href="[(#SELF|parametre_url{lettre,#VALEUR})]">]#VALEUR</li>[(#VALEUR|in_array{#GET{auteurs_alpha}}|oui)</a>]
</BOUCLE_alphabet>
</ul>
</div>
</B_alphabet>

Affichage des résultats

Une dernière boucle va sélectionner les auteurs correspondant

  • soit à la lettre cliquée
  • soit à la première lettre comportant des auteurs (valeur par défaut).

Dans le premier cas, la boucle va balayer le tableau beginbyX ou X est la valeur de la lettre choisie.

[(#REM) Traitement des listes d'auteurs
- on peut aussi utiliser un modele d'affichage ]

<B_artlettre>
<div class="liste_auteur">
<BOUCLE_artlettre(AUTEURS){id_auteur IN #GET{commence_par#ENV{lettre,#GET{mondebut} }}}{tout}>
<a href="#URL_AUTEUR">#NOM</a><br />  
</BOUCLE_artlettre>
</div>
</B_artlettre>

Naturellement, il s’agit là d’un traitement de données très basique. On peut construire, à sa guise, un modèle d’affichage qui reprendra les informations complètes de l’auteur où celles gérées par le plugin Inscription2.

La finition par les styles CSS

Il suffit de quelques styles CSS pour obtenir ce que vous voudrez de ce modèle. Voici, pour exemple, un ensemble de style que j’ai utilisé pour obtenir le résultat affiché plus haut.

div.alphabet{
	font-family: Arial, Helvetica, sans-serif;
	font-size: 9px;
	color: #999;
}
div.alphabet ul{
	margin:0;
	padding:0;
}
div.alphabet ul li{
	margin:0;
	padding:0;
	display:inline-block;
	width:10px;
	text-align:center;	
	padding:2px;
	margin-right:2px;
	background-color: #E3E3E3;
	border: 1px solid #E3E3E3;	
}
div.alphabet ul li.on{
	background-color: #006;
}
div.alphabet ul li.plein{
	border: 1px solid #666;
}
div.alphabet ul li a{
	display:inline-block;
	width:10px;	
	text-align:center;	
}

div.alphabet ul li a:hover{
	color:#006;
	text-decoration:none;
	font-weight:bold;
}
div.alphabet ul li.on a{
		color: #fff;
		font-weight:bold;
		text-decoration:none;
}

updated on 9 February 2019

Discussion

6 discussions

  • Bonjour

    Tout d’abord veuillez excuser mon ignorance profonde, mais apprécié mes efforts ;-)

    Je vais essayé d’être le plus clair possible sans être trop long.

    Je cherche à faire un annuaire pour mon site. Ce qui suit est dans l’idéal et je suis bien conscient que cela s’opère étapes par étapes.

    Dans l’idéal, j’aimerais :
    1) que cet annuaire se remplisse automatiquement à partir des auteurs du site
    2) qu’il soit possible de classer les auteur par ordre alphabétique “vrai” (complet pas Albert Dupontel qui apparait avant Donald Duck)
    3) qu’à l’affichage, il soit mentionné Duck Donald ou Dupontel Albert (et non Donald Duck ou Albert Dupontel)
    4) que les administrateurs soient en mesure de n’afficher que certains auteurs en filtrant ceux qui ne remplisse pas certaines conditions (par exemple seuls les rédacteurs soient affichés, pas les visiteurs, ou que les auteurs dont le champ adresse mail est rempli...)
    5) ajouté des champs au sujet des auteurs (par ex. photo, organisme de rattachement, etc.)
    6) que l’on puisse faire la distinction entre une entrée d’annuaire correspondant à un individu et une entrée d’annuaire correspondant à une organisation (ce qui implique d’ajouter un champ au sujet de l’auteur pour faire la distinction entre ces deux types d’auteurs.
    7) pouvoir afficher les entrées de l’annuaire dans un article avec pourquoi pas la barre de navigation alphabétique que vous proposez plus haut
    8) de pouvoir n’afficher que les entrée de l’annuaire correspondantes à une organisation

    J’ai passé 2 jours à lire et essayé de comprendre comment faire à partir de nombreux liens et tout particulièrement :
    -  http://contrib.spip.net/Tri-alphabetique-tout-en-SPIP
    -  http://contrib.spip.net/Tri-alphabetique-des-auteurs
    -  http://contrib.spip.net/Un-annuaire-bien-range-avec-ENV

    ainsi que
    -  http://forum.spip.net/fr_191645.html et les liens qu’il propose, ce qui par la suite m’a amené à au plugin “formidable” et “formitable” et la doc qui va avec... pour créer un formulaire permettant au gens de remplir leur fiche contact,etc...

    bref...

    Je suis loin d’être un pro de la prog, mais je m’en sort toujours avec un tutoriel bien fait détaillé, précis quoi. Je suis capable d’adapté un bout de code à mes besoin si il est commenté avec précision, qu’il est précisé dans quel fichier et où dans le code il faut copier le bout de code, etc.)

    Pour vous dire franchement en essayant d’y aller étapes par étapes, j’ai voulu commencé par suivre la contrib sur le tri alphabétique tout en spip, eh ben je suis resté coincé après la création du ficher mes_fonctions.php

    Je me rend bien compte qu’il y a plusieurs chose dans ma liste des 8 fonctions que je souhaiterais que mon annuaire ait.

    Un exemple d’annuaire qui me plait bien et celui-la
    http://ens.math.univ-montp2.fr/SPIP/sem.php3?a=anuter

    mais franchement la technique proposé dans l’article
    http://contrib.spip.net/Un-annuaire-bien-range-avec-ENV
    donne aucun résultat dans spip 2.19. et c’est pas faute d’avoir fait des centaines de tests.

    Merci de votre aide

    cordialement

    Jo

    Reply to this message

  • patrice47310

    Bonjour,

    j’ai d’installé cette contrib sur spip 2.1.8 tout fonctionne bien sauf que ma barre de navigation alphabétique est vertical.
    Est ce que quelqu’un pourrait me dire comment faire pour qu’elle soit horizontale?

    Reply to this message

  • 1

    Bonjour,
    j’ai essayé d’installer cette contrib mais voilà l’erreur que ça me donne :
    3 Erreur(s) dans le squeletteNuméro message squelette boucle Ligne
    1 Filtre lastfirstletter non défini squelettes/modeles/annuaire.html _listalpha 4
    2 Filtre lastfirstletter non défini squelettes/modeles/annuaire.html _listalpha 0
    3 Filtre array_sort non défini squelettes/modeles/annuaire.html / 0

    Est-ce que c’est compatible avec spip 2.1 et la dernière version de spip-bonux ?

    Reply to this message

  • 2

    Bonjour,

    Cette contribution est très utile mais les résultats (les auteurs dont le nom commence par une même lettre) ne sont pas classés par ordre alphabétique. Dupont sera par exemple avant Dartagnan.

    Une solution ?

    Merci.

    • Heureusement, il n’y a pas de confusion possible parmi les 4 mousquetaires (blague du soir, espoir)

    • En effet, la boucle <BOUCLE_listalpha(AUTEURS){par nom}{tout}> classe le champ #NOM par ordre alphabétique, donc:

      • Albert Dupont -> A
      • Bob Dylan -> B
      • Charles d’Artagnan -> C

      Deux solutions:

      -  Soit modifier la contrib actuelle et ajouter le “nom” (dernier mot du champ #NOM) dans les tableaux “commence_par”. On pourra alors trier les tableaux, par exemple dans la boucle alphabet, pour que la boucle auteurs suivante les affiche dans le bon ordre.

      Reste à savoir ce qu’il advient de “Robert Van Piperzeel” qui sera classé à P et non à V...

      -  Soit encoder les noms d’auteurs sous la forme “Dupont, Albert” et “Van Piperzeel, Robert”. Ceci a pour avantage que le classement et la séparation entre nom et prénom font l’objet d’un traitement humain un peu plus intelligent que strrpos!

      Dans la fonction lastfirstletter, il faudra remplacer:

      $pos = strrpos(trim($texte), " ");
        if ($pos === false) { // pas trouvé -> 1er lettre
            $texte = $texte{0};
        } else {
            $texte = $texte{$pos+1};
        }

      par

      $texte = $texte{0};

      En effet, on ne cherche plus la première lettre du dernier mot mais la première lettre tout court.

      On pourra aussi facilement créer un filtre qui remet “Dupont, Albert” en “Albert Dupont” grâce aux fonctions explode, array_reverse et implode de PHP.

    Reply to this message

  • 3

    En fait, c’est plus compliqué, il faut :

    1. [(#SET{alphabet, [(#VAL{ABCDEFGHIJKLMNOPQRSTUVWXYZ}|str_split)]})]
    • Effectivement, c’est beaucoup plus simple comme cela. J’intègre cette modification avec mes remerciements

    • hélas, trois fois hélas, la fonction str_split() n’existe qu’à partir de php5...
      mais comment vont faire tous ceux dont le serveur tourne encore avec un (vieux) php4 ?

      c’est à peine plus compliqué (bien que de plus en plus abscons...) en utilisant la bonne vieille (et robuste) fonction preg_split [1]:

      [(#SET{alphabet,
      #VAL{'//'}|preg_split{'ABCDEFGHIJKLMNOPQRSTUVWXYZ', -1, 1}
      })]


      le dernier argument «1» signifiant :
      «à exécuter avec le flag PREG_SPLIT_NO_EMPTY»

    • Voir http://us2.php.net/manual/en/functi...

      à mettre dans config/mes_options.php :

      if(!function_exists('str_split')) {
        function str_split($string,$string_length=1) {
          if(strlen($string)>$string_length || !$string_length) {
             do {
                $c = strlen($string);
                $parts[] = substr($string,0,$string_length);
                $string = substr($string,$string_length);
             } while($string !== false);
          } else {
             $parts = array($string);
          }
          return $parts;
        }
      }

    Reply to this message

  • Je pense que :

    1. #SET{alphabet, #ARRAY{0,'A',1,'B',2,'C',3,'D',4,'E',5,'F',6,'G',7,'H',8,'I',9,'J',10,'K',11,'L',12,'M',13,'N',14,'O',15,'P',16,'Q',17,'R',18,'S',19,'T',20,'U',21,'V',22,'W',23,'X',24,'Y',25,'Z'}}

    Peut s’écrire plus simplement par quelque chose d’approchant:

    1. [(#SET{alphabet,[(#VAL{ABCDEFGHIJKLMNOPQRSTUVWXYZ}|explode{''})]})]

    Ou l’inverse, je ne sais plus :

    1. [(#SET{alphabet,[(#VAL{''}|explode{ABCDEFGHIJKLMNOPQRSTUVWXYZ})]})]

    Reply to this message

Comment on this article

Who are you?
  • [Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom