Summary: Mailform4 alias Mailform2² - A contact form module with extensible form fields
Version: 2021-04-16
Prerequisites: pmwiki-2.2.14+, Captcha
Status: Stable
Maintainer: MKonrad, AntonyTemplier (i18n)
Users: +2 (View / Edit)
Categories: Forms PHP55 PHP72
Discussion: Mailform4-Talk

Questions answered by this recipe

  1. How can I easily integrate a contact form on my Wiki for user feedback?
  2. How can I modify the fields of such a contact form?
  3. How can I achieve that the fields will be validated?
  4. How can I prevent that it will be abused by spammers?


This cookbook is based on Mailform2 by Joachim Durchholz, a simple but useful contact form for feedback from users. The code has been mostly rewritten and provides the following new features:

  • customizable amount of form fields
  • customizable email template
  • form validation with user feedback
  • no more spam because of CAPTCHA usage
  • easier installation and integration
  • easier localization
  • support for checkbox and radio buttons


Download & Installation

  1. Download and install CAPTCHA
  2. Download mailform4.zipΔ
  3. Extract the Zip-Archive and copy the folders "cookbook" and "wiki.d" to your PmWiki-Installation. Now there should be a file mailform4.php in the cookbook/-directory
  4. Edit your local/config.php. Add the following lines after you have included the CAPTCHA-Script and modify them as you wish:
$Mailform4['recipient'] = ''; //the address the contact form output will be sent to
$Mailform4['subject'] = ' contact form message';
// Optionnal, uncomment those two lines to use cc or bcc extra contacts
//$Mailform4['cc'] = '';
//$Mailform4['bcc'] = '';

//define the fields and the validation checks:
$Mailform4ValidFields = array(
  'name' => array('string', 3, 120), //a string between 3 and 120 characters long
  'sender' => array('email', 3, 120),//an email between 3 and 120 characters long
  'text' => array('string', 3, null) //a string with at least 3 characters

  1. Include the contact form on any page you like with the following statement:
(Here comes some text...)

(:include Mailform4/FormTemplate:)

(... some more text)

Adding more form fields and modifying the content form output

By default, there are three fields for your contact form: Name, e-mail and message text. You can add as many fields as you wish and define how they will be validated. For each field you need to:

  1. Add a line to the $Mailform4ValidFields array in your local/config.php
  2. Add a field to your form template
  3. Add a variable to your form output

For example, if you want to add a new field "age", you can do the following:

  1. Add a new line for field "age" in the $Mailform4ValidFields array in your local/config.php:
$Mailform4ValidFields = array(
  'name' => array('string', 3, 120), //a string between 3 and 120 characters long
  'age' => array('number', 12, 99), //a number between 12 and 99
  'sender' => array('email', 3, 120),//an email between 3 and 120 characters long
  'text' => array('string', 3, null) //a string with at least 3 characters
The field "age" will be validated so that it must be a numeric value between 12 and 99. Currently 3 validation types are supported: "string", "number" and "email". "email" checks if it is really an email with the format user@domain.tld.
  1. Add a new form field "age" in the form template, which is located at the wiki page Mailform4.FormTemplate (or the page specified in $Mailform4MailTemplate):
(:input form "{*$PageUrl}?action=mailform4" post:)
|| border=0
||$[Your name]: ||(:input text size="50" name="mailform4[name]" value="{$Mailform4Name}":) ||
||$[Your age]: ||(:input text size="2" name="mailform4[age]" value="{$Mailform4Age}":) ||
||$[Your email address]:  ||(:input text size="50" name="mailform4[sender]" value="{$Mailform4Sender}":) ||
||$[Your message]: ||||
||(:input textarea name="mailform4[text]" value="{$Mailform4Text}" rows=10 cols=70:) ||||
||$[Enter CAPTCHA value]: {$Captcha} (:input captcha:) ||||
||(:input submit value="$[Send message]":) ||||
(:input end:)
Please notice that if your field is named "age", you have to use mailform4[age] as input name and $Mailform4Age (with a big "A") as input value.
  1. Add a new variable to the email template located in the wiki page Mailform4.MailTemplate:
The following text has been submitted via contact form at %DATETIME% by:

Name: %NAME%
Age: %AGE%
Email: %SENDER%
IP: %IP%


Created by contact form software %MAILFORM4_URL% @ %WEBSITE%
Please note that you cannot use wiki-code here to style the output. The email will consist of pure ASCII-text, no HTML.

As you can see, you can easily add as many fields as you wish. You just need to add a field to the validator-array, an input field to your form and a variable with the uppercase letters of your field name to the mail template.

Checkboxes and Radio Buttons

To use checkboxes or radio buttons:

  1. Specify a checkbox or radio validation type in the $Mailform4ValidFields array:
$Mailform4ValidFields = array(
  // ... other fields ...
  'contact' => array('checkbox', null, null), //a single checkbox allowing both checked and unchecked
  'why' => array('radio', array('Commend', 'Complain', 'Enquire'), null) //a set of three radio buttons
  • For each checkbox, the 2nd and 3rd parameters of the array control the validation. Setting both to TRUE or FALSE will enforce that the checkbox is checked or unchecked respectively. Setting them to nulls or different booleans will allow both unchecked and checked. The value of the field when rendered in the email is "checked" or "unchecked".
  • For a set of radio buttons, the 2nd parameter is an array of valid field values. (The 3rd parameter is ignored.) The value of the field when rendered in the email is the selected valid field value.
  • For a multi-language use, the value of the fields rendered in the email can by translated via the Site.XLPage-Mailform4-XX page. For instance, to use the above 'why' element in french, you should add these lines :
  # Return for checkboxes an radios 
  'Commend' => 'Commande',
  'Complain' => 'Plainte',
  'Enquire' => 'Requête'
  1. Then create the form elements:
(:input form "{*$PageUrl}?action=mailform4" post:)
|| border=0
||$[Options]: ||(:input checkbox name="mailform4[contact]" value="Contact" {$Mailform4Contact} :) $[Please contact me] ||
||$[Reason]: ||(:input radio name="mailform4[why]" value="Commend" {$Mailform4WhyCommend} :) $[I have a commendation] ||
||           ||(:input radio name="mailform4[why]" value="Complain" {$Mailform4WhyComplain} :) $[I have a complaint] ||
||           ||(:input radio name="mailform4[why]" value="Enquire" {$Mailform4WhyEnquire} :) $[I have a question] ||
||(:input submit value="$[Send message]":) ||||
(:input end:)
  • For a checkbox, the input variable name (eg. $Mailform4Contact) is formed as for string, numeric and email fields.
  • For a set of radio buttons, each button in the set needs an input element. Each shares the same name. The values must correspond to those in the $Mailform4ValidFields entry. The input variables (eg. $Mailform4WhyCommend) are formed by concatenating the expected input variable name with the value for the button. (Only one of these variables will be set to "checked".)

Styling of validation messages

When the validation of some form fields fails, the user gets messages indicating that he or she should fill out the form correctly. When everything went fine and the email got sent, there is also an informational message displayed. You can should define some CSS styles to emphasize these messages. You can use this example in your CSS-file:

    margin: 10px;
    padding: 5px;
    background-color: #cfe49b;
    border: 1px solid #a3c159;

    margin: 10px;
    padding: 5px;
    background-color: #e4b39b;
    border: 1px solid #c16859;


Right now Mailform4 is available in English, German and French. If you want to translate it to your language or translate new form fields, you can use the default german translation located in Site.XLPage-Mailform4-de or default french translation located in Site.XLPage-Mailform4-fr as an example. See PmWiki:Internationalizations for more information about how to edit or load a XLPage.

Exemple of french localization with all strings used by mailform4:

  ### Mailform4 translations
  'Your email address' => 'Votre adresse email',
  'Your message' => 'Votre message',
  'Your name' => 'Votre nom',
  'Enter CAPTCHA value' => 'Entrer le CAPTCHA-Code',
  'Send message' => 'Envoyer message',

  # Check form messages
  'Please enter a valid email address.' => 'Saisissez une adresse email valide.',
  'Please enter a valid number between %d and %d.' => 'Saisissez un nombre compris entre %d et %d.',
  'Please enter a string that is between %d and %d characters long.' => 'Saisissez un texte entre %d et %d caractères.',
  'Please uncheck the checkbox.' => 'Décochez la case, SVP.',
  'Please check the checkbox.' => 'Cochez la case, SVP.',
  'Please fix the checkbox.' => 'Corrigez la case, SVP',
  'Please select one radio button.' => 'Sélectionnez un des choix proposés, SVP',
  'Please enter a value.' => 'Saisissez une valeur, SVP.',
  'Invalid CAPTCHA code. Please try again.' => 'Code CAPTCHA incorrect. Réessayez, SVP',

  # Feedback messages
  'Sending mails has been disabled.' => "L'envoi d'email a été désactivé.",
  'Thank you! Your mail has been successfully sent!' => 'Merci ! Votre email a été envoyé avec succès !',  
  'Failure sending email.' => 'L'envoi de votre email a échoué',

  # Return for checkboxes an radios 
  'checked' => 'coché',
  'unchecked' => 'décoché',

  # Name of fields
  'name' => 'nom',
  'sender' => 'email',
  'text' => 'texte'

Release notes

  • 2021-04-16: PHP 7.2 compatible
  • 2015-07-20: Use Markup_e for PHP 5.5. Revert wiki pages (MailTemplate, FormTemplate and translations) from wiki.d to wikilib.d ( to prevent to overwrite user's customizations when upgrading )
  • 2013-10-08: Fix bug that messed up $XLLangs array. Moved wiki pages (MailTemplate, FormTemplate and translations) from wikilib.d to wiki.d ( suggested by IanMacGregor )
  • 2013-03-29: Add extra headers : Cc, Bcc
  • 2012-09-18: Add headers to provide utf-8 encoded mails
  • 2012-02-10: Modifications to correct logic of feedback error messages and full translation for new form elements (checkboxes and radio buttons).
  • 2012-01-11: Added support for Checkboxes and Radio buttons. Modifications to correct quoting in strings/textareas to avoid wiki injection attacks. User configurable Mail Template page via $Mailform4MailTemplate. Added %HOST% field for use in the email template, which is the result of gethostbyaddr on %IP%. (Newly introduced English strings have not been provided with French or German translations.)
  • 2011-11-14: Better localization support: Previous version 2011-06-21 introduce bug with "from email information". It's now fixed, recipient can now reply directly to sender. Name of field can be translated via the Site.XLPage-Mailform4-?? allowing full translation of error messages. Adding "name" field in default config in order to have this cookbook working "out of the box".
  • 2011-06-21: Add french translation & allow full translation
  • 2010-07-22: Fixed a bug not showing the success message
  • 2010-07-11: Fixed some bugs that occurred when trying to send an email
  • 2010-05-11: First release

See also



This space is for User-contributed commentary and notes. Please include your name and a date (eg 2007-05-19) along with your comment. Optional alternative: create a new page with a name like "ThisRecipe-Talk" (e.g. PmCalendar-Talk).

See discussion at Mailform4-Talk

User notes +2: If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.