Carnet Wiki

ccmCréerMaBaliseAMoi...

Version 5 — Mars 2013 — Nicolas Hoizey

Voilou, cette page du spikini pour mettre le résultat de mes recherches pour pouvoir créer ses balises (merci à James pour sa contrib #TITRE_PARENT !)

Lors de la création d’un plugin, il est souvent nécessaire d’utiliser des balises qui ne correspondent pas forcément directement au nom des colonnes des nouvelles tables. Par exemple on pourrait nécessiter une balise qui provienne du résultat d’une requête entre deux des nouvelles tables. Dans ce cas, en sus des nouvelles tables proprement dites, il est nécessaire de créer de nouvelles balises.

Au fil de l’épluchage des plugins déjà écrits par les « pionniers », j’ai pris conscience que les balises SPIP pouvaient être de 2 types :

-  des balises de type « indépendant » : elles peuvent être appelées dans ou hors d’une boucle. Par exemple la balise #NOM_SITE_SPIP.

-  des balises liées aux boucles : elles retournent un résultat dépendant d’une boucle. Exemple : une balise #TITRE.

S’il s’avère plutôt simple (tout du moins, pas plus compliqué que de créer son propre filtre...) de créer une balise indépendante, il n’en va pas de même pour les balises dépendant d’une boucle, car il faut percevoir comment les paramètres sont véhiculés et transitent entre les différents objets...

Les paramètres passent dans une mystérieuse variable appelée « $p »... Même si quelques explications sont entrevues sur le spikini, c’est tout de même extrèmement confus (pour tous ceux comme moi n’ont pas un bac+8...).

Premiers essais :
les balises #SUIVANT | #PRECEDENT | #PREMIER | #DERNIER

Pour tester le principe, j’ai tenté de me créer une balise (en fait un ensemble de 4 balises...) qui auraient pu me retourner, pour chaque enregistrement d’une boucle quelconque, les id des enregistrements suivants et précédents, ainsi que les id du premier et de dernier enregistrement de la boucle.

Et je suis parvenu à un résultat !

Les filtres qui trouvent les enregistrements... comment dire ? concommitents ?

Les deux premiers filtres sont simples, pour trouver l’id de l’enregistrement qui devra être retourné par la balise #PREMIER, on prend le 1er enregistrement sorti par la requête, triée par ordre croissant. Idem pour le dernier, on prend le 1er enregistrement sorti par la requete, mais cette fois triée par ordre décroissant.

function trouve_premier ($id_element) {
	$nom_champ = "id_article"; // le nom du champ pour "SELECT nom_champ..."
	$nom_table = "spip_articles"; // le nom de la table pour "... FROM nom_table..."
	$critere = "id_article";  // le critère de tri pour "... FROM critere..."
	$sql_premier = 'SELECT '.$nom_champ.' from '.$nom_table.' ORDER BY '.$critere.' ASC LIMIT 1';
	$recup_premier = spip_query($sql_premier);
	while ($premier = spip_fetch_array($recup_premier)) {$id_premier = $premier[$nom_champ];}
	return $id_premier;
}
function trouve_dernier ($id_element) {
	$nom_champ = "id_article"; // le nom du champ pour "SELECT nom_champ..."
	$nom_table = "spip_articles"; // le nom de la table pour "... FROM nom_table..."
	$critere = "id_article";  // le critère de tri pour "... FROM critere..."
	$sql_dernier = 'SELECT '.$nom_champ.' from '.$nom_table.' ORDER BY '.$critere.' DESC LIMIT 1';
	$recup_dernier = spip_query($sql_dernier);
	while ($dernier = spip_fetch_array($recup_dernier)) {$id_dernier = $dernier[$nom_champ];}
	return $id_dernier;
}

Pour le suivant et le précédent, un tout petit peu plus compliqué, car j’ai pris le parti de boucler, c’est à dire que si on est sur le dernier enregistrement, le suivant est le 1er de la liste. Idem pour le 1er de la liste, la valeur de l’enregistrement précédent est le dernier de la liste.

function trouve_suivant ($id_element) {
}

function trouve_precedent ($id_element) {
}

Parmi les améliorations qui pourraient être apportées à ces filtres, la plus compliquée (ou du moins celle que je ne suis pas parvenu à réaliser...) est de les rendre indépendants de la requete dans laquelle on les appelle. Par exemple, si je suis dans une BOUCLE_auteurs, je voudrais trouver les suivant, précédent, premier et dernier des auteurs, donc la requete doit rechercher un id_auteur et non plus un id_article. Ensuite, si dans la boucle on a spécifié un critère de tri, il faudrait que les suivant, précédent, etc tiennent compte cet ordre de tri. Ainsi, il faudrait passer aux filtres 2 paramètres supplémentaires, en sus de l’id de l’élément en cours, qui seraient : le nom de la table, le nom du champ dont on veut trouver le suivant, et le critère de tri. Pour l’instant je ne sais pas extraire ces paramètres de $p, mais je pense que l’on peut y arriver !

Après les filtres, les balises !

Dans leur version simple, les balises retournent juste un numéro. Comme vous l’avez compris, exactement le même résultat aurait pu être obtenu simplement avec un filtre genre (#ID_ARTICLE. Mais je préférait pouvoir utiliser simplement des balise #SUIVANT, #PRECEDENT, etc.

function balise_PREMIER (){
}

function balise_DERNIER (){
}

function balise_SUVANT (){
}

function balise_PRECEDENT (){
}

Voila où j’en suis de mes recherches... J’espère que cela pourra aider certains, et évenuellement susciter des commentaires ou des remarques.


La page de spikini sur la structure des boucles m’a bien aidé à démarrer. A ce jour il me reste néanmoins un certain nombre d’interrogations...

En farfouillant dans balises.php j’ai trouvé les significations suivantes :
-  $p->nom_boucle retourne le nom de la boucle, sans le « BOUCLE » devant... A priori, ça donne la même chose que $p->id_boucle ou $p->descr['id_mere'].

-  $p->descr['source_file'] retourne le chemin des squelettes (équivalent de #CHEMIN ?)

-  il me manque le moyen de lister tous les champs contenus dans $p, et en particulier celui qui sert de clé primaire...

Si on arrive à tout lister, alors c’est la porte ouverte à de nouveaux développements de plugins ! A compléter, donc, au fil de l’eau...