Ce qui parait évident au premier abord ne l’est pas forcément dans la réalité. On va être méthodique et commencer par corriger les principaux écueils actuels du plugin :
- ne pas déclarer les autorisations dans le fichier d’option mais bien en utilisant un fichier spécifique appelé par le pipeline autoriser,
- ne pas jouer au fou avec des
id_extrabasé sur les clés de tableau qui pourraient être problématiques si deux administrateurs modifient un même extra en même temps (bon, j’admets c’est peu probable), - utiliser la classe
ChampExtraaussi dans l’interface plutôt que d’utiliser un autre tableau, ce qui sera plus pérenne, - rationaliser les noms des fonctions entre les deux plugins,
- ajouter des points de log.
Rationaliser les nommages
Afin d’éviter de trop se disperser dans les noms des fonctions entre le plugin ’core’ et le plugin ’interface’ pour les champs extras, nous allons les renommer, ainsi que leurs fonctions cextras et iextras. Et en plus, je l’ai déjà fait, ce qui donne : http://zone.spip.org/trac/spip-zone... et le retardataire http://zone.spip.org/trac/spip-zone... !
Autorisations au bon endroit !
Je l’avais oublié un peu trop vite, mais il y a un pipeline pour les autorisations, qui permet de charger un fichier contenant de nouvelles autorisations.
Nous allons donc le déclarer dans l’interface à la place du fichier d’options.
- <pipeline>
- <nom>autoriser</nom>
- <inclure>inc/iextras_autoriser.php</inclure>
- </pipeline>
Le fichier d’options est déplacé, renommé dans inc/iextras_autoriser.php et modifié comme suit :
- <?php
- // fonction pour le pipeline, n'a rien a effectuer
- function iextras_autoriser(){}
- // declarations d'autorisations
- function autoriser_iextras_onglet_dist($faire, $type, $id, $qui, $opt) {
- return autoriser('configurer', 'iextra', $id, $qui, $opt);
- }
- function autoriser_iextras_configurer_dist($faire, $type, $id, $qui, $opt) {
- return autoriser('webmestre', $type, $id, $qui, $opt);
- }
- ?>
La fonction iextras_autoriser doit être présente, mais elle ne sert à rien. Elle est juste prétexte à la lecture du fichier d’autorisation au moment de l’appel à la librairie autoriser de SPIP.
Ajouter des points de logs
Certaines actions effectuées méritent d’être logguées, comme l’ajout et la suppression de champ extra.
Créons une fonction pour cela dans le core du plugin :
- function extras_log($contenu, $important=false) {
- if ($important
- spip_log($contenu,'extras');
- }
- }
On ajoutera au fur et à mesure des appels aux points essentiels du plugin.
Utiliser la classe ChampExtra dans l’interface graphique
Les objets PHP peuvent se linéariser et se dé-linéariser de la même manière que les tableaux PHP. La condition est que la classe soit définie au moment de la dé-linéarisation. Ce qu’on appelle linéarisation, ou sérialisation, c’est l’action de transformer une variable PHP en une chaine de caractère particulière pouvant alors être stockée, par exemple dans un fichier. Ces chaines peuvent être ensuite dé-sérialisées pour obtenir de nouveau la variable d’origine.
Donc, à la place d’un tableau PHP, nous allons stocker une classe ChampExtra.
Rien d’extraordinaire à montrer ici : http://zone.spip.org/trac/spip-zone...
Utiliser un identifiant qui identifie réellement !
L’identifiant que nous avons attribué aux champs extras correspond en ce moment à la clé du tableau PHP contenant la liste des champs extras. Cette clé, générée automatiquement n’identifie pas les contenus, mais juste une position dans un tableau. Si par mégarde la position change entre le moment où l’on affiche la liste des extras et le moment où l’on appuie sur le bouton supprimer (parce que quelqu’un a déplacé l’extra en question presque au même moment), alors ce sera un mauvais champ qui sera supprimé ! Pas good !
Nous allons donc créer un identifiant qui représente réellement le contenu du champ extra, de sorte que si le champ est déplacé dans le tableau, ce soit bien lui néanmoins qui soit supprimé et non son voisin.
On ajoute donc des petites fonctions à la classe ChampExtra pour gérer cet identifiant :
- // creer l'id du champ extra :
- function make_id(){
- // creer un hash
- foreach ($this as $cle=>$val) {
- if ($cle[0]!=='_') {
- $hash[] = $val;
- }
- }
- }
- // determiner un identifiant
- function get_id(){
- if (!$this->_id) $this->make_id();
- return $this->_id;
- }
- // transformer en tableau PHP les variable publiques de la classe.
- function toArray(){
- foreach ($this as $cle=>$val) {
- if ($cle[0]!=='_') {
- $extra[$cle] = $val;
- }
- }
- $extra['id_extra'] = $this->get_id();
- return $extra;
- }
La première fonction make_id() crée un hash (une chaine unique) en utilisant les variables de la classe ChampExtra qui ne commencent pas par un souligné.
La seconde get_id() renvoie l’identifiant (ou le crée puis le renvoie), enfin, la dernière déjà présente mais modifiée retourne un tableau PHP avec le contenu de la classe ChampExtra et en profite pour ajouter dedans une clé ’id_extra’ avec l’identifiant en question.
De la sorte, le formulaire peut maintenant récupérer des données en fonction d’un identifiant fiable. Voyons par exemple comment devient la fonction charger du formulaire :
- function formulaires_editer_champ_extra_charger_dist($id_extra='new', $redirect=''){
- // nouveau ?
- $new = ($id_extra == 'new') ? ' ': '';
- // valeur par defaut
- 'champ' => '',
- 'table' => '',
- 'type' => '',
- 'label' => '',
- 'sql' => "text NOT NULL DEFAULT ''",
- 'id_extra' => $id_extra,
- 'new' => $new,
- 'redirect' => $redirect,
- );
- // si un extra est demande (pour edition)
- // remplir les valeurs avec infos de celui-ci
- if (!$new) {
- $extras = iextras_get_extras();
- foreach($extras as $extra) {
- if ($extra->get_id() == $id_extra) {
- break;
- }
- }
- }
- return $valeurs;
- }
Lorsque nous sommes face à un champ en modification (pas nouveau), on parcoure la liste des champs extras tant qu’on ne trouve pas celui ayant le bon identifiant. Lorsque c’est le bon, on ajoute ses valeurs dans le chargement. C’est un peu plus long en traitement, mais ce n’est pas un lieu d’un site fréquenté (ça ne sert qu’à la création du site généralement). Les changements complets sont là : http://zone.spip.org/trac/spip-zone...
Nous avons maintenant corrigé les principaux écueils et pouvons attaquer la prise en compte par le plugin des champs déjà ajoutés dans la base de donnée. Ca ne va pas être si simple que ça !
Bien poser la problématique...
Quand on ne sait pas trop comment commencer, il y a plusieurs possibilités :
- dormir (le plus efficace certainement),
- faire des schémas et des plans sur papier qui permettent d’avoir une vue d’ensemble meilleure ou encore écrire en français la problématique,
- commencer par ce dont on est certain ; le reste viendra en codant.
Cernons la problématique : certains webmestres ont déjà ajouté dans des tables des champs via phpMyAdmin ou en écrivant dans un squelette SPIP :
- <?php
- sql_alter("TABLE spip_articles ADD COLUMN fruits text NOT NULL DEFAULT ''");
- ?>
Ces champs déjà présents ne sont pour le moment pas pris en compte par le plugin. La question, c’est comment les prendre en compte, et que prendre en compte aussi. Car il peut y avoir une lecture à plusieurs niveaux : le champ peut exister et être déclaré, mais sans être accessible aux rédacteurs d’articles, c’est à dire ne s’affichant pas dans les formulaires. Le champ peut aussi être déclaré et devoir s’afficher.
Le plus simple, il me semble, c’est de pouvoir dire qu’un champ peut non seulement être supprimé, mais peut aussi être lié et délié au plugin champs extras. Ainsi, on pourrait lier un champ au plugin, il s’affiche alors dans le formulaire, puis le délier (il ne s’y affiche plus, et n’est plus géré par le plugin d’interface) mais est toujours présent dans la table. Ceci résoudrait l’épineux problème de la suppression car sinon, on ne pourrait retirer un champ extra ajouté dans le plugin qu’en le supprimant... Ce qui n’est pas forcément idéal.
On a donc un premier aperçu de ce qu’il faut réaliser (ajouter un champ existant / délier un champ extra du plugin).
Commençons par pouvoir ajouter les champs existants. Il faut déjà pouvoir les lister. Enfin, lister tous les champs de la base de donnée qui ne sont pas déclarés à SPIP, c’est bien de ceux là qu’il s’agit, car ceux déjà déclarés ont toutes les chances d’être déjà gérés par d’autres plugins. Ca tombe assez bien car Fil a déjà réalisé cette partie dans le futur défunt plugin « extras2 » que ce plugin est en train de manger !
On va donc intégrer tout ou partie de son code. (¡ Que viva GPL !)
Récupérer les descriptions des tables SQL
On va donc comparer deux descriptions : celle des tables réelles et celles des déclarations faites à SPIP. La différence des deux donnera les champs possiblement utilisables par le plugin. Ajoutons ces fonctions au core, adaptées de Fil :
- // Liste les champs anormaux par rapport aux definitions de SPIP
- // (aucune garantie que $connect autre que la connexion principale fasse quelque chose)
- function extras_champs_anormaux($connect='') {
- // recuperer les tables et champs accessibles
- $tout = extras_base($connect);
- // recuperer les champs SPIP connus
- include_spip('base/auxiliaires');
- include_spip('base/serial');
- // chercher ce qui est different
- foreach ($tout as $table => $champs) {
- $nchamps[$table] = $champs;
- } else {
- foreach($champs as $champ => $desc) {
- $nchamps[$table][$champ] = $desc;
- }
- }
- }
- }
- if($nchamps) {
- $tout = $nchamps;
- }
- return $tout;
- }
- // etablit la liste de tous les champs de toutes les tables du connect donne
- // ignore la table 'spip_test'
- function extras_base($connect='') {
- foreach (extras_tables($connect) as $table) {
- if ($table != 'spip_test') {
- $champs[$table] = extras_champs($table, $connect);
- }
- }
- return $champs;
- }
- // liste les tables dispos ans la connexion $connect
- function extras_tables($connect='') {
- if ($s = sql_showbase(null, $connect)) {
- while ($t = sql_fetch($s, $connect)) {
- }
- }
- return $a;
- }
- // liste les champs dispos ans la table $table de la connexion $connect
- function extras_champs($table, $connect) {
- $desc = sql_showtable($table, null, $connect);
- return $desc['field'];
- } else {
- }
- }
Commençons par observer la fonction extra_tables(). Elle demande quelle sont les tables réellement présentes dans la base, gràce à la fonction sql sql_showbase(). Le paramètre $connect correspond au nom du fichier de connexion qu’utilise SPIP pour se connecter (dans le répertoire connect/). Lorsqu’il n’est pas renseigné, SPIP utilise sa connexion principale (la connexion ayant installée le SPIP).
La fonction extra_champs() prend un nom de table en entrée et récupère la liste des champs réels et leurs descriptions SQL, ceci gràce à la fonction sql_showtable().
La fonction extra_base() crée un tableau de toutes les descriptions des champs pour chaque table rencontrée.
Reste maintenant la fonction extras_champs_anormaux(). Elle récupère tous les champs réels en appelant extra_base(), tous les champs SPIP déclarés en concaténant les tableaux tables_principales et tables_auxiliaires, et retourne la liste des champs présents en base, mais non déclarés à SPIP.
Afficher les champs utilisables dans l’interface
Nous allons maintenant afficher ces champs dans l’interface graphique du plugin, avec des actions pour les associer ou les supprimer définitivement.
Ajoutons déjà l’appel à un squelette les affichant dans exec/iextras.php :
- include_spip('inc/cextras_gerer');
- 'extras'=>extras_champs_anormaux(),
- ));
Puis créons le squelette champs_extras_possibles.html, sur le même principe que son collègue prive/contenu/champs_extra.html :
- <BOUCLE_si_extras(CONDITION){si #ENV{extras}}>
- [(#CHEMIN{images/iextras-24.png}|debut_cadre_trait_couleur{1, "", <:iextras:liste_des_extras_possibles:>})]
- <BOUCLE_tables(POUR){tableau #ENV**{extras}}>
- <h2>[(#VAL{iextras:table_}|concat{#CLE|replace{^spip_|s$,''}}|_T)]</h2>
- <B_extras>
- <ul class="liste_extras_possibles">
- <BOUCLE_extras(POUR){tableau #VALEUR}>
- <li>
- #CLE
- | <a href="[(#URL_ACTION_AUTEUR{iextras, [associer_champ/#_tables:CLE/(#CLE)], #SELF})]"><:iextras:action_associer:></a>
- | <a href="[(#URL_ACTION_AUTEUR{iextras, [supprimer_champ/#_tables:CLE/(#CLE)], #SELF})]" class="supprimer"><:iextras:action_supprimer:></a>
- </li>
- </BOUCLE_extras>
- </ul>
- </B_extras>
- </BOUCLE_tables>
- <script type="text/javascript">
- (function($) {
- $('ul.liste_extras_possibles .supprimer').click(function(){
- return confirm("<:iextras:supprimer_reelement|attribut_html:>");
- });
- })(jQuery);
- </script>
- [(#VAL{1}|fin_cadre_trait_couleur)]
- </BOUCLE_si_extras>
Nous bouclons sur les différentes tables, puis sur les champs et nous affichons un lien pour associer et un lien pour supprimer le champ.
Nous en profitons pour ajouter en même temps, sur l’autre squelette prive/contenu/champs_extras.html un lien pour désassocier un champ extra déclaré :
Il faut maintenant s’occuper de traiter les différentes actions.
Créer les nouvelles actions
Modifions le fichier actions/iextras.php pour lui ajouter ces traitements. Cela peut donner le résultat ci-dessous. Chaque action appelle une fonction dédiée. Notons juste le cas de l’association d’un champ SQL déjà présent : après l’appel de la fonction d’association, on redirige la page vers le formulaire de modification. C’est un peu déroutant, mais lorsqu’on ajoute un tel champ, une des premières choses faite sera de renseigner correctement le label, donc envoyer sur le formulaire parait assez cohérent. (NdA : finalement j’ai réellement trouvé ça trop déroutant en pratique et j’ai mis en commentaire ce code)
Pour cela, on appelle la fonction redirige_par_entete() présent dans la librairie inc/header. Elle prend comme paramètre l’URL de redirection et doit être appelée avant tout affichage sur la page.
- <?php
- function action_iextras_dist() {
- $securiser_action = charger_fonction('securiser_action', 'inc');
- $arg = $securiser_action();
- // droits
- include_spip('inc/autoriser');
- if (!autoriser('configurer', 'iextra')) {
- include_spip('inc/minipres');
- echo minipres();
- exit;
- }
- // actions possibles
- 'supprimer_extra',
- 'desassocier_extra',
- 'associer_champ',
- 'supprimer_champ'))){
- include_spip('inc/minipres');
- exit;
- }
- // cas de suppression
- if (($arg == 'supprimer_extra') and $id_extra = $id_extra_ou_table){
- action_supprimer_champ_extra($id_extra);
- }
- // cas de desassociation
- if (($arg == 'desassocier_extra') and $id_extra = $id_extra_ou_table){
- action_desassocier_champ_extra($id_extra);
- }
- // cas de l'association d'un champ existant
- if (($arg == 'associer_champ') and ($table = $id_extra_ou_table) and $champ){
- $id_extra = action_associer_champ_sql_comme_champ_extra($table, $champ);
- // si l'association fonctionne, rediriger vers le formulaire de modification du champ extra
- if ($id_extra) {
- // redirection vers le formulaire d'edition du champ
- $redirect = generer_url_ecrire('iextras_edit');
- $redirect = parametre_url($redirect,'id_extra', $id_extra, '&');
- include_spip('inc/header');
- redirige_par_entete($redirect);
- }
- }
- // cas de la suppression d'un champ existant
- if (($arg == 'supprimer_champ') and $table = $id_extra_ou_table){
- action_supprimer_champ_sql($table, $champ);
- }
- }
- // suppression d'un champ extra donne
- function action_supprimer_champ_extra($id_extra) {
- include_spip('inc/iextras');
- $extras = iextras_get_extras();
- foreach($extras as $i=>$extra) {
- if ($extra->get_id() == $id_extra) {
- extras_log("Suppression d'un champ par auteur ".$GLOBALS['auteur_session']['id_auteur'],true);
- extras_log($extra, true);
- $table = table_objet_sql($extra->table);
- sql_alter("TABLE $table DROP ".$extra->champ);
- iextras_set_extras($extras);
- break;
- }
- }
- }
- // desassocier un champ extra
- // (ne plus le gerer avec le plugin champ extra
- // mais ne pas le supprimer de la base de donnee)
- function action_desassocier_champ_extra($id_extra) {
- include_spip('inc/iextras');
- $extras = iextras_get_extras();
- foreach($extras as $i=>$extra) {
- if ($extra->get_id() == $id_extra) {
- extras_log("Desassociation du champ $extra->table/$extra->champ par auteur ".$GLOBALS['auteur_session']['id_auteur'],true);
- iextras_set_extras($extras);
- break;
- }
- }
- }
- // definir un champ SQL existant comme un champ extra a prendre
- // en compte par ce plugin
- function action_associer_champ_sql_comme_champ_extra($table, $champ){
- // recuperer la description du champ
- include_spip('inc/cextras_gerer');
- $champs = extras_champs_anormaux();
- $sql = $champs[$table][$champ];
- // creer un champ extra avec ce champ
- 'table' => objet_type($table),
- 'champ' => $champ,
- 'label' => 'label_'.$champ,
- 'type' => 'input',
- 'sql' => $sql,
- ));
- // penser a creer une fonction pour ajouter et supprimer un champ...
- // ajout du champ
- extras_log("Ajout d'un champ deja existant par auteur ".$GLOBALS['auteur_session']['id_auteur'],true);
- extras_log($extra, true);
- $extras = iextras_get_extras();
- $extras[] = $extra;
- iextras_set_extras($extras);
- // retourner id_extra
- return $extra->get_id();
- }
- }
- // suppression de la base d'un champ d'une table donnee.
- function action_supprimer_champ_sql($table, $champ) {
- // recuperer les descriptions
- // pour verifier que le champ n'est pas declare par quelqu'un
- include_spip('inc/cextras_gerer');
- $champs = extras_champs_anormaux();
- // suppression
- extras_log("Suppression du champ $table/$champ par auteur ".$GLOBALS['auteur_session']['id_auteur'],true);
- $table = table_objet_sql($table);
- sql_alter("TABLE $table DROP ".$champ);
- }
- }
- ?>
Ordonner les champs extras
Lorsqu’il y a au moins deux champs extras déclarés sur une table, on peut avoir envie de les afficher dans un certain ordre. Nous allons donc ajouter deux actions : monter et descendre. Par ailleurs, on ne peut pas monter le premier élément ni descendre le dernier !
- [(#TOTAL_BOUCLE|>{1}|oui)
- [(#COMPTEUR_BOUCLE|!={1}|oui)
- | <a href="[(#URL_ACTION_AUTEUR{iextras, [monter_extra/(#VALEUR|table_valeur{id_extra})], #SELF})]"><:iextras:action_monter:></a>
- ]
- [(#COMPTEUR_BOUCLE|!=={#TOTAL_BOUCLE}|oui)
- | <a href="[(#URL_ACTION_AUTEUR{iextras, [descendre_extra/(#VALEUR|table_valeur{id_extra})], #SELF})]"><:iextras:action_descendre:></a>
- ]
- ]
En ajoutant ces deux nouvelles actions, on remarque qu’il commence à y en avoir beaucoup (d’actions) et que leur affichage est un peu le fouillis. Avant de traiter les actions, on va effectuer un peu de présentation CSS.
D’une part, nous allons mettre les actions dans une liste ul/li :
- <ul class="actions">
- [(#TOTAL_BOUCLE|>{1}|oui)
- [(#COMPTEUR_BOUCLE|!={1}|oui)
- <li><a href="[(#URL_ACTION_AUTEUR{iextras, [monter_extra/(#VALEUR|table_valeur{id_extra})], #SELF})]" title="<:iextras:action_monter_title|attribut_html:>"><:iextras:action_monter:></a></li>
- ]
- [(#COMPTEUR_BOUCLE|!=={#TOTAL_BOUCLE}|oui)
- <li><a href="[(#URL_ACTION_AUTEUR{iextras, [descendre_extra/(#VALEUR|table_valeur{id_extra})], #SELF})]" title="<:iextras:action_descendre_title|attribut_html:>"><:iextras:action_descendre:></a></li>
- ]
- ]
- <li><a href="[(#URL_ECRIRE{iextras_edit}|parametre_url{id_extra,#VALEUR|table_valeur{id_extra}})]" title="<:iextras:action_modifier_title|attribut_html:>"><:iextras:action_modifier:></a></li>
- <li><a href="[(#URL_ACTION_AUTEUR{iextras, [desassocier_extra/(#VALEUR|table_valeur{id_extra})], #SELF})]" title="<:iextras:action_desassocier_title|attribut_html:>"><:iextras:action_desassocier:></a></li>
- <li><a href="[(#URL_ACTION_AUTEUR{iextras, [supprimer_extra/(#VALEUR|table_valeur{id_extra})], #SELF})]" class="supprimer" title="<:iextras:action_supprimer_title|attribut_html:>"><:iextras:action_supprimer:></a></li>
- </ul>
Ajouter du CSS dans l’interface privé
Ensuite, nous allons ajouter du CSS pour présenter cette liste. Comment ? Très simple, chaque plugin peut déclarer un fichier prive/style_prive_plugin_prefix.html qui sera interprété comme un fichier css. Créons le fichier prive/style_prive_plugin_iextras.html et ajoutons dedans :
- ul.actions {text-align:right;}
- ul.actions li{display:inline; padding-right:3px; border-right:1px solid ##ENV{couleur_claire};}
On remarquera que ce squelette reçoit quelques paramètres (lang, couleur_foncee, couleur_claire et ltr (direction de la langue)). Nous utilisons ici la couleur claire pour mettre une petite bordure.
Par contre, voir les modifications CSS dans le privé n’est pas simple du tout car d’une part les CSS sont compactées automatiquement dans l’espace privé, mais on peut désactiver cela en ajoutant dans son fichier d’option :
- define('_INTERDIRE_COMPACTE_HEAD_ECRIRE',true);
Et d’autre part, ce sont des CSS calculées à partir de squelettes SPIP, et les faire recalculer n’est pas simple. Le plus rapide étant de vider à la fois le cache de SPIP et celui du navigateur.
Traiter les actions monter et descendre
Nous allons utiliser une fonction assez géniale de PHP pour cela : array_splice(). Cette fonction permet d’insérer ou de remplacer des éléments dans un tableau. Nous allons l’utiliser pour insérer notre champ déplacé au bon endroit.
Pour cela, on ordonne notre tableau pour avoir tous les champs d’une même table à la suite, puis il suffit de remonter ou descendre un élément pour modifier l’ordre.
Commençons par trier les champs par table :
- // tableau des extras, tries par table SQL
- function iextras_get_extras_tries_par_table(){
- $extras = iextras_get_extras();
- foreach($extras as $e) {
- }
- $tables[$e->table][] = $e;
- }
- foreach ($tables as $table) {
- foreach ($table as $extra) {
- $extras_tries[] = $extra;
- }
- }
- return $extras_tries;
- }
Ensuite, nous pouvons ajouter les actions monter et descendre :
- // remonter d'un cran un champ extra
- function action_monter_champ_extra($id_extra) {
- include_spip('inc/iextras');
- $extras = iextras_get_extras_tries_par_table();
- foreach($extras as $i=>$extra) {
- if ($extra->get_id() == $id_extra) {
- extras_log("Remonter le champ $extra->table/$extra->champ par auteur ".$GLOBALS['auteur_session']['id_auteur']);
- if ($i !== 0) {
- iextras_set_extras($extras);
- }
- break;
- }
- }
- }
- // descendre d'un cran un champ extra
- function action_descendre_champ_extra($id_extra) {
- include_spip('inc/iextras');
- $extras = iextras_get_extras_tries_par_table();
- foreach($extras as $i=>$extra) {
- if ($extra->get_id() == $id_extra) {
- extras_log("Descendre le champ $extra->table/$extra->champ par auteur ".$GLOBALS['auteur_session']['id_auteur']);
- if ($i+1 !== $total) {
- iextras_set_extras($extras);
- }
- break;
- }
- }
- }
Résultat des courses : http://zone.spip.org/trac/spip-zone... (et petit « oups »).
Afficher une boite d’information
Pour terminer ce plugin, nous allons ajouter des descriptions sur les pages de l’interface. Rien de transcendant, mais il existe des fonctions et pipelines déjà prévus, alors utilisons les !
Commençons par créer les chaines de langues :
- 'info_description_champ_extra' => "Cette page permet de gérer des champs extras,
- c'est à dire des champs supplémentaires dans les tables de SPIP,
- pris en compte dans les formulaires d'édition.",
- 'info_description_champ_extra_creer' => "Vous pouvez créer de nouveaux champs qui s'afficheront alors
- sur cette page, dans le cadre «Liste des champs extras», ainsi que dans les formulaires.",
- 'info_description_champ_extra_presents' => "Enfin, si des champs existent déjà dans votre base de donnée,
- mais ne sont pas déclarés (par un plugin ou un jeu de squelettes), vous
- pouvez demander à ce plugin de les gérer. Ces champs, s'il y en a,
- apparaissent dans un cadre «Liste des champs présents non gérés».",
Puis créons une nouvelle fonction cadre_champs_extras_infos() dans le fichier exec/iextras.php. Elle contient simplement l’appel d’un pipeline boite_infos avec un paramètre type indiquant quelle information afficher :
Nous appelons la fonction dans la partie gauche de la page comme ceci :
- // colonne gauche
- echo debut_gauche('', true);
- echo cadre_champs_extras_infos();
Le pipeline « boite_infos » appelle automatiquement un squelette prive/infos/$type avec les autres paramètres qui lui sont transmis (ici il n’y a pas d’autre chose que « type »), mais pour les infos de la page auteur sont transmis l’id_auteur ainsi que tout le contenu de l’entrée SQL de l’auteur en question (row) :
Bref, il nous suffit donc, pour avoir quelque chose de fonctionnel, de créer le squelette prive/infos/champs_extras.html avec :
- <p><:iextras:info_description_champ_extra:></p>
- <p><:iextras:info_description_champ_extra_creer:></p>
- <p><:iextras:info_description_champ_extra_presents:></p>
Et c’est tout ! Résultat : http://zone.spip.org/trac/spip-zone... .
Conclusions
Promis, j’arrête de parler de ce plugin « champs extras », de toute façon il n’y a plus grand chose à dire, l’essentiel est maintenant codé. Il restera à prendre en compte des champs extras autre que le type text ou textarea, comme des sélections, des liste de choix, etc...
En tout cas, cet exemple de plugin vous aura fait découvrir l’essentiel des pipelines de SPIP pour ajouter des éléments dans des formulaires, pour afficher des pages dans le privé. J’espère que cela vous aura été profitable et que ça vous donnera des idées pour vos réalisations.
Plus vous utiliserez les outils prévus par SPIP, meilleure sera sa portabilité au fil des évolutions. Sur ce, bons champs extras !