Les formulaires CVT de SPIP « Formulaires de SPIP par l’exemple »

samedi 27 juin 2009 // Semences SPIP

Introduction

Les formulaires de SPIP 2.0 sont maintenant découpés en 4 parties :

  • le HTML qui gère l’affichage graphique du formulaire,
  • la fonction charger() insère les valeurs préremplies,
  • la fonction verifier() contrôle les données soumises,
  • la fonction traiter() exécute les actions.

La partie HTML du formulaire est écrite dans le fichier formulaires/{nom}.html. Les 3 fonctions PHP dans le fichier formulaires/{nom}.php et s’appellent précisément :

  • formulaires_{nom}_charger_dist(),
  • formulaires_{nom}_verifier_dist(),
  • formulaires_{nom}_traiter_dist().

Le formulaire s’appelle dans un squelette SPIP par la balise #FORMULAIRE_{NOM}, par exemple #FORMULAIRE_PIPOTIN

Projet exemple : traduire via google

Nous avons besoin d’un formulaire disposant d’un champ texte, dont le contenu sera traduit en anglais en utilisant l’API de Google Translate au moment de la soumission.

HTML

La partie HTML ressemble à çà :

  1. <div class="formulaire_spip formulaire_pipotin">
  2. [<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
  3. [<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
  4. <form action="#ENV{action}" method="post"><div>
  5.         #ACTION_FORMULAIRE{#ENV{action}}
  6.         <ul>
  7.                 #SET{erreurs,#ENV**{erreurs}|table_valeur{traduire}}
  8.                 <li class="editer_traduire obligatoire[ (#GET{erreurs}|oui)erreur]">
  9.                         <label for="traduire">Traduire</label>
  10.                         [<span class='erreur_message'>(#GET{erreurs})</span>]
  11.                         <textarea name='traduire' id='champ_traduire'>#ENV{traduire}</textarea>
  12.                 </li>
  13.                 [
  14.                 #SET{erreurs,#ENV**{erreurs}|table_valeur{traduction}}
  15.                 <li class="editer_traduction[ (#GET{erreurs}|oui)erreur]">
  16.                         <label for="traduction">Traduction</label>
  17.                         [<span class='erreur_message'>(#GET{erreurs})</span>]
  18.                         <textarea name='traduction' id='champ_traduction'>(#ENV{traduction})</textarea>
  19.                 </li>
  20.                 ]
  21.         </ul>
  22.         <p class="boutons"><input type="submit" class="submit" value="<:pass_ok:>" /></p>
  23. </div></form>
  24. </div>

Analysons le code pour comprendre. Il y a plusieurs éléments. D’une part le code est encadré dans une balise <div> ayant une classe CSS générale « formulaire_spip » et une spécifique « formulaire_XX » :

  1. <div class="formulaire_spip formulaire_pipotin">
  2. </div>

Dedans, deux lignes servent à afficher les messages de réussite ou d’erreur :

  1. [<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
  2. [<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]

Les variables d’environnement « message_erreur » et « message_ok » sont envoyées au squelette via les retour des fonctions PHP…

Ensuite, la description du formulaire ajoute grâce à la balise #ACTION_FORMULAIRE des informations utiles à SPIP pour le traitement du formulaire.

  1. <form action="#ENV{action}" method="post"><div>
  2.         #ACTION_FORMULAIRE{#ENV{action}}
  3.         …
  4. </div></form>

L’URL de soumission est calculée par SPIP et envoyée par la variable « action » à l’environnement du squelette.

Se trouve ensuite les champs du formulaire, structurés dans un chainage UL / LI. Ils affichent éventuellement des messages d’erreurs.

Les champs sont insérés avec des classes CSS particulières si le champ est obligatoire ou en erreur.

  1. #SET{erreurs,#ENV**{erreurs}|table_valeur{traduire}}
  2. <li class="editer_traduire obligatoire[ (#GET{erreurs}|oui)erreur]">
  3.         <label for="traduire">Traduire</label>
  4.         [<span class='erreur_message'>(#GET{erreurs})</span>]
  5.         <textarea name='traduire' id='champ_traduire'>#ENV{traduire}</textarea>
  6. </li>

Pour terminer sur la partie HTML, signalons que la version 1.12 de CFG, à titre expérimental, propose une balise #SAISIE simplifiant l’écriture d’appel des champs de formulaire. Avec, cela donne l’écriture suivante :

  1. [(#SAISIE{textarea,traduire,oui}{label=Traduire})]

Soit au complet, le formulaire HTML donnerait :

  1. <div class="formulaire_spip formulaire_pipotin">
  2. [<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
  3. [<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
  4. <form action="#ENV{action}" method="post"><div>
  5.         #ACTION_FORMULAIRE{#ENV{action}}
  6.         <ul>
  7.                 [(#SAISIE{textarea,traduire,oui}{label=Traduire})]
  8.                
  9.                 [(#ENV{traduction}|oui)
  10.                         [(#SAISIE{textarea,traduction}{label=Traduction})]
  11.                 ]
  12.         </ul>
  13.         <p class="boutons"><input type="submit" class="submit" value="<:pass_ok:>" /></p>
  14. </div></form>
  15. </div>

Charger

La fonction PHP charger() permet d’envoyer à l’environnement du squelette de formulaire des valeurs par défaut. La fonction retourne un tableau PHP correspondant au contexte de compilation. Mais, si les nom des clés du tableau correspondent à des variables qui ont déjà été soumises (par soumission du formulaire ou via l’URL), alors ce sont ces valeurs que le squelette utilisera pour son contexte.

Pour notre formulaire, nous allons avoir besoin de 2 paramètres, l’un pour recevoir le texte à traduire, l’autre pour retourner le contenu de la traduction.

  1. function formulaires_pipotin_charger_dist() {
  2.         $contexte = array(
  3.                 'traduire' => '',
  4.                 'traduction' => '',
  5.         );
  6.         return $contexte;
  7. }

Ici, par défaut les deux paramètres sont laissés vides. Lorsque l’on soumet le formulaire (si l’on a rempli le champ "traduire" dans celui-ci) - et que la fonction vérifier ou traiter indique qu’il faut réafficher la saisie, la gestion de CVT fait que le texte soumis dans le champ "traduire" sera réintroduit automatiquement dans le contexte au chargement du formulaire. On ne perd donc pas les données saisies si une erreur apparaît.

Paramètres d’un formulaire

Il est possible d’envoyer des paramètres lors de l’appel du formulaire dans les squelettes, par exemple :

  1. [(#FORMULAIRE_NOM{parametreA, parametreB})]

Ces deux paramètres sont alors récupérables en tant que paramètres des fonctions Charger, Vérifier et Traiter :

  1. formulaires_nom_charger_dist($parametreA, $parametreB) {
  2. ...
  3. }

Vérifier

Elle sert à tester les saisies des utilisateurs et à retourner éventuellement des messages d’erreur en cas de problèmes, qui peuvent être spécifiques à un champ de saisie. Pour notre exemple, on peut proposer :

  1. function formulaires_pipotine_verifier_dist() {
  2.         $erreurs = array();
  3.         if (!_request('traduire')) {
  4.                 $erreurs['message_erreur'] = "Vous avez oublié d'écrire ! Votre clavier est cassé ?";
  5.                 $erreurs['traduire'] = "C'est là dedans qu'on écrit son texte !";
  6.         }
  7.         return $erreurs;
  8. }

La fonction vérifier est assez simple : elle retourne un tableau PHP vide s’il n’y a pas d’erreur, un tableau non vide s’il y a une erreur quelconque.

Traiter

C’est la fonction qui s’occupe de tout les traitements que doit exécuter le formulaire lorsque les vérifications sont valides.

Cette fonction retourne un tableau PHP qui peut contenir entre autre les clés "message_ok", "message_erreur", "editable" (si le formulaire doit ou non être réaffiché après le traitement).

Ici, nous devons interroger une page distante de Google et récupérer son résultat. On utilise l’API de SPIP pour cela (recuperer_page) et la fonction de PHP 5.2 pour analyser le JSON (tableau javascript) récupéré.

En cas d’erreur, on le signale ; en cas de réussite, on force l’insertion du texte récupéré dans le prochain chargement du formulaire, avec la fonction de SPIP « set_request() »

  1. // http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=hello%20world&langpair=en%7Cit
  2. define('URL_GOOGLE_TRANSLATE', "http://ajax.googleapis.com/ajax/services/language/translate");
  3. function formulaires_pipotin_traiter_dist() {
  4.         // creer l'url selon l'api google
  5.         $texte = _request('traduire');
  6.         $url = parametre_url(URL_GOOGLE_TRANSLATE,'v',"1.0",'&');
  7.         $url = parametre_url($url,'langpair','fr|en','&');
  8.         $url = parametre_url($url,'q',$texte,'&');
  9.         // chargement du texte traduit par google (retour : json)
  10.         include_spip('inc/distant');
  11.         $trad = recuperer_page($url);
  12.         // attention : php 5.2
  13.         $trad = json_decode($trad, true); // true = retour array et non classe
  14.         // recuperation du resultat si OK
  15.         if ($trad['responseStatus'] != 200) {
  16.                 return array(
  17.                         "editable" => true,
  18.                         "message_erreur" => "Pas de chance, faux retour de l'ami Google !"
  19.                 );
  20.         }
  21.         // envoi au charger
  22.         set_request('traduction', $trad['responseData']['translatedText']);
  23.         // message
  24.         return array(
  25.                 "editable" => true,
  26.                 "message_ok" => "Et voilà la traduction !",
  27.         );
  28. }

Documents joints

  • Formulaire Pipotin (Zip – 5.4 ko)

    Traduction par Google via un formulaire CVT (plugin adapté au plugin Zesty)

6 commentaires


Vos commentaires :

  1. Le 30 juin 2009 à 17:27, par Chourak

    Travaillant également sur les formulaires CVT de spip je coince un peu sur une action que je voudrais initier au submit des infos : reset le formulaire une fois que le traitement est effectué (dans mon cas enregistrement des infos en bdd). Des idées ? des pistes ?

  2. Le 2 juillet 2009 à 16:23, par Nicolas Hoizey

    Raaaah, c’est super tout ça, mais pourquoi ce n’est pas plutôt dans la doc officielle, ou sur programmer.spip.org (qui devrait devenir la doc officielle) ?

    Et puis la notation expérimentale de CFG c’est génialissime pour simplifier encore, mais pareil, ça va enfin aller dans le core, ou pas ?

    Bref, CVT c’est génial, mais quand on voit qu’il faut piocher les infos à droite et à gauche, et que ça nécessite Bonux et CFG pour être complet, ça freine un peu... ;-)

    En tout cas, bravo, ça va dans le bon sens !

  3. Le 2 juillet 2009 à 17:18, par marcimat

    @nicolas :

    Oui, chaque chose en son temps : là, j’ai écrit ça "à l’arrache"...

    Quand à #SAISIE... y a des problèmes de grammaire, faut reprendre l’écriture qui ne va pas, j’avais pas fait gaffe (en fait c’est moi qui n’écrivait pas correctement mes #INCLURE déjà à la base)...

    Enfin, pour CFG, il va y en avoir un bout de mis dans le core... je m’y engage... :p... pour #SAISIE, c’est moins certain :p ...

  4. Le 11 juillet 2009 à 17:26, par codewarrior

    Bon article, mais pouvez-vous clarifier le mécanisme editable. Je souhaiterais éviter qu’un formulaire soit posté plusieurs fois, en le faisant disparaitre lorsque le message ’posté OK’ apparait. Pour poster un autre formulaire, il faudrait alors rappeler la page, ce qui initialiserait un formulaire vide. Merci de votre aide. Remarque : par certains cotés, SPIP devient plus complexe à programmer que PHP !!!

  5. Le 7 août 2009 à 15:13, par Ben

    petite précision à propos de #EDITABLE : si l’on ne veut plus afficher le formulaire en cas de bon remplissage du formulaire, il faut bien positionner editable à faux ( dans l’exemple de trad donné ici on VEUT réafficher le formulaire donc il est laissé à true) .

    return array("editable" => false,
    "message_ok" => "Merci d'avoir rempli le formulaire",);

    On peut aussi faire un redirige_par_entete("http://manouvelleUrl.com") pour renvoyer vers une AUTRE page (de remerciement par exemple .

  6. Le 9 novembre 2009 à 16:56, par m*

    khlk jkghjkg jkjhk


Ajoutez votre commentaire

Ajoutez votre commentaire
Qui êtes-vous ? (optionnel)

Pour afficher votre trombine avec votre message, enregistrez-la d'abord sur gravatar.com (gratuit et indolore). Postez ensuite votre message ici, sans oublier d'indiquer votre adresse e-mail (non publiée).



Site réalisé avec SPIP | © 2001-2010 marcimat. Ma Graine .Net | Archives