The CVT forms of SPIP

It is easy to create dynamic forms. This is thanks to a transparent mechanism that separates the functioning of a form into a view (template) and three distinct steps: Charging (loading), Verifying, and Treating.

One view plus 3 steps

Take the example of a contact form that we wish to insert using the tag #FORMULAIRE_CONTACT.

When SPIP sees the #FORMULAIRE_CONTACT tag, it recognises it as a tag of the type #FORMULAIRE_xxx.
So it looks for the template formulaires/contact.html in order to display the form.
Nothing else is required for the form to be displayed [1]. This means that the styling and visual integration on the page can be carried out entirely independently of the 3 steps outlined below.

Charging (loading)
Before displaying the form, SPIP calls, if it exists, the formulaires_contact_charger_dist() function to fill the form’s fields with any default values. These fields and values are passed to the template, formulaires/contact.html, which makes use of them.

When a visitor fills in the form and and clicks the submit button, SPIP calls the formulaires_contact_verifier_dist() function to check the validity of the data. The function returns a list of messages corresponding to each field for which errors have been detected, or else an empty list if no error has been found.

If the verification process has not detected any error, then SPIP automatically calls the function which processes the data entered on the form: formulaires_contact_traiter_dist(). This function can undertake any operation with the form’s data: sending an email, saving to a database, ...

This "treating" function returns a list of information, including a message that confirms that the data which the user has submitted has been received.


Any arguments which are passed to the tag, in a form such as #FORMULAIRE_CONTACT{#ID_AUTEUR}, are automatically passed down to the functions which charge, verify and treat, in exactly the same order.


The separation of forms into a display template plus the three “CVT” functions, Charger, Verifier and Traiter, means that each of these elements can be customised independently:

  • the template of a SPIP form can be customised in the squelettes/ directory;
  • the formulaires_contact_charger_dist() function can be customised by defining a function named formulaires_contact_charger()
  • the formulaires_contact_verifier_dist() function can be customised by defining a function named formulaires_contact_verifier()
  • the SPIP standardisation of the CVT process makes it possible for forms to benefit from additional features without any development.

In particular, the ease of navigation and the response time experienced by the visitor can be improved by submitting the form using asynchronous requests. Programming in this way, using AJAX is complex. But SPIP and CVT radically simplify the treating of your forms using AJAX.

It is sufficient simply to surround the form in a div with the ajax class, such as:

<div class='ajax'>

When the visitor submits the form, it is sent to SPIP as an asynchronous request; SPIP only returns the result after checking and treating the submitted data. The visitor receives a faster response because the whole page is not reloaded, but only the zone that actually contains the form!

Compatibility with SPIP’s previous dynamic forms

The old dynamic forms of SPIP which used a template plus a series of functions balise_formulaires_xxx, balise_formulaires_xxx_stat, et balise_formulaires_xxx_dyn will still function. However you are advised to migrate to move towards the CVT system for your forms.

From a technical point of view, CVT is an additional layer implemented by the generic functions balise_formulaires_xxx, balise_formulaires_xxx_stat, et balise_formulaires_xxx_dyn.

It would therefore be possible, for example for the automatic collecting of arguments, to define one’s own balise_formulaires_contact_stat function.

Further information on the same subject is available here.


[1... but you may find the information about The HTML structure of forms in SPIP to be helpful.

Author Paolo Published : Updated : 11/07/23

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