Une fonction pour vérifier l'usage de <modeles> dans un #TEXTE ?

Bonjour,

Je cherche à réaliser un tableau de suivi d’intégration d’articles.
Certains sujets nécessitent d’utiliser des modèles pour pouvoir être publiés.
Par exemple le texte d’un article devra utiliser au moins un modèle <imagexx> et deux modèles <tableauxx> pour être publiable.

Dans un premier temps, je cherche simplement à réaliser une fonction qui prendrait un #TEXTE comme paramètre et pourrait me retourner un tableau des modèles utilisés au sein du texte.

Est-ce que des fonctions natives exploitables et sa rapprochant plus ou moins existent déjà ?

Dans le code de SPIP, je découvre la Classe Modeles.php : https://search.spip.net/git.spip.net/spip/spip/-/blob/ecrire/src/Texte/Collecteur/Modeles.php

Cela semble s’approcher de ce que je recherche, mais certainement trop bas niveau pour que je puisse m’appuyer dessus…

Auriez-vous des pistes/idées pour gérer cela proprement ?

J’ai pu avancer en tentant via SQL une requête de ce type :

SELECT 
    id_lieu
FROM 
    spip_lieux
WHERE 
    texte REGEXP '<image[0-9]+>'
GROUP BY
    id_lieu;

La REGEXP fonctionne, mais MARIADB en version 10 ne prend malheureusement pas en charge la fonction SQL REGEXP_COUNT qui aurait pu permettre de compte le nombre de modèles utilisés, représentés par la REGEXP.

J’ai bien trouvé une voie de contournement mais je ne la trouve pas satisfaisante :

SELECT 
    id_lieu,
    SUM(
        (LENGTH(texte) - LENGTH(REPLACE(texte, '<image', ''))) / LENGTH('<image')
    ) AS modeles_image
FROM 
    spip_lieux
WHERE 
    texte REGEXP '<image[0-9]+>'
GROUP BY
    id_lieu;

Je préfèrerai donc gérer cela via PHP plutôt qu’en SQL…

Ça semble la bonne piste car c’est bien ce que le core utilise pour détecter les modèles dans les textes des objets cf Sourcegraph & Sourcegraph

Bonjour @Pierre_Jean,

Et si tu prenais le problème autrement ?
Normalement si tes modèles sont bien déclarés, quand ils sont ajoutés dans le #TEXTE d’un contenu éditorial, tu dois pouvoir faire une boucle avec le critère {vu} pour les sélectionner non ?

Plutôt que de faire une requête SQL avec du regex, une boucle avec jointure du type :

<BOUCLE_d(spip_documents_liens lieux) {objet = lieu} {vu=oui}>
	#ID_DOCUMENT
</BOUCLE_d>

J’ai pas testé, mais ça pourrait être une piste à creuser

Merci pour ton retour.

Malheureusement, je cherchais ici à tester l’usage de modèles qui ne bénéficient pas de liaisons avec la table de documents, comme des modèles de citation, ou des modèles générant des tableaux (des noisettes custom appelées via un dans les #TEXTE.

Pour retrouver d’ancien appel de modèle avant que le modèle concerné ne soit en place ?

Exemple avec le modèle fictif modeles/citation.html qui contient :

<BOUCLE_citation(CITATIONS){id_citation=#ENV{id}}{0,1}>
<blockquote>
#TEXTE_CITATION
</blockquote>
</BOUCLE_citation>

Ce modèle est par exemple ensuite appelé dans le #TEXTE d’un article lambda via :

<citation15>

Mon objectif était via une requête SQL de pouvoir déterminer quels étaient les articles dont la colonne texte (#TEXTE) inclue au moins un modèle de type citation via une regexp du type :

'<citation[0-9]+>'

Avec MariaDB comme moteur SQL, cela ne passe pas, du coup je me suis rabattu sur une fonction PHP dédiée à laquelle je fais passer en entrée le #TEXTE et le type de modèle que je cherche à l’intérieur afin de déterminer combien de fois il est appelé :

# Compter le nombre de modèles dans une chaîne de texte
# Utilisé par maj_lieux_modeles()
function compter_modeles($texte, $nom_modele) {
	
	$regexp = '/<' . $nom_modele . '[0-9]+>/';
    preg_match_all($regexp, $texte, $correspondances);
    
    // Compter le nombre total d'occurrences trouvées
    $nombre_modeles = count($correspondances[0]) ?? 0;
    
    return $nombre_modeles;
	
}

Ok, je vois mais du coup pour en revenir à ma suggestion précédente :

// Ajouter le modèle citation à la liste des modèles de documents
function prefixeduplugin_declarer_tables_objets_sql($tables){
	$tables['spip_documents']['modeles'][] = 'citation';
	return $tables;
}

Avec bien sur dans le paquet.xml du plugin <pipeline nom="declarer_tables_objets_sql" inclure="prefixeduplugin_pipelines.php" />

Et ensuite dans ton squelette (ici lieux étant le nom de ta table mais ça peut être articles, ou ce que tu veux)

<BOUCLE_d_vu(spip_documents_liens lieux) {objet = citation} {vu=oui}>
	VU : #ID_DOCUMENT
</BOUCLE_d_vu>
<BOUCLE_d_pas_vu(spip_documents_liens lieux) {objet = citation} {vu=non}>
	PAS VU : #ID_DOCUMENT
</BOUCLE_d_pas_vu>
2 « J'aime »

D’ailleurs attention à ta regex qui ne marchera pas si ton modèle est appelé avec des paramètres, tu devrais reprendre la regex de SPIP (présente dans le fichier ecrire\src\Texte\Collecteur\Modeles.php) en l’adaptant :

$regexp = 
	'@<('.$nom_modele.')' # <modele
	. '\s*([0-9]*)\s*' # id
	. '([|](?:<[^<>]*>|[^>])*?)?' # |arguments (y compris des tags <...>)
	. '\s*/?' . '>@isS' # fin du modele >
;

Très intéressant @jo_ac_OT , je n’avais aucunement connaissance de la possibilité de déclarer « proprement » des modèles…

Mais, je ne comprends pas pourquoi cela se ferait sur spip_documents. Quel lien avec un modèle lambda de citation comme dans mon exemple ?

Ok pour un modèle lié à une image, une vidéo, un pdf… quelquechose de lié à un véritable objet document, mais dans les cas que je décris, les modèles n’ont pas de rapport avec un document présent sur le site.

À moins que l’on puisse déclarer de nouvelles entrès de modèles pour les tables de liaisons d’autres objets du style :

$tables['spip_lieux']['modeles'][] = 'citation';

C’est de quelque chose comme ça dont tu parles ?

Alors je ne suis pas expert, et j’avais trouvé des exemples en fouillant dans le code source d’autres plugins. Mais c’est vrai que la doc est quasi inexistante, je n’arrive pas à la retrouver.

Tu peux regarder de ce coté la : Sourcegraph

Tous ce que j’en ai compris/testé c’est que ça te permet de passer automatiquement à vu un modèle déclaré si il est présent dans le #texte ou le #chapeau d’un contenu éditorial.

1 « J'aime »

Intéressant, je vais fouiller, il faudrait juste que ce mécanisme soit aussi adaptée à d’autres tables de liaison, et ça serait bingo !

Merci !

Si tu trouves comment faire, je suis preneur, partages ton code :slight_smile:

À noter que le plugin rechremp Rechercher/Remplacer - Plugins SPIP permet de faire ces recherches dans une page de l’espace privé.

  • de manière accessible à tous avec <citation qui devrait suffire la plupart du temps
  • soit avec regexp