CVT Forms by example

A contact form in 4 steps

The creation of forms has been greatly simplified for webmasters and developers. Let’s take a look at a simple, concrete example.

Stage 1: Create the template for the form

In the sub-directory called formulaires/ of your "squelettes" folder, create a file called contact.html which will contain the HTML code for your contact form. For example:

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

As you can see, this form only has a few constituent elements:

  • the action attribute for the <form> HTML tag contains #ENV{action}, which represents the URL of the current page on which the form will be sent
  • #ACTION_FORMULAIRE{#ENV{action}} tells SPIP to take into account the data sent by this form and the calls to the three functions: "charger, verifier, traiter"
  • each input, textarea or select field contains the #ENV{xxx} value, where xxx corresponds to the corresponding attribute name.

At this stage already, you can display this form in a template by using the #FORMULAIRE_CONTACT tag or insert it directly into the text of an article using what SPIP refers to as calling a "model" template with <formulaire|contact>. You are already able to test and refine the presentation and content of your form without needing to write even one single line of PHP code.

However, if you were to enter some text and actually click on the OK button, your form won’t do anything, and you won’t find your data going anywhere.

Stage 2: The "charger" function

So we’re now going to tell SPIP which fields the site visitor can enter.

To do this, create a contact.php file in the formulaires/ sub-directory (right beside your contact.html file), and put the following code into it:

<?php

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

?>

Just what does this code do, then?

It declares the charger function for the contact form in the formulaires directory which is therefore named as formulaires_contact_charger.
The _dist suffix indicates that this is the default charger function for this form, but that it can be later customised (refer to the topic about overloading functions http://programmer.spip.org/Overload...).

This function lists in the $valeurs array variable all of the fields in your form, and the initial default value for each of those fields.
The formulaires_contact_charger_dist function then returns this list of fields.

Test your form again: if you enter the fields and validate with the OK button, you will see this time that the form has not lost the values that you have entered (even if the form still doesn’t actually do anything).

In this example, all of the fields are empty by default. We could improve our function by automatically filling out the email whenever the site visitor is identified.
This would give us the following code for the charger function:

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

If you now test your field once you have already been identified, you will notice that:

  • the email field has already been filled out with your SPIP account email
  • the values entered or modified are retained even after validation

Stage 3: Check that the entered data is correct

Before accepting the values entered by the site visitor, we should naturally check that whatever the visitor has entered is valid data.

So for example, we will define the following constraints:

  • the email and message fields are mandatory
  • the email field must be correctly formatted

To check the inputs, we will create the formulaires_contact_verifier_dist function (on a similar basis to that charger function) within the same contact.php file that we wrote before:

function formulaires_contact_verifier_dist(){
	$erreurs = array();
	// check that mandatory fields are indeed filled out:
	foreach(array('email','message') as $obligatoire)
		if (!_request($obligatoire)) $erreurs[$obligatoire] = 'This field is mandatory';
	
	// check that any entered email address is correctly formatted:
	include_spip('inc/filtres');
	if (_request('email') AND !email_valide(_request('email')))
		$erreurs['email'] = 'This email address is not valid';

	if (count($erreurs))
		$erreurs['message_erreur'] = 'Your data entry contains errors!';
	return $erreurs;
}

Note: using the code _request() is explained in detail on the site programmer.spip.org

The verifier function returns a list of fields in error, with the error message corresponding to each field that is in that list.

At this stage, you will not see any difference if you test the form: in fact, your contact.html form does not display any errors. You will therefore need to modify it as shown below:

[<p class='formulaire_erreur'>(#ENV*{message_erreur})</p>]
<form action='#ENV{action}' method='post'>
	#ACTION_FORMULAIRE{#ENV{action}}
	<label>Enter your email</label>
	[<span class='erreur'>(#ENV**{erreurs}|table_valeur{email})</span>]
	<input type='text' name='email' value='#ENV{email}' />
	<br />
	<label>Enter your 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>

Important:

  • displays a general error message returned by the verifier function
    [<p class='reponse_formulaire reponse_formulaire_erreur'>(#ENV*{message_erreur})</p>]
  • the error messages before each field:
    [<span class='erreur_message'>(#ENV**{erreurs}|table_valeur{email})</span>]

You can now test your form by entering an invalid email address or by leaving any of the fields deliberately empty: your form is already interacting with the site visitor!

Stage 4: Do the form processing!

Whenever the verifier function does not return any errors, SPIP automatically called the corresponding traiter (process) function. We declare this function as formulaires_contact_traiter_dist (still in the same contact.php file) and make it send an email to the site’s webmaster:

Our contact form';
	$message = _request('message');	
	$envoyer_mail($email_to,$sujet,$message,$email_from);
	return array('message_ok'=>'Your message has been processed. You will receive a response as soon as possible!');
}

Note that the verifier function does not do any checking: all the checking has been done previously (in the verifier function). If the traiter function is called, it means that the verifier function has already established that there are no major problems with the data entered.

The traiter function returns a success message, "message_ok" stored in an array. Just like the error messages, you need to modify the form so that this success message can be displayed, as shown in the code below:

[<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>Enter your email</label>
		[<span class='erreur'>(#ENV**{erreurs}|table_valeur{email})</span>]
		<input type='text' name='email' value='#ENV{email}' />
		<br />
		<label>Enter your 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>
]

Important:

  • displays a success message at the top of the form
    [<p class="formulaire_message">(#ENV*{message_ok})</p>]
  • conditionally displays the the data entry form in #EDITABLE mode: this means that after entering the data, it is generally more clear for the site visitor to not redisplay the whole form, but only the success message. That’s what #EDITABLE is used for.

And that’s it ! You can now deploy your contact form.

Bonus

Would you like the interaction between your form and the site visitor to be faster and not need to completely reload the entire page any time that there’s an error or during the validation?

What you need is for your form to be run using the AJAX mode. Usually this is a cumbersome task, and this kind of implementation requires a lot of laborious and difficult work. But this has been simplified in SPIP, using the CVT standard methodology, which means that you can benefit from the automated systems available for forms, one of which includes ajaxification of your forms.

In order to turn it on, all you need to do is to enclose your form in a <div> with the class ajax:

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

And that’s all! Too easy by far...

To take things a little further

-  This simple example does not generate a terribly pretty form. For a more aesthetically pleasing, semantically useful and accessible result, do try and use the structural recommendations in The HTML structure of forms in SPIP for all of your SPIP forms.

-  Full details about the charger() function: The charger() function in CVT forms
-  Full details about the verifier() function: The verifier() function in CVT forms
-  Full details about the traiter() function: The traiter() function in CVT forms

Author Mark, Thomas Sutton Published : Updated : 22/07/23

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