Le blog.

Créer un formulaire WordPress sur-mesure.

Dans le processus de création d’un site web WordPress, il est parfois nécessaire de créer un formulaire pour un besoin très spécifique. Des extensions existent, certes, mais abordons ici la création d’un formulaire WordPress sur-mesure « fait maison » et étudions les bonnes pratiques pour profiter des nombreux outils que nous offre WordPress.

Dans cet article, je travaille directement dans le thème WordPress TwentyFifteen. Vous pouvez télécharger les fichiers PHP du tutoriel (1 modèle de page et 1 functions.php) et vous en servir comme base pour votre formulaire maison.

Il va sans dire que les formulaires peuplent nos sites Internet, et cette tendance ne déroge pas aux sites WordPress. Dans beaucoup de cas, l’utilisation d’une extension dédiée à la gestion des formulaires s’avère efficace. Mais parfois, de par la spécificité voire la complexité des objectifs du formulaire à créer, le créateur du site WordPress doit savoir mettre les mains à la pâte et créer de toute pièce un formulaire sur-mesure.

Quand et pourquoi utiliser un plugin WordPress de formulaire ?

Contact Form 7, Gravity Forms, Form Maker… les extensions WordPress pour administrer les formulaires d’un site sont nombreuses. Et mieux : certaines sont bien faites et efficaces ! Ici même, nous avons récemment vanté Gravity Forms et listé de nombreux trucs et astuces de développeur web pour cette extension.

Avec ou sans plugin, de toute manière, un bon développeur WordPress retombera toujours sur ses pattes et saura profiter des actions et des filtres des (bonnes) extensions pour traiter et manipuler les données d’un formulaire après soumission. Mais une extension en fera toujours « plus » — voire « trop » — par rapport à un code fait sur-mesure :

  • des fichiers externes CSS et JS sont souvent appelés
  • la personnalisation peut s’avérer fastidieuse (écraser des styles CSS ou des événements JS)
  • des mises à jour de l’extension peuvent même parfois rendre un formulaire inutilisable du jour au lendemain
  • des addons tiers parfois payants sont souvent nécessaires pour relier un formulaire à des applications tierces
  • sans compter le temps passé à éplucher la documentation ou le code source du plugin pour comprendre les coulisses de ce dernier

Bref… A vous de juger du temps gagné et du temps perdu grâce (ou à cause) à une extension de formulaire WordPress.

Développer un formulaire WordPress : ce qu’il ne faut pas faire

Eviter les mauvais développements de WordPress
Attention au mauvais code !

Vous trouverez de nombreux tutoriels concernant la création d’un formulaire de contact WordPress personnalisé. Certaines solutions fonctionnent bien, certes, mais sont mal pensées : nous allons ici séparer le template visuel de toute la logique de traitement des données.

Vous pouvez en effet inclure dans votre template de page tout le code nécessaire au bon fonctionnement du formulaire : structure HTML, affichage des erreurs, réception des données, validation des entrées, envoi du mail ou autre logique…

Mais je déconseille fortement cela : dans une optique de « separation of concerns », il est logique de séparer la scène des coulisses. La scène, c’est l’affichage du formulaire ou des erreurs, tout ce qui est présenté à l’utilisateur. Les coulisses, ce sont toutes les actions qui se passent après la soumission d’une entrée de formulaire : vérification des données, validation, analyse conditionnelle, traitement et décision des actions…

Imaginez, dans le premier cas, devoir décider de changer le design et la structure HTML d’un template : il sera fastidieux de séparer le code qui concerne le formulaire du reste de la page. Si la logique, qui n’a rien à voir avec l’apparence du formulaire, est placée ailleurs (dans functions.php), il devient alors bien plus facile de maintenir le thème, modifier le design voire même d’ajouter des fonctionnalités à ce formulaire à l’avenir.

Ainsi, le code est plus organisé : la vue (la partie visible de l’iceberg) est éditable dans le template de la page tandis que le contrôleur (la partie cachée de l’iceberg) est géré dans le fichier functions.php. C’est ce que nous allons faire ici.

Votre propre formulaire WordPress sur-mesure : la (bonne) marche à suivre

Pour illustrer notre tutoriel, nous allons ici créer un petit formulaire très simple : un champ permet à un utilisateur de définir la valeur d’un don. Une cagnotte grandit à chaque fois qu’un utilisateur soumet le formulaire, si et seulement si le don est supérieur à 0 et inférieur à 10000 €.

Formulaire de don (cagnotte) dans WordPress
Un petit formulaire permet d’enregistrer les dons d’une cagnotte

La création de la structure HTML du formulaire

Dans un template (ou modèle de page) fait spécialement pour ce formulaire, on insère la structure HTML utile au formulaire.

Ici, rien bien compliqué… Un champ numérique avec son label, un bouton d’envoi et c’est tout !



<form action="#" method="POST" class="comment-form">
	<p>
		<label for="don">Valeur du don</label>
		<input id="don" type="number" name="don" value="5" />
	</p>
	<p>
		<input id="submit" type="submit" name="cagnote-don-envoi" id="submit" class="submit" value="Envoyer" />
	</p>
</form>

Notez tout de même que le bouton d’envoi de type submit possède un attribut name que nous utiliserons un peu plus loin pour bien vérifier, en PHP, qu’une entrée de formulaire a été envoyée et qu’il faut la traiter.

La méthode POST m’est plus habituelle mais si vous souhaitez envoyez vos données en GET, pas de souci tant que vous modifiez le reste du code adéquatement.

L’ajout de propriétés PHP et WordPress au formulaire



<form action="#" method="POST" class="comment-form">
	<?php wp_nonce_field('faire-don', 'cagnotte-verif'); ?>

	<p>
		<label for="don">Valeur du don</label>
		<input id="don" type="number" name="don" value="5" />
	</p>
	<p>
		<input id="submit" type="submit" name="cagnote-don-envoi" id="submit" class="submit" value="Envoyer" />
	</p>
</form>

Il s’agit ici de profiter des pouvoirs de WordPress afin de sécuriser l’utilisation de notre formulaire via les NONCES. La fonction wp_nonce_field() permet de vérifier que le contenu d’une requête d’un formulaire provient bien du site actuel, et non d’un autre site. Ce n’est donc pas une protection parfaite, mais protège dans beaucoup de cas.

Son premier argument représente une action, le second argument représente un nom. Ces deux mots sont réutilisés un peu après dans notre code afin de vérifier si le NONCE reçu correspond bien a ces deux arguments.

Il est très important d’inclure des champs NONCES dans vos formulaires WordPress.

L’interception des données avec l’action template_redirect et la vérification de la sécurité du formulaire

Nous attaquons la logique de traitement du formulaire : on sort donc du template pour aller dans le fichier functions.php afin de traiter les données reçues.



function traitement_formulaire_don_cagnotte() {

	if (isset($_POST['cagnote-don-envoi']) && isset($_POST['cagnotte-verif']))  {

		if (wp_verify_nonce($_POST['cagnotte-verif'], 'faire-don')) {

		}

	}
}
add_action('template_redirect', 'traitement_formulaire_don_cagnotte');

Voilà la fonction maison où la magie opère…

L’action template_redirect pour intercepter les données au plus tôt

Dans l’optique éventuelle de rediriger l’utilisateur vers une autre page après analyse des données du formulaire, il est primordial de hooker sur une action WordPress qui s’exécute avant que les headers de la page soient générés. On vérifie ce que l’on veut, traite nos données $_POST et on peut ensuite rediriger avec wp_redirect() sans crainte d’obtenir une erreur Cannot modify header information – headers already sent.

La première condition présente dans notre fonction nous permet d’être sûr qu’une entrée de formulaire a été soumise. Etant donné que notre fonction est couplée à l’action template_redirect, elle s’exécutera à chaque chargement de page. Il est donc important de filtrer les demandes et de vérifier que c’est le moment d’analyser l’entrée du formulaire : si $_POST[‘cagnote-don-envoi’] existe, c’est donc que l’on a cliqué sur le bouton submit du formulaire et qu’il est donc temps d’analyser la requête.

Cette même condition vérifie aussi, assez sommairement pour l’instant, la présence du NONCE défini ci-dessus, via isset($_POST[‘cagnotte-verif’]).

Sécurisons l’envoi/réception des données : la vérification des NONCES

Pas bien compliqué : la fonction wp_verify_nonce() fait la paire à wp_nonce_field() utilisé auparavant et permet de vérifier la véracité du NONCE envoyé. Il suffit d’y définir en paramètres le nom, puis l’action du NONCE (à l’inverse de ce que l’on a écrit dans wp_nonce_field() auparavant).

Traiter les données de votre formulaire personnalisé


function traitement_formulaire_don_cagnotte() {

	if (isset($_POST['cagnote-don-envoi']) && isset($_POST['cagnotte-verif'])) {

		if (wp_verify_nonce($_POST['cagnotte-verif'], 'faire-don')) {

			$don = intval($_POST['don']);

			if ($don < 0) {

				$url = add_query_arg('erreur', 'radin', wp_get_referer());

				wp_safe_redirect($url);
				exit();

			} 

			else if ($don > 10000) {

				$url = add_query_arg('erreur', 'trop', wp_get_referer());

				wp_safe_redirect($url);
				exit();

			}

			else {

				$cagnotte_actuelle = intval(get_option('valeur_cagnotte', 0));
				$nouvelle_cagnotte = $cagnotte_actuelle + $don;

				update_option('valeur_cagnotte', $nouvelle_cagnotte);

			}

		}

	}
}
add_action('template_redirect', 'traitement_formulaire_don_cagnotte');

Le plus dur est fait : une fois nos vérifications faites, à vous de faire ce que vous avez à faire avec les données du formulaire contenu dans la variable $_POSTMais décrivons ce que nous faisons ici…

  1. on stocke le montant du don dans une variable
  2. si ce don est inférieur à 0, on ajoute une variable GET ?erreur=radin dans l’URL afin de pouvoir afficher un message d’erreur en front-end, grâce à la fonction add_query_arg()Enfin, on redirige l’utilisateur vers cette URL
  3. si le don est supérieur à 10000 €, on fait la même chose mais en ajoutant une variable GET ?erreur=trop dans l’URL avant de rediriger l’utilisateur avec wp_safe_redirect()
  4. sinon, on ajoute le montant de ce nouveau don à l’ancienne valeur de la cagnotte pour mettre à jour la cagnotte stockée dans l’option WordPress valeur_cagnotte

C’est vraiment là que tout ce joue et que le formulaire sur-mesure prend tout son charme : vous pouvez vraiment faire ce que vous voulez. Vous disposez des données du formulaire dans $_POST, des données utilisateur si il est connecté… A vous de jouer et de créer les logiques et comportements qui ne sont pas facilement possibles avec des extensions.

Et, au risque de me répéter : les headers n’étant pas envoyés, vous pouvez rediriger l’utilisateur où bon vous semble selon telle ou telle condition.

Notez que la fonction wp_get_referer() permet d’accéder à l’URL d’origine, celle d’où le formulaire a été posté.

Renvoyer l’utilisateur vers la page du formulaire et transmettre des messages

Nous avons précédemment ajouté des valeurs GET dans l’URL de redirection si certaines conditions n’étaient pas respectées afin d’afficher des erreurs. Une petite mise à jour de notre template nous permet d’afficher des messages d’erreur avant le formulaire.


<?php if (isset($_GET['erreur']))
 {

 	echo '<div class="alert">';

		switch ($_GET['erreur'])
		{
			case 'radin' :
				echo 'Vous ne pouvez pas faire un don inférieur à 0 €.';
				break;

			case 'trop' :
				echo 'Nous n'acceptons pas les dons supérieurs à 10000 €.';
				break;

			default :
				echo 'Une erreur est survenue.';

		}

 	echo '</div>';

 } ?>

On analyse la valeur de notre variable $_GET[‘erreur’] et affiche le message correspondant selon le cas d’erreur.

Conclusion

Grâce à cet exemple pratique, nous avons vu comment mettre en place rapidement et proprement un formulaire WordPress créé sur-mesure :

  1. un modèle de page nous permet d’afficher le formulaire en lui-même ainsi que des messages d’erreur
  2. dans functions.php, l’action template_redirect nous permet d’intercepter les valeurs du formulaire, de les analyser comme bon nous semble et de rediriger l’utilisateur

En plus d’être flexible, cette solution sera bien plus performante qu’une lourde extension pleine d’options et de fichiers externes. Mais surtout, les perspectives sont énormes : création d’un post, envoi d’un e-mail, enregistrement dans une feuille de calcul Google Spreadsheet, connexion à une API d’un service tiers comme MailChimp, publication sur les réseaux sociaux, identification ou mise à jour d’un compte utilisateur, … Les possibilités sont infinies !

Faites-nous part en commentaire des utilisations originales de formulaires WordPress personnalisé que vous avez eu l’occasion de créer !

24 commentaires ont été rédigés, ajoutez le votre.

  1. Florent Maillefaud Répondre

    Merci pour ton article très enrichissant !

    Cela ne m’arrange pas trop, il faut que je reprenne tout un plugin pour sécuriser et bien coder :-)

    Bonne continuation

  2. Fred Répondre

    Bonjour,
    Il aurait été intéressant de traité au moins deux inputs pour le traitement de plusieurs erreurs.
    Cdlt

  3. Rétrolien: Intercepter les données des formulaires Contact Form 7 dans WordPress

  4. Marc Répondre

    Enfin un article qui ne présente pas un stupide formulaire de contact.

    Merci ça va beaucoup m’aider.

    Vraiment merci.

  5. simhabenoliel Répondre

    Bonjour
    Votre tuto est super
    J’ai creer un formulaire.. Seulement ‘ai besoin d’ajouter un captcha
    Savz vous comment faire?
    Merci

  6. fenucci michel Répondre

    J’aimerai savoir s’il est possible de conserver les valeurs des champs quand on redirige sur la page du formulaire en cas d’erreur, plutôt que de tout redevoir taper.
    Merci pour votre aide.
    Super tuto!!

      • Tricart Répondre

        Bonjour Pierre, un grand merci pour ton tuto il est vraiment top !!
        malgré ton lien je bataille depuis un moment pour conserver la valeur des champs après redirection sur erreur, je n’y arrive pas, aurais le temps de faire un petit exemple avec un input de base histoire de me remettre sur la voie ? ce serait top, en tout cas un grand merci

  7. Maeva Répondre

    Bonjour,

    Merci beaucoup pour cet article tres clair.
    Cela etant, connaissez-vous une plateforme securisee vers laquelle je pourrais rediriger mes visiteurs pour l’enregistrement de donnees personnelles confidentielles ?

    Merci d’avance !

    • Pierre Saïkali Répondre

      Maeva,
      Je pense qu’il est tout à fait envisageable de sauvegarder les données personnelles confidentielles sur le serveur qui héberge WordPress.
      Mais il faut évidemment bien mettre en place le serveur : serveur semi-dédié ou dédié, sécurisé au maximum, avec connexion HTTPS au site pour crypter les données.

  8. Denis Répondre

    Bonjour et merci pour vos tutoriels riches en enseignements!

    J’ai une petite question concernant ce tuto, Il semblerait que l’envoie de mon formulaire n’échappe pas au problème d’actualisation du nagivateur en faisant F5 (soumission à nouveau du formulaire).
    Ai-je manqué une étape et m’indiquer quelle est la partie du code à prendre en compte pour corriger mon erreur ou bien comment procéder pour enrayer ce défaut?

    Merci pour votre aide

    Denis

    • Denis Répondre

      pouvez-vous m’indiquer pardon…

    • Pierre Répondre

      Bonjour Denis,

      Dans ce petit tuto je ne propose pas d’envoyer/traiter les données du formulaire en AJAX, c’est bel et bien un formulaire « à l’ancienne » où la page s’actualise pour traiter la demande :)

  9. Denis Répondre

    Bonsoir,

    J’ai suivi vos tutoriels de création de metaboxes et de formulaire et je suis confronté à un petit problème.
    En effet les valeurs des inputs des métaboxes sont bien inséréées dans la base de données car elles apparaissent bien dans les colonnes créées au niveau du tableau « all contacts » après avoir soumis le formulaire par contre le champs inputs dans chaque description du contact du dashborad restent vides.

    Une petite idée?

    Merci pour votre aide

    Denis

    • Pierre Répondre

      Difficile à dire sans code. Si vous arrivez à uploader votre code sur un gist ou pastebin, je pourrais peut-être vous aider :)

  10. scapel Répondre

    Bonjour, et merci pour ce tuto qui me sera super utile! J’ai deux questions pour finir d’y voir clair:
    1) Dans les formulaires, normalement on indique le nom de la fonction appelée au moment du submit, et là on peut lire dans l’exemple action= »# » , alors comment arrive-ton sur la page functions.php ?
    2) Je souhaite mettre en application se tuto dans un shortcode, il y t’il des restrictions? Peut on faire passer des arguments a la page qui contient le shortcode comme le tuto l’explique?
    Merci d’avance!
    Seb.

    • Pierre Répondre

      Salut Seb,

      1) On utilise l’action template_redirect, qui « intercepte toutes les pages » si je puis dire. Il faut juste vérifier si une certaine clé dans le $_POST est présente.

      2) Je ne vois pas de problème à générer le code du formulaire avec un shortcode.

  11. dewy Répondre

    Bonjour,

    et merci pour ce tuto. cependant j’ai une petite question concernant la création du formulaire. est ce qu’il et possible d’utiliser cette technique pour une création d’un formulaire uniquement en back office.

    je suis en train de créer un plugin avec un formulaire qui affectera uniquement le back office. l’action template redirect est valable uniquement pour le front non?

    encore merci pour le partage de votre savoir ;)

  12. Rétrolien: Développer un formulaire WordPress : proposer un produit WooCommerce

  13. Anne Répondre

    Bonjour,
    merci pour cet article.
    Il y a un point que je n’ai pas compris : comment faire pour enregistrer dans la base de données les valeurs entrées dans le formulaire?
    Merci beaucoup

    • Pierre Répondre

      Bonjour Anne,

      Vaste question ! Cela dépend de ce que vous voulez enregistrer…

      S’il s’agit de créer un post/page/type de contenu, il faudrait utiliser quelque part wp_insert_post.
      S’il s’agit de mettre à jour la meta d’un post, il faudrait utiliser update_post_meta.
      S’il s’agit d’écrire dans une table sur-mesure dans la BDD, il faut utiliser l’object $wpdb.

  14. JS Répondre

    Bonjour et merci,
    est-il possible d’isoler les fonctions de traitement dans un autre fichier que functions.php ?

  15. yab Répondre

    bjr et merci pour cet article mais petit soucis,
    >> impossible de remonter quoi que ce soit en POST … ou en GET d’ailleurs à partir du form.
    >> par contre la fonction se lance bien mais mon print_r sur post reste définitivement vide :(
    Template : onepress plus

    une idée ?

    merci d’avance.

Laisser un commentaire