Si vous êtes fidèle à mes publications, vous avez déjà vu passer mon article "Afficher des définitions" il y a quelques semaines, où le but était de créer un glossaire dans un article, cet article ne servant qu'a cela. Mais le travail ici est différent.
Aujourd'hui, je souhaite revenir sur ce travail que j'ai effectué depuis quelques semaines désormais, donc le but est d'écrire un plugin, qui se décompose en deux fonctionnalités :
- La première fonctionnalité se trouve dans des articles, dans lesquels je vais pouvoir "encadrer" de l'information entre tags dans un article, et afficher cette information taguée d'une manière très spécifique dans mon article.
- La deuxième spécificité de mon outil et de pouvoir retrouver dans l'ensemble des articles de Joomla, les informations que j'ai écrite entre ses tags, afin de pouvoir afficher une synthèse.
et dont le but est de centraliser sur un article des définitions disséminées sur d'autres articles ici et là
C'est exactement le même principe sous Word par exemple, où vous "marquez une entrée" dans un index et que vous insérez ensuite la table des index.
Pour mieux comprendre ce que mon outil doit faire, je vous propose l'exemple suivant : imaginons que vous ayez un site internet sur Joomla dont la thématique est relativement spécifique, et que vous devez au fil de vos articles, apporter des définitions de certains termes que vous employez dans votre article. Chacun de ces termes se définit avec deux éléments :
- Le premier est un terme à définir,
- Le deuxième est bien entendu la définition de ce terme.
Chaque fois que vous allez écrire un article, vous allez pouvoir introduire la définition d'un nouveau terme d'un nouveau mot.
L'outil que je vous propose aujourd'hui, va avoir comme but de pouvoir appliquer un style particulier de votre définition à l'endroit où il est défini/marqué, mais surtout, dans un module ou dans un autre article, reprendre l'intégralité des termes sur l'ensemble de votre site; déjà définis, afin d'en faire une "liste détaillée".
Principe de fonctionnement
Nous travaillons ici avec uniquement des plugins de contenu. Ainsi, nous allons au cours de nos articles, définir nos mots que nous souhaitons expliciter, avec une balise dans laquelle nous avons définir le mot ainsi que sa définition. Pour cela, le mot défini doit répondre à une Regex très particulière, et vous pourrez définir vos termes de la manière suivante :
/\{define \((.*)\)(.?)*\((.*)\)/m
Comme vous pouvez le constater dans la définition de cette expresion rationnelle, après le mot-clef define, je passe deux paramètres entre parenthèses (ce qui me permet d'être certain de récupérer ce que je veux) Ainsi, dans un article, si je veux définir un mot, je vais avoir cette ligne :
{define (bogoss) (auteur du site www.sebastien-lhuillier.com)}
- define : c'est le mot clef de mon tag
- (bogoss) - ou premier paramètre- : c'est le terme que vous voulez définir. Les parenthèses son obligtoires ! (elles son utilisées car on peut definr une chainen de plusieurs mots)
- (auteur du site...) - ou deuxieme paramètre : C'est la definition du terme. Là aussi les parenthèses sont obligatoires.
L'utilisation du double tag
Vous l'aurez compris, mon principe repose sur deux éléments :
- le premier élément est un tag déclaratif qui va nous permettre, au cœur d'un article, de pouvoir spécifier au système que nous sommes en train de déclarer un élément. Dans notre exemple, nous déclarons une définition.
- le deuxième tag sur lequel nous allons nous baser est un autre tag de synthèse. Lorsque Joomla rencontrera ce tag, il lui sera ordonné d'exécuter une requête SQL afin de rechercher l'ensemble des articles publiés contenant des definitions, et dans l'extraire au moyen d'une expression rationnelle, le contenu correspondant, dans notre cas, à une définition.
Si je me permets d'insister véritablement sur cette manière de faire, c'est que vous retrouverez donc les prochaines semaines je pense, sur mon site, d'autres utilisation de ce principe, afin de pouvoir aller rechercher au cœur des articles publiés de Joomla content, des informations à synthétiser. Et quand on gère professionnellement une un système documentaire comme je le fais, les applications à ce système ne manquent pas
Je souhaite donc revenir un tout petit instant sur ce dernier terme utilisé, la "synthétisation". J'entends par là l'idée de parcourir l'ensemble des articles Joomla, et d'en extraire les informations qui ont été taguées comme telles, pour pouvoir afficher dans un article, leur synthèse.
Je souhaite aussi revenir sur le plan pratique de cette synthèse, c'est tout bêtement sur une simple requête SQL dans laquelle je recherche parmi mes articles, ceux qui contiennent au moins un tag d'ouverture de mon plugin, ce qui me permet de ne pas parcourir l'ensemble des articles mais uniquement ceux comportant au moins un tag. Une fois que j'ai récupéré l'ensemble de ces enregistrements dans mon curseur, je vais pouvoir les parcourir afin d'en extraire, au moyen d'expression(s) rationnelle(s), le contenu qui m'intéresse.
Arrivé à ce stade, je souhaite faire une petite analyse de cette manière de faire qui pourrait, je vous accorde, être effectuée autrement. En effet, depuis la version 8 de MySQL, ce système de gestion de base de données permet en effet l'extraction d'information au moyen d'expressions rationnelles sans avoir à déléguer ca à PHP. Toutefois, je suis embêté sur deux points sur cette manière de faire.
- Le premier problème réside dans le fait que professionnellement parlant, je ne suis encore pas passé sur la version 8,
- et l'autre point qui m'embête aussi, c'est que la requête utilisée va être propre ou SGBD. Le jour où nous passons de MySQL à PostGre, la requête ne fonctionne plus. C'est la raison pour laquelle, j'écarte un maximum de choses dans mon code PHP afin d'avoir le strict minimum dans mes requêtes SQL à des fins de compatibilité ascendante.
Le tag déclaratif : revenons sur la manière détaillée de son fonctionnement
Comme je vous l'ai spécifié un peu plus haut dans ma prose, mon système repose sur un double tag. Le tag déclaratif est un tag qui permet, au cœur de votre article, de spécifier à Joomla que vous allez à cet endroit-là, spécifier une définition. J'ai opté dans mon tag pour l'utilisation de paramètres spécifiques de manière à ce qu'il se résume à la forme suivante :
{define (mot_ddfini) définition du mot}
Comme vous pouvez le voir dans l'utilisation de mon tag, nous avons deux paramètres :
- le premier correspondant au mot à définir
- le deuxième correspondant à la définition en elle-même du mot.
La Regex qui en découle a donc la forme suivante
/\{define \((.*)\)(.?)*\((.*)\)/m
Si vous avez dans un article Joomla une chaîne de caractères sur cette forme, c'est que nous avons donc à faire à une définition. En l'occurrence, puisque la définition a été écrite dans l'article, le petit programme va en extraire le contenu en suivant l'expression rationnelle, et en afficher et la substantifique moëlle
Le tag de synthétisation
Le tag de synthétisation, comme son nom l'indique, va synthétiser à l'endroit où il est appelé, l'ensemble des informations disséminées dans mes différents articles correspondant à l'expression rationnelle définie.
Dans mon cas, je n'utilise pas d'expression de ce type dans des modules, tout se trouve dans des articles. C'est la raison pour laquelle, bien que cela puisse être faisable avec des modules, je ne garantis pas son utilisation correcte de ce plugin si vous mettez des contenus de mon type dans les modules.
Toutefois, le code peut-être facilement modifiable, dans la mesure où nous utilisons la propriété texte de l'objet article pour afficher les données, vous pouvez réutiliser mon code pour aller chercher le contenu texte d'un module. Je n'ai pas regardé comment cela fonctionnait, mais je reste convaincu que cela ne doit pas être bien compliqué.
Le principe de ce tag de synthétisation repose sur une simple requête qui va rechercher l'ensemble des articles publiés dans Joomla, et je vais, pour chacun d'entre eux, extraire le contenu de l'article, le passer dans une moulinette à expressions rationnelles pour en extraire les informations qui m'intéressent. Si le contenu de l'article contient ces expressions répondant à ma règle, alors je les mets de côté afin de synthétiser à la fin du plugin.
Je concatène dans une chaîne de caractères ce que je souhaite afficher à l'utilisateur, et mon plugin, dans sa toute dernière ligne de code, va remplacer une tag défini pour afficher cette liste par le contenu qui aura récupéré de l'ensemble des articles, par le récultat de ma concaténation.
Parmi les mises en garde que je dois faire, contrairement à ce qui est écrit dans ma requête, vous pouvez rajouter des clauses spécifiques pour l'extraire que des informations répondant à certains critères.
C'est le cas notamment pour l'extraire que des informations d'articles dont le statut est publié. D'ailleurs, en relisant mon code durant l'écriture de cet article, je me suis rendu compte que je synthétisais aussi le résultat des articles non publiés. Je vais de ce pas rajouter une clause WHERE pour ne pas prendre en compte les articles non publiés.
Bien entendu, libre à vous de corriger ou de modifier ma requête en fonction de vos spécificités métier.
Enfin, je vais remplacer mon short code défini pour ce plugin par le contenu concaténé.
Une travail pas tout a fait terminé ?
Etre informaticien, savoir développer c'est marrant, mais je continuie à être une véritable buse en infographie et mise en page. Il vous restera à votr charge de retoucher mon CSS qui n'est pas beau j'en conviens, mais vous êtes prévenus :)
define.php
<?php
defined('_JEXEC') or die('Access deny');
class plgContentDefine extends JPlugin
{
function onContentPrepare($content, $article, $params, $limit){
$document = JFactory::getDocument();
$document = JFactory::getDocument()->addStyleSheet("plugins/content/define/style.css");
$sql = "SELECT #__content.id, #__content.title, #__categories.title, #__content.introtext
FROM #__content, #__categories
WHERE `introtext` LIKE '%{define%'
AND #__categories.id = #__content.catid
and #__content.state=1
ORDER BY #__content.id DESC";
$db = JFactory::getDBO();
$db->setQuery($sql);
$row = $db->loadObjectList();
$str = '<div class="liste-definitions">';
foreach($row as $uneLigne)
{
$re = '/\{define \((.*)\)(.?)*\((.*)\)/m';
preg_match_all($re, $uneLigne->introtext, $matches, PREG_SET_ORDER, 0);
$str .= '<div class="une-definition">';
foreach ($matches as $L)
{
$str .= "<span class=\"terme-defini\">".$L[1]."</span><span class=\"definition-terme\">".$L[3]."</span><span class=\"article-id\">".$uneLigne->id."</span>";
}
$str .= '</div>';
}
$article->text = str_replace('{listeTermesDefinis}',$str,$article->text);
}
}
define.xml
<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="Content">
<name>Definitions dans un article</name>
<author>Sebastien LHUILLIER</author>
<creationDate>Aout 2023</creationDate>
<copyright>Sébastien LHUILLIER</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.</authorEmail>
<authorUrl>www.sebastien-lhuillier.com</authorUrl>
<version>1.0</version>
<description>Syntheses des Definitions</description>
<files>
<filename plugin="define">define.php</filename>
<filename>define.xml</filename>
<filename>style.css</filename>
</files>
</extension>
