Cet article analyse le plugin Le Couteau Suisse au niveau du développement et fournit des renseignements à tous ceux qui désireraient, soit comprendre le fonctionnement du plugin afin d’en optimiser ou d’en améliorer certains aspects, soit développer eux-même de nouvelles fonctionnalités ou de nouveaux outils [1].
Généralités de développement
Savoir développer un plugin pour SPIP est un plus pour développer un outil, puisque l’outil est comme un « mini-plugin », mais ce n’est pas forcément nécessaire. Voici quelques liens d’information :
Plugins : Tutoriaux pour Plugins
Pipelines : http://doc.spip.org/@Tuto-Se-servir...
L’intégration des petits plugins existants est très simple :
Un paragrahe « add_outil() » à ajouter dans le fichier « couteau_suisse/config_outils.php » (voir la syntaxe ci-dessous).
Deux déclarations à ajouter dans chaque fichier de langue situé dans « lang/ » afin de définir le nom et la description du nouvel outil (voir la syntaxe ci-dessous). Pour ces deux premiers points, il suffit de récupérer les informations demandées dans le fichier « plugin.xml » de l’ancien plugin
Les fichiers *.php de l’ancien plugin doivent être placés sans aucune modification a priori dans le dossier « outils/ »
Il est donc toujours possible pour les auteurs de revenir sur leur code
L’intégration de nouvelles fonctionnalités est donc tout aussi simple :
Un paragraphe « add_outil() » à ajouter dans le fichier « couteau_suisse/config_outils.php » (voir la syntaxe ci-dessous).
Deux déclarations à ajouter dans chaque fichier de langue suitué dans « lang/ » afin de définir le nom et la description du nouvel outil (voir la syntaxe ci-dessous).
Un module (éventuel) à placer dans le répertoire « outils/ »
Une petite confirmation sur la page de configuration du plugin (ecrire/?exec=admin_couteau_suisse) et le tour est joué !
Syntaxe (format simpliste) des déclarations dans config_outils.php
- 'id' => # Un identifiant unique et sans espace
- // optionnel (aide) :
- 'auteur' => # Auteur(s) de l'outil
- 'contrib' => # Numéro d'article fournissant la doc sur spip-contrib.net
- 'jquery' => 'oui', # Indique si l'outil nécessite la librairie jQuery
- 'categorie' => # Une valeur égale, par exemple, à : 'admin', 'public', 'spip', 'divers', etc.
- // optionnel (code) :
- 'code:options' => # Directement le code php à exécuter dans mes_options.php
- 'code:fonctions' => # Directement le code php à exécuter dans mes_fonctions.php
- 'code:spip_options' => # Directement le code php à exécuter le plus en amont possible (options SPIP en général)
- 'code:css' => # Directement le code des styles à insérer entre <head> et </head>
- 'code:js' => # Directement le code Javascript à insérer entre <head> et </head>
- 'code:jq' => # Directement le code jQuery à exécuter quand le DOM est prêt
- 'code:jq_init' => # Directement le code Javascript ou jQuery à exécuter au chargement de la page ou d'un fragment Ajax
- 'version-min' => # La version minimale de SPIP pour utiliser cet outil. Ex. : 1.92
- 'version-max' => # La version maximale de SPIP pour utiliser cet outil. Ex. : 1.91
- 'traitement:UNEBALISE:1erMomentSpip' => # 'fonction à utiliser'
- 'traitement:UNEBALISE:2eMomentSpip' => # 'fonction à utiliser'
- etc.
- 'pipeline:1erPipeline' => # 'fonction à utiliser'
- 'pipeline:2emePipeline' => # 'fonction à utiliser'
- 'pipelinecode:3emePipeline' => # Directement le code php a executer pour ce pipeline
- etc.
- ));
L’identifiant « id » sert à plusieurs choses :
inclure le fichier du même nom, placé dans le dossier « outils/ » et contenant les fonctions utilisées,
lire les traductions du nom et de la description de l’outil. Celles-ci se trouvent dans les fichiers de langue du dossier « lang/ »,
inclure l’éventuel fichier de styles (.css) du même nom, placé dans « outils/ »
inclure l’éventuel fichier javascript (.js) du même nom, placé dans « outils/ »
inclure l’éventuel fichier d’options (mon_outil_options.php), placé dans « outils/ »
inclure l’éventuel fichier de fonctions (mon_outil_fonctions.php), placé dans « outils/ »
stocker dans la base de donnée l’état de l’outil : actif/inactif.
La fonction associée à chacun des pipelines utilisés doit se trouver dans un seul fichier, celui indiqué par « id ». Par exemple, si l’on déclare 'id' => 'mon_outil', et bien le fichier en question est : « outils/mon_outil.php ». Ensuite, dans tous les fichiers de langue (par exemple « lang/cout_fr.php » ou « lang/cout_it.php ») il faut bien définir les traductions comme ceci : 'mon_outil:nom' => 'Mon bel Outil', et 'mon_outil:description' => 'Ma belle description'. Enfin, si cet outil utilise les feuilles de styles, alors le fichier doit s’intituler « outils/mon_outil.css ». S’il utilise des fonctions javascript, alors le fichier doit s’intituler « outils/mon_outil.js ».
Le « cadre » du Couteau Suisse
options, fonctions et pipelines
Le principe de Couteau Suisse est de compiler (lors de l’accès à la page privée de configuration du plugin, ou lorsque le rédacteur demande un calcul manuel de son article en partie publique) les options, fonctions et pipelines utilisés par les outils activés. Le plugin ne produit donc qu’un seul fichier « mes_options.php », un seul fichier « mes_fonctions.php » et un seul fichier par pipeline. N’hésitez pas à vous rendre dans le dossier « tmp/couteau-suisse » (SPIP versions 1.9.2 et suivantes) ou « ecrire/data/couteau-suisse » (pour les versions antérieures) afin de contrôler les divers fichiers ainsi créés.
Table des traitements
Si aucun pipeline n’est utilisé alors il est parfois nécessaire de créer un fichier « outils/mon_outil_fonctions.php » pour y stocker les fonctions nécessaires par exemple à un traitement automatique d’une balise SPIP (voir l’outil « decoupe »). Afin de gagner en performance et d’utiliser au maximum la personnalisation des balises SPIP, tous les traitements sont compilés au moment de l’installation des outils. Il est donc possible d’obtenir le code suivant :
grâce à la configuration suivante :
- // 1er outil :
- 'traitement:TEXTE:post_propre' => 'fonction1',
- // 2ème outil :
- 'traitement:TEXTE:post_propre' => 'fonction2',
- 'traitement:TEXTE:pre_propre' => 'fonction3',
Attention, la syntaxe suivante est interdite, la deuxième ligne écrasant la première :
- // Mon outil :
- 'traitement:TEXTE:post_propre' => 'fonction1',
- 'traitement:TEXTE:post_propre' => 'fonction2',
La bonne syntaxe (notez bien la parenthèse) est :
- // Mon outil :
- 'traitement:TEXTE:post_propre' => 'fonction1(fonction2',
Aide aux raccourcis
La liste des outils apportant de nouveaux raccourcis aidant à la rédaction des textes du site commence à s’allonger. Sur la page d’administration du plugin, sont maintenant listés (dans un cadre sur la gauche) les raccourcis typographiques actifs que l’on peut utiliser dans ses articles ou autres différents textes du site.
Chaque outil introduisant de nouveaux raccourcis doit prévoir une fonction « mon_outil_raccourcis() » qui renvoie l’aide en question en listant les raccourcis typographiques disponibles. Cette chaine (hor spécificités de langage !) peut-être pré-compilée lors de l’installation de l’outil, au sein de la fonction « mon_outil_installe() » en la stockant dans les métas.
Lors de l’appel à l’aide, la chaine de langue prévue à cet effet est : ’mon_outil:aide’ et doit être présente dans les fichiers de langue (couteau_suisse/lang/). Par exemple : ’chatons:aide’ => ’Chatons : @liste@’. Le contrôle « @liste@ » sera remplacé par la liste des raccourcis préalablement calculée et stockée dans les métas.
À l’intérieur de la fonction chatons_installe(), $liste est le tableau des raccourcis disponibles.
On place donc aussi :
Au final voici comment est renvoyée l’aide aux raccourcis :
- function chatons_raccourcis() {
- }
Si la fonction ’mon_outil_raccourcis’ censée traiter cette chaine de langue n’existe pas, alors la chaine de langue est utilisée telle quelle.
TODO : création d’une balise pouvant servir d’aide à la rédaction des forums.
Fonction d’exclusion de balises
La fonction cs_echappe_balises($balises, $fonction, $texte) permet aux outils utilisant des remplacements typographiques de protéger le texte situé entre certaines balises.
$balise est la liste de balises à ignorer. Exemple : ’html|code|cadre|frame|script|acronym|cite’
$fonction est la fonction de modification typographique
$texte est le texte d’origine à traiter
Si $balise='' alors les balises suivantes sont protégées par défaut : html|code|cadre|frame|script
Exemple simple d’utilisation :
- function small_caps_remplace($texte) {
- "<span style=\"font-variant: small-caps\">\\1</span>", $texte);
- }
- function small_caps($texte) {
- return cs_echappe_balises('', 'small_caps_remplace', $texte);
- }
Cet exemple permet à l’outil small_caps de remplacer toutes les textes entre balises <sc> et </sc> par un texte en petites capitales. Mais tout ce qui se trouve entre <html> et </html>, <code> et </code>, <cadre> et </cadre>, <frame> et </frame> ou <script> et </script> est ignoré.
Installation d’un outil
Une fonction d’installation est automatiquement appelée par le plugin (si elle existe), lorsque l’utilisateur demande manuellement de recalculer une page, ou lorsqu’un administrateur consulte la page de configuration du plugin (ecrire/?exec=admin_couteau_suisse). Cette fonction intitulée mon_outil_installe() (notez bien le suffixe obligatoire « _installe ») doit obligatoirement se trouver dans le fichier « outils/mon_outil.php » (voir l’outil « smileys »).
Cette fonction peut être utile pour stocker à long terme des données particulières dans la base de donnée (sous forme de métas) afin d’accélérer le futur calcul des pages du sites.
En somme...
Cela semble assez bien tenir la route pour l’instant... J’attends vos retours d’expériences !
Pour créer un nouvel outil, le mieux est toujours de voir comment sont configurés les autres (il y en a plus de 30...) afin de s’en inspirer. En dernier recours, le forum ci-dessous est fait pour vous.
Exemples d’outils
Lignes à placer dans config_outils.php :
- 'id' => 'pucesli',
- 'auteur' => '[Jérôme]',
- 'categorie' => 'typo-corr',
- 'pipeline:pre_typo' => 'pucesli_pre_typo',
- ));
- 'id' => 'forcer_langue',
- 'code:options' => '$GLOBALS["forcer_lang"]=true;',
- 'categorie' => 'admin',
- ));
- 'id' => 'decoupe',
- 'traitement:TEXTE:post_propre' => 'decouper_en_pages',
- 'categorie' => 'typo-racc',
- ));
Lignes à placer dans lang/cout_fr.php :
- 'pucesli:nom' => 'Belles puces',
- 'pucesli:description' => 'Remplace les puces - (tiret) des articles par des puces -* (<li><ul>...</li></ul>)',
Les variables
Le plugin « Le Couteau Suisse » permet de manipuler facilement des variables agissant sur le fonctionnement public ou privé de SPIP. Ces variables bénéficient donc d’une entrée spécifique (<input>) sur la page de configuration du plugin (ecrire/?exec=admin_couteau_suisse), afin que l’administrateur y porte ses choix. Il y a actuellement 2 types de variables : les cases ’input’ (chaine ou nombre) et les boutons radio.
Syntaxe (format simpliste) des déclarations de variables dans config_outils.php
- 'nom' => # Un nom unique et sans espace
- 'format' => # type de variable : _format_CHAINE ou _format_NOMBRE
- 'defaut' => # valeur par défaut prise par la variable
- 'code' => # code php inline (la variable est ici représentée par %s) à insérer dans l'outil en lieu et place du raccourci %%ma_variable%%
- // optionnels :
- 'radio' => # tableau de valeurs ('code' => 'valeur') où 'code' est un choix de réponse et 'valeur' la traduction _T('valeur') affichée dans la description de l'outil sur la page de configuration
- 'radio/ligne' => # nombre de boutons radio par ligne
- 'check' => # label d'un bouton de type checkbox
- 'lignes' => # nombre de lignes (d'un textarea) nécessaires pour une variable de type 'chaine'
- 'code:condition' => # code pris en compte uniquement si 'condition' est vrai (la variable est ici représentée par %s)
- ));
Ces variables sont utilisées dans le code inline utilisé par les outils et le plugin les repère grâce à la syntaxe suivante : %%ma_variable%%. La valeur par défaut est la valeur attribuée à la variable lors de la toute première installation de l’outil en question ou lors d’une réinitialisation générale du plugin (ecrire/?exec=admin_couteau_suisse&reset=oui). Un outil peut sans aucun problème manipuler plusieurs varibles dans son code inline.
Voici un exemple d’outil utilisant une chaine de caractère que l’administrateur du site devra renseigner :
- /*
- Ici on demande au plugin une case input de type texte.
- La variable est : cookie_prefix_var.
- A la toute première activation de l'outil,
- la valeur sera : $GLOBALS["cookie_prefix"]
- Le code inséré dans mes_options sera :
- $GLOBALS['cookie_prefix']="monprefixe";
- */
- 'nom' => 'cookie_prefix_var',
- 'format' => 'chaine',
- 'defaut' => "\$GLOBALS['cookie_prefix']",
- 'code' => "\$GLOBALS['cookie_prefix']=%s;",
- ));
- 'id' => 'cookie_prefix',
- 'code:options' => "%%cookie_prefix_var%%",
- 'categorie' => 'admin',
- ));
Voici un exemple d’outil utilisant une condition simple (grâce à ’code :%s’, le plugin insère le code dans mes_options.php seulement si la variable %s est non nulle) :
- /*
- Ici on demande au plugin une case input de type texte.
- La variable est : forum_lgrmaxi.
- A la toute première activation de l'outil, la valeur sera : 0
- Si la valeur est différente de zéro (condition : '%s'),
- le code inséré dans mes_options sera par exemple :
- define('_FORUM_LONGUEUR_MAXI', 1000);
- */
- 'nom' => 'forum_lgrmaxi',
- 'format' => 'nombre',
- 'defaut' => 0,
- 'code:%s' => "define('_FORUM_LONGUEUR_MAXI', %s);",
- ));
- 'id' => 'forum_lgrmaxi',
- 'code:options' => "%%forum_lgrmaxi%%",
- 'categorie' => 'admin',
- 'version-min' => 1.92,
- ));
Pour une condition plus poussée (ici ’code:strlen(%s)’ implique une utilisation du code si la variable %s est de longueur non nulle) :
- /*
- Ici, si la variable 'style_p' a une longueur nulle,
- le code inséré dans mes_options sera :
- $GLOBALS['class_spip']='';
- et si la variable 'style_p' a une longueur non nulle,
- le code inséré dans mes_options sera par exemple :
- $GLOBALS['class_spip']=' class="maclasse"';
- */
- 'nom' => 'style_p',
- 'format' => 'chaine',
- 'defaut' => 'spip',
- 'code:strlen(%s)' => ' class=%s',
- ));
- 'id' => 'style_p',
- 'code:options' => "\$GLOBALS['class_spip']='%%style_p%%';",
- 'categorie' => 'public',
- 'version-min' => 1.93,
- ));
Les boutons radio (choix multiples prédéfinis) sont assez simple à définir. Il suffit de remplir le tableau ’radio’ au sein de la variable en question. Voici un exemple concernant le calcul des adresses du site :
- /*
- Ici on demande au plugin six boutons radio : _T('page'), _T('html'),
- _T('propres'), _T('propres2'), _T('standard'), et _T('propres-qs')
- La variable SPIP est : radio_type_urls3
- le 'defaut' => 'page' signifie que 'page' (traduit par : _T('cout:page')) sera coché
- par défaut à la toute première installation de l'outil.
- 'mavaleur' => 'matraduction' signifie que la valeur 'mavaleur' est traduite
- par _T('cout:matraduction') dans les fichiers de langue (tweak_spip/lang/).
- si l'utilisateur choisi le bouton 'html',
- alors le code inséré dans mes_options sera celui-ci :
- $GLOBALS['type_urls']="html";
- */
- 'nom' => 'radio_type_urls3',
- 'format' => 'chaine',
- 'page' => 'page',
- 'html' => 'html',
- 'propres' => 'propres',
- 'propres2' => 'propres2',
- 'standard' => 'standard',
- 'propres-qs' => 'propres-qs'
- ),
- 'defaut' => 'page',
- 'code' => "\$GLOBALS['type_urls']=%s;",
- ));
- 'id' => 'type_urls',
- 'code:options' => "%%radio_type_urls3%%",
- 'categorie' => 'admin',
- ));
Dysfonctionnements
N’hésitez pas à remonter tout type de dysfonctionnement du plugin, nous essaierons d’y répondre, dans la mesure du possible. Dans un premier temps, tentez quand même de chercher les causes de vos soucis et soyez méthodiques. Le code est gratuit et améliorable ; chacun peut apporter une pierre à l’édifice.
Dans vos messages, soyez précis. Indiquez bien les différentes versions des éléments que vous utilisez : plugin, squelette, SPIP, PHP, etc. Pour débusquer un bug et trouver la source, il faut d’abord isoler le Couteau Suisse en désactivant les autres plugins, puis isoler l’outil défaillant. Désactiver temporairement son squelette et réutiliser le squelette source de SPIP ("dist") peut également donner des informations utiles.
3 moyens de contact :
Mail direct, si par hasard vous savez à qui vous adresser
Le forum ci-après, histoire que tout le monde en profite
Les listes de diffusion comme spip.zone, sur gmane.org
Avant toute chose, assurez-vous d’avoir :
la toute dernière version du plugin
validé la page des plugins (admin_plugin)
validé la page du couteau suisse (admin_couteau_suisse)
vidé le cache
supprimé le dossier tmp/couteau-suisse
Historique
Pour l’instant, il n’y a pas d’historique officielle. Juste les logs de la version SVN disponibles ici.
L’outil "Boîtes Privées" vous permet de suivre en direct les derniers dépôts SVN. Rendez-vous sur la page de configuration (ecrire/?exec=admin_couteau_suisse).
Perpectives
Le plugin activé, mais sans aucun outil activé ne fait absolument rien de significatif. Des optimisations sont probablement encore à faire. En effet, le plugin fonctionne bien et remplit son office correctement : il précompile les outils à l’avance et facilite ensuite le calcul des pages avant la mise en cache. Mais préserver les ressources est toujours la priorité de ses auteurs et de ses utilisateurs. Ce qui est sûr, c’est qu’il vaut mieux deux outils que deux plugins !










