The bureaucracy plugin allows you to create an 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.
On an open wiki, you might want to use the CAPTCHA plugin to avoid automated spam. When it is installed, Bureaucracy automatically integrates the captcha check in its form submission handling.
The SMTP plugin may help when your DokuWiki can't send mails.
When you use Bureaucracy's template action, 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.
The recent Struct plugin draws heavy inspiration from the data plugin and allows for central management of wanted structured data while keeping the functionality of the data plugin. The struct plugin supports integration with the Bureaucracy Plugin. This allows reusing the input mechanisms of the different types in Bureaucracy forms and creation of structured data when pages are created through Bureaucracy's template action.
An additional plugin to look at is pagemod, which adds a pagemod
action for the Bureaucracy plugin to add data to an existing page (in addition to the current templating and mailing functionality)
The Data plugin can not only be useful in templates as mentioned above, but it also provides a data_aliastextbox
field 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.
With Struct plugin, you can use any field from any defined schema as a field in a bureaucracy form. You can also add a whole schema to the form.
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:
<form> Action mail me@example.com 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" </form>
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.
fieldset
s and the submit
button, the label is optional.
select
type, need a third parameter.
"S p a c e s"
"
by using ""
e.g. "With ""quotes"" in the string"
The plugin takes care of validating the form, the field types, and set constraints.
mail
, template
, script
.pagemod
or struct_lookup
.
mail
:
template
:
_
to try and use the target namespace template (use an absolute path) (required)
script
:
conf/plugin/bureaucracy/
directory
@@
marks emailadress as Reply-To address for mail action
x23
) (optional)
"=true value" "!false value"
). If only used for a fieldset the default values are not required.
|
char "Peaches|Apples|Oranges"
)
|
char "Peaches|Apples|Oranges"
)
multiselect “Label” “Opt1|Opt2|Opt3” =Opt1,Opt3
,
” in e-mail message
,
” or you can provide optional separator: @@Label(separator)@@
|
char "Peaches|Apples|Oranges"
)
"=some value"
)
<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.
page_tgt
based on a template page page_tpl
new:destination
, then addpage will try to add new:destination:page_tgt
action
field a !
is given as template, that template is skipped and only template(s) added by addpage
are used.
.
and ..
can be used to reference namespaces relative to the new page. Defaults to .
_
for type of field, using dataplugin type syntax
>
followed by a number to require numeric data bigger than the given number
<
followed by a number to require numeric data smaller than the given number
=
to set a default value, you can also use placeholders here
!
char to make a field optional
^
char to give a field the focus (possible for only one field at a page)
@
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)
@@
to mark the value of a field as Reply-To address for mail mode
0000
for a number field, for completing inputted values with leading zeros upto the same length
++
for a number
field to make it auto-increment the counter on each form submit.
/
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 ()-+/
**Message
. Example:
textbox "Your pagename" /^[^\/:]+$/ "**Don't use / or : in your page name"
_
to define type alias.
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:
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:
man 7 regex
.
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:
<form> action mail me@example.com labels mylabels fieldset "field" textbox "name" number "age" >13 <99 submit "submit" </form>
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:
Note: double slashes // cannot be used in the translation field on the translation page — http://forum.dokuwiki.org/u/SFITCS 2016-12-15 22:27 |
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:
<form> action mail me@example.com 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" </form>
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, because it will check if the referred yesno field is set (It will not look for the default values eventually set by “=Value” “!Not Value”. If you need the value of the yesno in a template, you have to provide the default values explicitly.).
NOTE:
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"
and
fieldset "Motorbike spareparts" "Vehicule" "Motorbike" select "Sparepart2" "3 wheels|handle bar"
To show only the shown value of both select fields “Sparepart1” and “Sparepart2” in a template, use the construct
@@Sparepart1|@@@@Sparepart2|@@
The chosen one will be filled out and the not chosen one will be replaced by an empty string (“”).
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!]]
Bureaucracy does three things:
The last step is where the data is processed. The action to use is defined in the action
field, as described above. Currently three modes are supported: mail
, template
, and script
. Additional modes (e.g. to store the data in a database) can easily be added.
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 commas.
Example to automate email to an address which the user enters:
Fieldset "Some Information" Textbox "Employee Name" email Email_Address Action mail @@email_address@@
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.
subject
field you can replace the default subject
@@
you add Reply-To address(es) to the mail.
Example:
action mail @MAIL@ forename@surname.name 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="http://example.com/conditions">conditions</a>. Kind regards, Future Machines company </code> <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 [1] http://example.com/conditions </code>
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
_
) as template name, the plugin will attempt to use the configured namespace template of the destination namespace.
!
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)
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:
<form> 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" ! submit </form>
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:
<form> 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" submit </form>
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
The templates need to contain the same fields as your form, and some other placeholders are available too. Some of them can be used as default values for form fields:
Placeholder | action |
---|---|
@@Field label@@ ##Field label## | Will be replaced by the actual values the user filled into the form. |
@curNS(arg)@ @getNS(arg)@ @noNS(arg)@ @p_get_first_heading(arg)@ | Will be replaced with a result of the corresponding dokuwiki function. arg can be both a static value, eg. @curNS(some:test:value)@ or the placeholder of a field, eg. @p_get_first_heading(@@field@@)@ . |
@@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 timereplacements in your template. |
@DATE(<datetime>,%%Y-%%m-%%e)@ @DATE(<datetime>)@ | Accepts different datetime formats, which are outputted in the requested strftime format. Providing no format returns date with format of the config:dformat setting. |
@ID@ @USER@ @MAIL@ … etc | DokuWiki replacement patterns for templates are available too |
@FORMPAGE_ID@ @FORMPAGE_NS@ @FORMPAGE_CURNS@ … etc | Works like replacement patterns but refers to the page with the form |
@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 |
<noreplace>…</noreplace> | The content between <noreplace>…</noreplace> is preserved without performing any replacements but tags itself 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 :-)
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.
When using a user
or users
field, additional data of the selected users can be used in the template:
This action gives the data to a PHP script supplied by the administrator. The script then can do whatever it wants with the data.
The script must be placed in conf/plugin/bureaucracy/
directory. It must contain one class that is named helper_plugin_bureaucracy_handler_scriptname
and implements the interface dokuwiki\plugin\bureaucracy\interfaces\bureaucracy_handler_interface
That means the class has to have the handleData($fields, $thanks)
method with the fields and the thanks-message as parameters. It returns a thanks-message on success or false
on error.
This is a simple script handler that will just print the form's arguments in DokuWiki's debug log.
<form> action script example.php textbox "Type something" submit "Write to log" </form>
<?php use dokuwiki\plugin\bureaucracy\interfaces\bureaucracy_handler_interface; class helper_plugin_bureaucracy_handler_example implements bureaucracy_handler_interface { /** * Log the form fields to DokuWiki's debug log */ public function handleData($fields, $thanks) { dbglog($fields, __FILE__ . ': ' . __LINE__); dbglog($thanks, __FILE__ . ': ' . __LINE__); return $thanks; } }
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"
Yes sir
for checking the field, and No sir
for unchecking. Leaving out default value(s) does result in no return value.
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 "One" number "Two" ++ number "Third" >3 <40 hiddenautoinc "Four (notice: conflicts with Two)" number "Fifth" 000 number "Sixth" ++ 000
number
field. So don't combine in one form.)
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
!
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.
describe passed data in detail. For now check the source.
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 );
The event PLUGIN_BUREAUCRACY_EMAIL_SEND
gives developers of other plugins access to the submitted form data before it is actually sent in the actionmail.php
.
This makes it easier to provide custom fields in bureaucracy emails.
The event data includes the form fields info and all the values, so they can be processed by third-party plugins:
$evdata = [ 'fields' => $fields, 'values' => &$this->values ];
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.
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'] = '%d/%m/%Y %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(function(){ jQuery('.bureaucracy__plugin .datepicker').datepicker({ dateFormat: "yy-mm-dd", changeMonth: true, changeYear: true }); });
to this:-
/** * Init datepicker for all date fields */ jQuery(function(){ 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() { parent::_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() { parent::_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')))); } } }
As of release 2016-03-11 it is also necessary to change this:-
if(preg_match('/^(\d\d\d\d)-(\d\d?)-(\d\d?)$/', $value, $m)) {
to this:-
if(preg_match('/^(\d\d?)-(\d\d?)-(\d\d\d\d)$/', $value, $m)) {
— http://forum.dokuwiki.org/u/SFITCS 2016-11-26 01:16
Now packaged as a plugin - plugin:bureaucracy-au — http://forum.dokuwiki.org/u/SFITCS 2017-03-10 08:23
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.