Formulaires CVT par l’exemple

Un formulaire de contact en 4 étapes

La création de formulaires est extrêmement simplifiée pour le webmestre ou le développeur. Voyons cela à travers un exemple simple et concret.

Étape 1 : Créer le squelette de son formulaire

Dans le sous-répertoire formulaires/ de votre dossier « squelettes », créez le fichier contact.html qui va contenir le code HTML de votre formulaire de contact. Par exemple :

<form action='#ENV{action}' method='post'>
	#ACTION_FORMULAIRE{#ENV{action}}
	<label>Votre email</label>
	<input type='text' name='email' value='#ENV{email}' />
	<br />
	<label>Votre message</label>
	<textarea name='message'>#ENV{message}</textarea>
	<input type='submit' name='ok' value='ok' />
</form>

Comme vous pouvez le constater, ce formulaire ne contient que quelques particularités :

  • l’attribut action de la balise <form> contient #ENV{action} qui est l’URL sur laquelle le formulaire sera envoyé ;
  • #ACTION_FORMULAIRE{#ENV{action}} indique à SPIP de transmettre aux fonctions « charger, verifier, traiter » les données saisies et celles contenues éventuellement dans l’URL (depuis SPIP 2.1 l’argument #ENV{action} est en fait inutile, étant à présent la valeur par défaut) ;
  • chaque input, textarea ou select contient la valeur #ENV{xxx} où xxx correspond à l’attribut name correspondant.

À ce stade, vous pouvez déjà afficher ce formulaire dans un squelette, avec la balise #FORMULAIRE_CONTACT ou directement dans le texte d’un article avec le code <formulaire|contact>. Vous apprécierez de pouvoir tester et affiner le rendu et le contenu de votre formulaire sans écrire une seule ligne de PHP.

Toutefois, si vous saisissez du texte et cliquez sur le bouton OK, votre formulaire ne fait rien, et vous ne retrouvez pas votre saisie.

Étape 2 : la fonction charger

Nous allons donc maintenant indiquer à SPIP quels sont les champs que l’internaute peut remplir.

Créez pour cela un fichier contact.php dans le sous-répertoire formulaires/ (juste à côté de votre squelette contact.html, donc), et mettez-y le code suivant :

<?php

function formulaires_contact_charger_dist(){
	$valeurs = array('email'=>'','message'=>'');
	
	return $valeurs;
}

?>

Que fait ce code ?

Il déclare la fonction charger du formulaire contact du répertoire formulaires consécutivement nommée formulaires_contact_charger.
Le suffixe _dist signale qu’il s’agit de la fonction charger par défaut de ce formulaire, mais qu’elle est éventuellement personnalisable (voir au sujet des surcharges http://programmer.spip.org/Surcharg...).

Cette fonction liste, dans la variable $valeurs, les champs de saisie de votre formulaire et, pour chaque champ, la valeur initiale par défaut.
La fonction formulaires_contact_charger_dist renvoie donc cette liste de champs.

Testez à nouveau votre formulaire : si vous remplissez les champs et validez avec le bouton OK, vous verrez que cette fois-ci le formulaire n’a pas perdu les valeurs que vous avez saisies (même s’il ne fait toujours rien).

Dans cet exemple, tous les champs sont vides par défaut. Nous pourrions améliorer notre fonction en remplissant automatiquement l’email lorsque le visiteur est identifié.
Cela nous donnerait le code suivant pour la fonction charger :

function formulaires_contact_charger_dist(){
	$valeurs = array('email'=>'','message'=>'');
	if (isset($GLOBALS['visiteur_session']['email']))
		$valeurs['email'] = $GLOBALS['visiteur_session']['email'];
	return $valeurs;
}

Si vous testez maintenant votre formulaire, en étant identifié, vous constaterez :

  • que le champ email est déjà rempli avec l’email de votre compte SPIP
  • que les valeurs saisies ou modifiées sont conservées telles quelles après validation

Étape 3 : Vérifier que la saisie est correcte

Avant de prendre en compte les valeurs saisies par l’internaute nous devons bien évidemment vérifier que ce qu’il nous envoie est correct.

Nous allons, par exemple, définir les contraintes suivantes :

  • les champs email et message sont obligatoires
  • l’email doit être valide

Pour vérifier la saisie, nous allons créer la fonction formulaires_contact_verifier_dist (sur le même modèle que la fonction charger) toujours dans le même fichier contact.php :

function formulaires_contact_verifier_dist(){
	$erreurs = array();
	// verifier que les champs obligatoires sont bien la :
	foreach(array('email','message') as $obligatoire)
		if (!_request($obligatoire)) $erreurs[$obligatoire] = 'Ce champ est obligatoire';
	
	// verifier que si un email a été saisi, il est bien valide :
	include_spip('inc/filtres');
	if (_request('email') AND !email_valide(_request('email')))
		$erreurs['email'] = 'Cet email n\'est pas valide';

	if (count($erreurs))
		$erreurs['message_erreur'] = 'Votre saisie contient des erreurs !';
	return $erreurs;
}

Remarque : l’utilisation de _request() est expliquée sur le site programmer.spip.org

La fonction verifier renvoie une liste de champs en erreurs, avec le message d’erreur correspondant à chaque champ.

À ce stade, vous ne verrez aucune différence si vous testez le formulaire : en effet, votre formulaire contact.html n’affiche pas les erreurs. Vous allez donc le compléter comme suit :

[<p class='formulaire_erreur'>(#ENV*{message_erreur})</p>]
<form action='#ENV{action}' method='post'>
	#ACTION_FORMULAIRE{#ENV{action}}
	<label>Votre email</label>
	[<span class='erreur'>(#ENV**{erreurs}|table_valeur{email})</span>]
	<input type='text' name='email' value='#ENV{email}' />
	<br />
	<label>Votre message</label>
	[<span class='erreur'>(#ENV**{erreurs}|table_valeur{message})</span>]
	<textarea name='message'>#ENV{message}</textarea>
	<input type='submit' name='ok' value='ok' />
</form>

Notez bien :

  • l’affichage d’un message d’erreur général renvoyé par la fonction verifier
    [<p class='reponse_formulaire reponse_formulaire_erreur'>(#ENV*{message_erreur})</p>]
  • les messages d’erreur devant chaque champ :
    [<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{email})</span>]

Vous pouvez maintenant tester votre formulaire en saisissant un email erroné ou en laissant un champ vide : votre formulaire commence déjà à interagir avec l’internaute !

Étape 4 : traiter !

Lorsque la fonction verifier ne renvoie aucune erreur, SPIP appelle automatiquement la fonction traiter correspondante. Déclarons cette fonction formulaires_contact_traiter_dist (toujours dans le fichier contact.php) et faisons-lui envoyer un mail au webmestre :

function formulaires_contact_traiter_dist(){
	$envoyer_mail = charger_fonction('envoyer_mail','inc');
	$email_to = $GLOBALS['meta']['email_webmaster'];
	$email_from = _request('email');
	$sujet = 'Formulaire de contact';
	$message = _request('message');	
	$envoyer_mail($email_to,$sujet,$message,$email_from);
	return array('message_ok'=>'Votre message a bien été pris en compte. Vous recevrez prochainement une réponse !');
}

Vous remarquerez que la fonction traiter ne fait aucune vérification : elles ont toutes été faites au préalable (dans la fonction verifier). Si la fonction traiter est appelée c’est qu’il n’y a aucune erreur.

La fonction traiter renvoie un message de succès, « message_ok », contenu dans un tableau. Comme pour les messages d’erreur, il faut compléter notre formulaire pour qu’il affiche ce message. Comme suit :

[<p class='formulaire_ok'>(#ENV*{message_ok})</p>]
[<p class='formulaire_erreur'>(#ENV*{message_erreur})</p>]
[(#EDITABLE|oui)
	<form action='#ENV{action}' method='post'>
		#ACTION_FORMULAIRE{#ENV{action}}
		<label>Votre email</label>
		[<span class='erreur'>(#ENV**{erreurs}|table_valeur{email})</span>]
		<input type='text' name='email' value='#ENV{email}' />
		<br />
		<label>Votre message</label>
		[<span class='erreur'>(#ENV**{erreurs}|table_valeur{message})</span>]
		<textarea name='message'>#ENV{message}</textarea>
		<input type='submit' name='ok' value='ok' />
	</form>
]

Notez bien :

  • l’affichage d’un message de succès au début
    [<p class="formulaire_message">(#ENV*{message_ok})</p>]
  • l’affichage conditionnel du formulaire de saisie en fonction de #EDITABLE : après la saisie, il est en général plus clair pour l’internaute de ne pas réafficher le formulaire complet mais juste le message de succès. #EDITABLE sert à cela.

Astuce : Il arrive parfois que l’on veuille placer une BOUCLE dans le formulaire (pour proposer les champs d’un select depuis la base par exemple). L’utilisation de #EDITABLE et de cette boucle provoque une erreur. La solution est d’y ajouter une boucle CONDITION comme le montre l’exemple ci-après :

    [<p class='formulaire_ok'>(#ENV*{message_ok})</p>]
    [<p class='formulaire_erreur'>(#ENV*{message_erreur})</p>]
    <BOUCLE_editable(CONDITION){si #ENV{editable}|oui}>
            <form action='#ENV{action}' method='post'>
                    #ACTION_FORMULAIRE{#ENV{action}}
                   <BOUCLE_article(ARTICLES){0,1}>#TITRE</BOUCLE_article>
             <label>Votre email</label>
                    [<span class='erreur'>(#ENV**{erreurs}|table_valeur{email})</span>]
                    <input type='text' name='email' value='#ENV{email}' />
                    <br />
                    <label>Votre message</label>
                    [<span class='erreur'>(#ENV**{erreurs}|table_valeur{message})</span>]
                    <textarea name='message'>#ENV{message}</textarea>
                    <input type='submit' name='ok' value='ok' />
            </form>
    </BOUCLE_editable>

C’est fini ! Vous pouvez utiliser votre formulaire de contact.

Le bonus : des formulaires ajax simplifiés

Vous souhaitez que l’interaction entre votre formulaire et l’internaute soit plus rapide et ne passe pas par le rechargement complet de la page à chaque erreur ou lors de la validation ?

Il faut que votre formulaire soit implémenté en AJAX. D’habitude c’est là que se situe la difficulté, ce type d’implémentation étant souvent long et laborieux. Mais c’est simplifié dans SPIP, par le formalisme CVT, qui vous fait bénéficier de mécanismes automatisés, dont l’ajaxisation de vos formulaires.

Pour cela, il suffit de placer votre formulaire dans une div dotée de la class ajax :

<div class='ajax'>
#FORMULAIRE_CONTACT
</div>

Et le tour est joué !

Pour aller plus loin

-  Cet exemple simple ne produit pas un joli formulaire. Pour un résultat plus esthétique, sémantique et accessible, n’hésitez pas à utiliser les recommandations de structures de Structure HTML des formulaires de SPIP pour tous vos formulaires SPIP
-  Tout savoir sur la fonction charger() : La fonction charger() des formulaires CVT
-  Tout savoir sur la fonction verifier()  : La fonction verifier() des formulaires CVT
-  Tout savoir sur la fonction traiter() : La fonction traiter() des formulaires CVT

Auteur cerdic, RealET Publié le : Mis à jour : 02/09/23

Traductions : català, English, Español, français, Nederlands