It's better when it's simple

User Tools

Site Tools


Bureaucracy Plugin

Compatible with DokuWiki

  • 2016-06-26 "Elenor Of Tsort" yes
  • 2015-08-10 "Detritus" yes
  • 2014-09-29 "Hrun" yes
  • 2014-05-05 "Ponder Stibbons" yes

plugin Easily create HTML forms to collect data which can be sent via email or used to create pages.

Last updated on
Syntax, Action
Conflicts with

Similar to conform, contact, contactmodern, form

Tagged with create, email, form, poll

The bureaucracy plugin allows you to create a HTML form right within DokuWiki. Input format validation is automatically handled by the plugin and requires no coding. User input can be emailed to a preconfigured address or used to create new pages using a template.

Download and Installation

Download and install the plugin using the Plugin Manager using the download link given above. Refer to Plugins on how to install plugins manually.


You might want to use on an open wiki the CAPTCHA plugin to avoid automated spam. When captcha plugin is installed, bureaucracy integrate automatically the captcha check in its form submit handling. The SwiftMail plugin may help when your DokuWiki can't send mails. When you use the template action of bureaucracy, you can add in the template a dataentry of the Data plugin that structures and stores your information for good accessibility, whereas the dataentry you can use placeholders of bureaucracy to place information from the form.

additional actions
An additional plugin to look at is the pagemod plugin which add an action pagemod for the bureaucracy plugin to add data to an existing page (in addition to the current templating and mailing functionality)

additional fields
The Data plugin can be useful in templates as mentioned before, but it provides a data_aliastextbox field too, that lets you create fields with types and type aliases of the data plugin. Some of these types have a nice layout e.g. pagesuggestions or listing using predefined options from type aliases. See example.


Without the CAPTCHA, this plugin should only be used on closed wikis, because it could easily be abused as a spam gateway.


Let's start with an example:

A sample form with validation errors

Action mail
Thanks "Thanks for submitting your valuable data."

Fieldset "A set of fields"
Textbox  "Employee Name" "=Your Name"
number "Your Age" >13 <99
email "Your E-Mail Address"
textbox "Occupation (optional)" !
password "Some password"

fieldset "even more fields"
select "Please select an option" "Peaches|Apples|Oranges"
static "Some static text that could be an agreement"
yesno "Read the agreement?"
textarea "Tell me about your self"
textbox "You need to write 'agree' here" /^agree$/
submit "Submit Query"

As you can see, you can define a email address where the data should be sent to and a thank you text to be shown when a user submitted the form. What follows are the various fields to fill in.

Field definitions:

  • Fields are defined by giving a type and a label.
    • For fieldsets and the submit button, the label is optional.
  • Some fields, like the select type, need a third parameter.
  • Additional constraints can be added after the main options.
  • Arguments need to be wrapped in double quotes when they contain spaces e.g. "S p a c e s"
  • Including a " by using "" e.g. "With ""quotes"" in the string"

The plugin takes care of validating the form, the field types, and set constraints.


  • action
    • The first parameter needs to be a supported action (see below).
      Currently supported are mail, template and pagemod (if this plugin is installed).
    • Additional parameters for type mail:
      • one or more email addresses to send the data to (required)
    • Additional parameters for type template:
      • name of a page or namespace (trailing colon) to use as template or a single underscore _ to try and use the target namespace template (use an absolute path) (required)
      • namespace:prefix or namespace: (mind the trailing colon) where new pages shall be created (optional)
      • separator to use when combining multiple fields into the pagename (optional)
    • Multiple actions can be defined by adding another action field
  • thanks
    • define a text to be displayed when the form was submitted. (optional)
  • fieldset
    • creates a new set of fields
    • a label is optional
    • Can be shown/hidden depending on the value of another field above it (see below)
      • Switching depends on the field given as second parameter (optional)
      • Fieldset is displayed as that field is set
        or has an exact match with the value given as third parameter (optional)
  • static
    • adds some static text to the form
  • wiki
    • similar to static, but parses the input as Wiki syntax
    • should be used sparsely as it is computationally expensive
  • textbox
    • creates a single line input field
    • needs a label
  • password
    • creates a single line password input field
    • needs a label
  • email
    • creates a single line input field
    • needs a label
    • the input is validated to be a valid email address
    • argument @@ marks emailadress as Reply-To address for mail action
    • creates a single line input field
    • needs a label
    • the input is validated to be numeric
    • can be pre-filled with auto-incrementing number, see example.
  • textarea
    • creates a multi-line input field
    • needs a label
    • to change the default size of 10 rows to N rows, use the argument xN ( x23 ) (optional)
    • creates a checkbox
    • needs a label
    • needs default values for yes and no ( =true_value !false_value )
  • select
    • creates a dropdown list
    • needs a label
    • needs a second argument containing the select options separated by a pipe | char
      ( "Peaches|Apples|Oranges" )
  • radio
    • creates a set of radiobuttons
    • needs a label
    • needs a second argument containing the radio options separated by a pipe | char
      ( "Peaches|Apples|Oranges" )
  • hidden
    • creates an invisible field with static data
    • needs a label
    • needs a default value parameter ( "=some value" )
  • hiddenautoinc
    • needs a label
    • creates an invisible field with a number that increases by 1 on each form submit
  • submit
    • creates a submit button (required)
    • a button label is optional
  • user / users
    • a DokuWiki user or list of DokuWiki users
    • needs a label
    • provides autocompletion
  • date
    • a date in the format YYYY-MM-DD
    • needs a label
    • provides a date picker
  • time
    • a time in the format (H)H:MM(:SS)
    • needs a label
  • usemailtemplate template_id
    • the content of the <code html>..</code> and <code text>..</code> at the template page is used in the email of the mail action, instead of default table with field values.
    • template_id is absolute or relative pageid. If relative, it is solved against the pageid of the form
  • addpage page_tpl page_tgt
    • adds another page page_tgt based on a template page page_tpl
    • only for use with the template action
    • if page_tpl is absolute or relative pageid. If relative, it is solved against the pageid of the form
    • page_tgt is relative to destination of page created by action field. e.g. action field tries to create new:destination, then addpage will try to add new:destination:page_tgt
    • When in the action field a ! is given as template, that template is skipped and only template(s) added by addpage are used.
  • data_aliastextbox (needs plugin)
    • requires Data plugin to display the field (See example)
    • needs label
    • an additional parameter is starting by underscore _ for type of field, using dataplugin type syntax
      • datatypes with a type alias that defines 'valid values' will appear as a (multi)select field
      • otherwise it appears as usual textbox, sometimes with added features as datepicker and pagesuggestions
  • labels
    • parameter is a wiki page containing a list of label translations
  • file
    • file upload FIXME

Constraints and Defaults

  • Start with a > followed by a number to require numeric data bigger than the given number
  • Start with a < followed by a number to require numeric data smaller than the given number
  • Start with a = to set a default value
  • Use a single ! char to make a field optional
  • Use a single ^ char to give a field the focus (possible for only one field at a page)
  • Use a single @ char to make its value be used for the pagename in template mode (the value will be appended to the pagename, separated by an underscore)
  • Use a double @@ to mark the value of a field as Reply-To address for mail mode
  • Use a number of 0000 for a number field, for completing inputted values with leading zeros upto the same length
  • Use a ++ for a number field to make it auto-increment the counter on each form submit.
  • Enclose a regular expression with / chars to require the the regexp to match before the field is accepted (case insensitive). Examples (for additional information see below):
    • /^[^\/:]+$/ nice for pagenames, the chars / and : aren't allowed
    • /^[0-9 \/()+\-]+$/ nice for phone numbers, allows only numbers and the chars ()-+/
  • Set message for if regular expressions don't match by using **Message. Example:
    • textbox "Your pagename" /^[^\/:]+$/ "**Don't use / or : in your page name"
  • Only for dataplugin field: start with a _ to define type alias.

A simple guide to Regular Expressions

A regular expression is used to define a pattern of text. In its simplest case (as used here) if the pattern can be found then the text is accepted, if the test fails then the text is rejected. Under bureaucracy, when the submit button is pushed text boxes are compared to their regular expressions. If the test passes, then submit can continue, if the test fails then submit rejects the form and asks for a correction.

The simplest possible regular expression (regex) is a single character: /a/. This states that the input text (the string) must contain somewhere within it the letter “a”. “access” would pass, as would “backups” but “Hello World” would fail.

The regex may contain a number of characters: /abc/ which requires that the string “abc” be found somewhere. “Learn your abc” passes but “a bc” fails (there is a space between the “a” and “b”).

Frequently you want to select one of a number of characters. Square brackets group a number of alternatives together: /[abc]/ means that either “a” or “b” or “c” must occur somewhere within the string. Ranges are possible, [a-z] means any lowercase letter. Putting things together, /rfc[0-9][0-9][0-9][0-9]/ matches any four digit request for comments such as “rfc0248” or “rfc4027”.

The brackets are called meta-characters, that is they don't represent real characters (like for instance “a”) but do affect how the string is interpreted. There are a number of meta-characters the most important of which are:

  • “^” which matches the start of a string.
  • “$” which matches the end of a string.
  • “*” which means that the character before it may appear 0 or more times.
  • “+” which means that the character before it must appear 1 or more times.
  • “\” means treat the next character as an ordinary character, not a meta-character.

For example /^[yn]$/ means that the string must start with a “y” or and “n” and have no characters following. “y” and “n” are therefore the only possible strings. /^I[0-9]+$/ matches US interstate roads: “I12”, “I66” and so forth. Somewhat confusingly “^” has another meaning when it occurs immediately after a left bracket, it negates the contents. /[^ab]/ matches any character other than and “a” or “b”.

Looking now at the examples above. /^[^\/:]+$/ starts at the beginning of the string (“^”) accepts any character other than “/” or “:” (“[^\/:]”, note the “\” to make the “/” into a normal slash), accepts these characters 1 or more times (“+”) and then needs to see the end of the string “$”. “/home/doc.txt” fails, there are slashes present. “ puzzled ” is acceptable.

Finally /^[0-9 \/()+\-]+$/. The whole string consists of a one or more characters (“^” to “+$”). These characters must be (“[” to “]”) numbers (“0-9”), spaces (“ ”), slashes and parenthesis (“\/” and “()”), pluses and minuses (“+\-”).

For more information:

External Label Names

By default all labels are used as provided. Eg. they are displayed in the form and they are used as placeholders for the template mode. In some cases you might want to use simpler names for the fields but still have more extensive labels displayed in the form.

This can be achieved with defining label translations in a separate wiki page and give this page in the labels field:

action mail
labels mylabels

fieldset "field"
textbox  "name"
number   "age" >13 <99
submit   "submit"

The translation page needs to contain a single wiki list with items named label = translation:

  * field  = Tell us about yourself"
  * name   = Your Name
  * age    = Your Age
  * submit = Send your Data

The above would result in the following form:

Dependencies with Fieldsets

Sometimes part of a form should only be asked when a certain answer was picked for a previous question. Simple dependencies like that can be created by using Fieldsets.

Consider the following example:

action    mail

fieldset  "Your Order"
textbox   "Your Name"
select    "What do you want"  "Car|Blimp"

fieldset  "Car Parameters" "What do you want" "Car"
number    "Number of Wheels"
textbox   "Extras"

fieldset  "Blimp Parameters" "What do you want" "Blimp"
select    "Filling" "Helium|Hot Air"
number    "Size"

fieldset  "Payment"
yesno     "Can you pay right now?"

fieldset  "Details" "Can you pay right now?"
textbox   "Name"
number    "Amount"

fieldset  "Confirm Order"
submit "Submit Query"

In this example, a user can select to order a car or a blimp. Depending on his choice, the second or third fieldset will be hidden or shown accordingly. The second parameter for the fieldset field references a previously defined field and the third parameter the value that field shall have to display the fieldset. Only exact matches are supported here, so best combine this feature with a select field as shown above.

When the user marks the checkbox of the yesno field in the fourth fieldset the fifth fieldset is shown, so the correct details can be noted. Here is no third parameter given to the fieldset, so it will check if the referred field is set.


  • Apparently dependencies don't work when the choice is provided by “radio” (only “select” and “yesno” work) for some reason. There might by a logical explanation for this, maybe.
  • How to use dependencies to adapt a select list. Example:
    First level “select” list
    select "Vehicule" "Car|Motorbike"

    Second level “select” lists:

    fieldset  "Car spareparts" "Vehicule" "Car"
    select "Sparepart1" "4 wheels|steering wheel"


    fieldset  "Motorbike spareparts" "Vehicule" "Motorbike"
    select "Sparepart2" "3 wheels|handle bar"

    To create an unique destination for both arguments “Sparepart1” and “Sparepart2” use the construct


    The chosen one will be filled out and the not chosen one will be replaced by “”.

Sometimes you may want to link to a bureaucracy form and pre-fill one or more fields. This can be easily achieved by adding parameters to your link using @-wrapped field names.

Imagining the form given in the previous section is on a page called orderform. Here is how you could link to a form for ordering Hot Air blimps:

[[orderform?@What do you want@=Blimp&@Filling@=Hot Air|Order a Hot Air Blimp!]]

Action Modes

The bureaucracy does three things:

  1. it displays a neat form
  2. it validates user input
  3. it gives the user input to a action mode

The last step is where the data is processed. What action is to be used is defined in the action field as described above. Currently two modes are supported: mail and template. Additional modes (e.g. for storing the data in a database) can easily be added.

Mail Mode

This is a simple action. When used default all user input will be sent by email to the configured email address. See the example above how to use it. You may specify multiple recipient mail addresses separated by spaces.

Example to automate email to an address which the user enters:

Fieldset "Some Information"
Textbox "Employee Name"
email Email_Address
Action mail @@email_address@@
  • If you add the field usemailtemplate you can define alternative content for the email. The template should contain two code blocks with text and html version of the message. Other text on the page is ignored. In the template you can use placeholders.
  • With the subject field you can replace the default subject
  • and by marking field(s) with the option @@ you add Reply-To address(es) to the mail.


action mail @MAIL@ 
usemailtemplate your:template
subject "new special subject"
======Mail template page======

<code html>
Dear @@Your Name@@,

You are <b>great<b>, you just <i>purchased</i> our @@What do you want@@!

We will deliver it fast as possible, see the 
<a href="">conditions</a>.

Kind regards,
Future Machines company

<code text>
Dear @@Your Name@@,

You are great, you just purchased our @@What do you want@@!

We will deliver it fast as possible, see [1].

Kind regards,
Future Machines company


Template Mode

This action uses given pages as template, will replace defined placeholders with the user input and create wiki pages. This is a very powerful, but somewhat complex concept.

The action line looks as follows:

action template [template] [destination] [separator]
  • template is
    • either a single page,
    • or a whole namespace (with trailing colon). When a namespace is given, all contained sub namespaces and pages will be copied to the destination and replacement patterns will be applied in all pages.
    • when you specify an underscore (_) as template name, the plugin will attempt to use the configured namespace template of the destination namespace.
    • and ! skips this template, but requires at least one via the addpage field
  • destination tells bureaucracy where to create the new page[s]. This is usually a namespace (trailing colon). See section below for more detail.
  • separator new page names can be created by using multiple form field values. This character defines how these should be concatenated (see method 1 of section below)

Defining the destination(s)

When using the template mode you need to define where resulting pages should be created. There are multiple ways to do this.

Method 1 The simplest way is to specify an output namespace and mark up your naming fields using the @ character. Here's an example:

action   template userstpl users: :

fieldset "Create Your User Page"
select   "What's your Continent?" "Europe|N. America|S. America|Asia|Australia|Africa" @
textbox  "What's your Name?" @
textarea "Enter a short bio" !

This would create a new page using the continent and name fields. Eg. if I fill in “Europe” and “Andi” for those fields, the resulting page would be users:europe:andi.

Method 2 Sometimes you want some more control over the resulting pagename(s). This can be achieved by using placeholders in the destination parameter and omitting the @ marker in the field definitions.

Placeholders are the field names surrounded by @@ characters. Additionally any strftime parameters can be used. Let's have another example:

action   template userstpl "users:%Y:@@What's your Name?@@:start"

fieldset "Create Your User Page"
select   "What's your Continent?" "Europe|N. America|S. America|Asia|Australia"
textbox  "What's your Name?"
textarea "Enter a short bio" !
yesno    "Do have publication?"

fieldset "Add your publications" "Do have publication?"
textarea "Publications:"
addpage   users:publicationtemplate publications

fieldset "Finish"

The above would create a namespace based on the current year and my name and create a start page within it: users:2012:andi:start

Method 3 When working with Dependencies with Fieldsets you might want to add additional pages when a fieldset is shown, but skip the page when the fieldset is hidden. This can be achieved with the special addpage field.

Just put it in the fieldset of question:

addpage additionaltpl somepage

The second fieldset from the example above adds a publication page, via a checkbox. Here the template for additional page is located on absolute path: users:publicationtemplate. Only when the yesno field is checked, the additional page is created on users:2012:andy:start:publications

Creating Templates

The templates need to contain the same fields as your form, and some other placeholders are available too:

Placeholder action
@@Field label@@
##Field label##
Will be replaced by the actual values the user filled into
the form.
@@Field label|Nice alternative@@ For empty field the text Nice alternative is shown
@NSBASE@ (only template action) Namespace that contains new page.
eg. if the new page is foo:bar:baz:bang, @NSBASE@ will contain baz
%Y %F %a %Y-%m-%d %s… etc strftime parameters to refer to current time
%% Replaced by % char, needed to avoid accidental time
replacements in your template.
Accepts different datetime formats, which are outputted in the
requested strftime format. Providing no format returns date
with format of the dformat setting.
@ID@ @USER@ @MAIL@ … etc DokuWiki replacement patterns for templates are available too
@YEAR@, @MONTH@, @DAY@, @TIME@, @TIMESEC@ Print current: year, month, day, time as hh:mm
and time as hh:mm:ss
@TABLEHTML@, @TABLETEXT@ (only mail action) html or text table of all field values
<noinclude>…</noinclude> Tags with their content are removed
@LANG@ Languagecode as configured
@TRANS@ Languagecode obtained from page id of form

For the userstpl from the example above, you could have the following page:

====== @@What's your Name?@@ ======

I'm living in @@What's your Continent?@@. I'm a user since %Y-%m-%d.

@@Enter a short bio|FIXME please fill in your biography@@

The result then would look somewhat like this with all the user data filled in:

====== Andreas Gohr ======

I'm living in Europe. I'm a user since 2007-12-23.

It's me :-)

ACL Checking & runas Option

By default this plugin will check for ACLs in template mode using the permissions of the user filling the form. This means the user needs to have at least read permissions for the template and create permissions for the namespace where the new page should be saved.

However sometimes you may want to give anonymous users a way to create pages in a restricted namespace without giving them any direct access. This is where the runas option comes into play. With this option you can specify a username in the config manager. The user you specify here will always be used for checking the permissions mentioned above, regardless of the user filling the form. This way you can specify the needed access for this particular virtual user in the ACL manager.

Note: the runas user does not need to exist. In fact it is recommended to use a non existing user. Even when it exists, permission checks are done on user level only, groups of the user will be ignored.


Checkbox field

Example code for checkbox field:

yesno     "Are you happy?" "=Yes sir" "!No sir"

yesno     "Show fieldset?"
fieldset  "Shown on checking the box" "Show fieldset?"
textbox   "Share your praise"
  • The checkbox returns the default value Yes sir for checking the field, and No sir for unchecking. Leaving out default value(s) does result in no return value.
  • When a fieldset refers to a yesno field, no third argument is needed, instead it checks if the yesno is set. No default values are required for yesno where the fieldset depends on, unless you like a return value to your mail or template from that yesno field of course.

Number field

number "One"
number "Two" ++
number "Third" >3 <40
hiddenautoinc "Four (notice: conflicts with Two)"
number "Fifth" 000
  • One Number field accepts only numbers
  • Two Number field it remembers the last number and increment it with one, you can change it
  • Third Number field accept any number between 3 and 40
  • Fourth Number field is hidden, and increment every time a form is saved. (At the moment this field conflict with an autoincrementing number field. So don't combine in one form.)
  • Fifth Number field returns values which are completed with leading zeros. Input of 23 will be returned as 023.


Adding a new field type

To add a new type, you need to implement a Helper Plugin inheriting from helper_plugin_bureaucracy_field. There you probably want to overwrite the renderfield() method and probably some other methods as well. Your field will automatically be available as type <plugin>_<component>. Eg. lib/plugins/foo/helper/bang.php creates a new type foo_bang.

If you need more control over adding one or more fields, you can implement an Action Plugin hooking to PLUGIN_BUREAUCRACY_FIELD_UNKNOWN. This event only has a BEFORE event and provides the following data:

$data = array(
   'fields' => &array(), // the fields initialized so far - add yours here
   'args' => array() // the tokenized line, args[0] should be your plugin

In your handler you need to check that args[0] is the field type you want to register. If it is, you need to call preventDefault() and add your own field(s) to the fields array. The added field has to be a descendant of helper_plugin_bureaucracy_field!

Adding a new action

To add a new action create a new Helper Plugin inheriting from helper_plugin_bureaucracy_action. This works similar to adding a new field described above.

Theres is also an Event you can hook called PLUGIN_BUREAUCRACY_ACTION_UNKNOWN. Again, there's only a preventable BEFORE event.

FIXME describe passed data in detail. For now check the source.

Influence Template mode

Saving the final page in template mode triggers an event called PLUGIN_BUREAUCRACY_TEMPLATE_SAVE. In the before mode you can prevent saving the page or modify it's content. The after event is triggered after a page has been created.

Passed data:

$data = array(
  'patterns' => &array(), // list of PREG patterns to be replaced
  'values' => &array(), // values for the above patterns
  'id' => string, // ID of the page being written
  'template' => &string, // the loaded template text
  'form' => string, // the page the bureaucracy form was on
  'fields' => helper_plugin_bureaucracy_field[], // all the fields of the form


Important! These are hacks - there is no guarantee they'll always work, and they will not survive updates.

If it breaks you get to keep the pieces.

Customise the Date Format

NOTE: The configuration setting for the PHP strftime function in /conf/dokuwiki.php also need to be changed (can also be changed via Admin→Configuration)

$conf['dformat']     = '%Y/%m/%d %H:%M';

To change the default date format from yy-mm-dd to dd-mm-yy (e.g. for Australia)

Change the jQuery datepicker format /plugins/bureaucracy/script/datepicker.js from:-

 * Init datepicker for all date fields
    jQuery('.bureaucracy__plugin .datepicker').datepicker({
        dateFormat: "yy-mm-dd",
        changeMonth: true,
        changeYear: true

to this:-

 * Init datepicker for all date fields
    jQuery('.bureaucracy__plugin .datepicker').datepicker({
        dateFormat: "dd-mm-yy",
        changeMonth: true,
        changeYear: true

Change the Bureaucracy error message in /bureaucracy/lang/en/lang.php from:-

$lang['e_date']          = '"%s" needs to be a valid date in the format yyyy-mm-dd.';

to this:-

$lang['e_date']          = '"%s" needs to be a valid date in the format dd-mm-yyyy.';

Change the Bureaucracy date validation in /bureaucracy/helper/fielddate.php from:-

     * Validate field input
     * @throws Exception when empty or wrong date format
    protected function _validate() {
        $value = $this->getParam('value');
        if (!is_null($value) && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
            throw new Exception(sprintf($this->getLang('e_date'),hsc($this->getParam('display'))));

to this:-

     * Validate field input
     * @throws Exception when empty or wrong date format
    protected function _validate() {
        $value = $this->getParam('value');
        if (!is_null($value) && !preg_match('/^\d{2}-\d{2}-\d{4}$/', $value)) {
            throw new Exception(sprintf($this->getLang('e_date'),hsc($this->getParam('display'))));

Customise the Thankyou message

To allow inserting DokuWiki code into the Thankyou field.

Change the syntax in bureaucracy/syntax.php from:-

$thanks .= '<p>' . $thanks_string . '</p>';

to this:-

$thanks .= p_render('xhtml',p_get_instructions($data['thanks']),$info);

Which then allows the use of a link back to the same page when processing a Bureaucracy form:-

Thanks [[$examplepage|Continue]]

NOTE: If form creates a data plugin edit table the wiki code needs to be quoted (surrounded by “ ” quotes as in the example below)

Thanks "[[$page|Continue]]"


Please report bug or feature request on the Github bugtracker.

plugin/bureaucracy.txt · Last modified: 2016-08-04 10:17 by