Working with MediaWiki
2nd ed., HTML version

Chapter 17 Page Forms

You have created infobox templates to handle all your data, and thought of ideal page layouts for every scenario. But how do you get the users to use any of what you've created? That's where the Page Forms extension comes in: it lets you define forms that can be used to create and edit pages using the structure you have set up. It makes use of information, such as field types, from Cargo and/or Semantic MediaWiki whenever possible, in an attempt to make creating the forms as easy as possible.

Getting started

The rest of this chapter provides a breakdown of the syntax and workflows you can use with Page Forms. But if you're just getting started, the best approach is to use Page Forms' helper pages to quickly create pages. There are essentially five good options:
  1. Use the page Special:CreateClass to create everything at once – categories, templates and forms.
  2. Use the individual pages Special:CreateCategory, Special:CreateTemplate and Special:CreateForm to create the entire data structure. This is a more hands-on approach, which is less ideal for starting out, but it's quite useful if you already have templates and categories in place (and possibly properties as well), and only want to create what is still missing.
  3. Similar to the previous option, you can go to any specific not-yet-created category, template or form page, and click on the “create with form” tab, which displays a form that matches the form found in the relevant one of those four special pages.
  4. Copy from an existing installation or package. If you see a data structure setup that you like elsewhere, you can copy and paste all the necessary files to your wiki. (Though it's usually a good idea to get their permission first, even if legally it probably isn't necessary.) And there may be a package of such pages, created with a generic purpose like project management in mind, that you want to copy onto your wiki; a few companies offer such packages.
  5. Use the Page Schemas extension. See here for an introduction to this extension; it lets you create a set of “schemas” for your data structure, from which forms, templates etc. can be automatically generated.
First, let's look at Special:CreateClass. Figure 17 shows the interface that appears on that page.
Figure 17.1: Special:CreateClass page
Using this interface, you can define an entire “class” – a data structure to represent a single page type, which is composed of a template, a form, a category, and properties. Not every page type can be defined in this way – some pages will contain more than one standard template, for instance – but in many cases it's a good starting point. The set of fields at the bottom is used to create the template, the form, and the properties.
Why bother creating the category? Because, in Page Forms, the category is where the connection between pages and their forms is defined, so that an “edit with form” tab shows up at the top of each page. This is done via the #default_form function, which we'll get to later.
Another option is to use the special pages Special:CreateCategory, Special:CreateTemplate and Special:CreateForm, all defined by Page Forms. These have the advantage of granularity – you can create, or regenerate, any specific pages – and they also have the advantage of additional fields that Special:CreateClass doesn't offer.
For example, in Figure 17 you can see part of the helper form at Special:CreateForm – it lets you set all the allowed parameters for each form field, with the group of parameters based on the selected input type. We'll get to all of these specific parameters in the next section.
Figure 17.2: Special:CreateForm page

Form definitions

Page Forms provides an entire syntax for defining forms, that makes use of special tags contained within triple curly brackets. Pages that define forms should always go in the "Form:" namespace (or, for non-English-language wikis, its equivalent in another language). Such pages are not called forms, but rather "form-definition pages", to distinguish them from the actual corresponding forms that users see.
Before we define the syntax, here's an example of the full contents of a form-definition page, for a “Project” form:
This is the 'Project' form.
To add a site with this form, enter its name below;
if a page with that name already exists, you will be sent to a form to edit that page.
 
{{#forminput:form=Project|autocomplete on category=Projects}}
</noinclude><includeonly>
<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div>
 
{{{for template|Project}}}
{| class="formtable"
! Client
| {{{field|Client|input type=combobox|values from category=Clients}}}
|-
! Start date
| {{{field|Start date}}}
|-
! End date
| {{{field|Start date}}}
|-
! Status
| {{{field|Status}}}
|}
{{{end template}}}
{{{for template|Task|multiple|label=Tasks}}}
{| class="formtable"
! Task name
| {{{field|Task name}}}
|-
! Deadline
| {{{field|Deadline}}}
|-
! Status
| {{{field|Status}}}
|}
{{{end template}}}
</includeonly>
Already, without getting into any of the specifics of the syntax, you can notice a few things:
We'll get to a full explanation later of almost all the elements of this definition, but one thing that won't be covered later is the <div id="wikiPreview"> element. That is there so that, when the user hits the “Show preview” button, the Page Forms code can display both the form and the previewed page on the screen at the same time. It's an optional element.
You can see what this form page looks like when a user goes there in Figure 17. Only the top part of the page's contents, within the <noinclude> tag, is displayed.
Figure 17.3: A form definition page's display
When they reach the input on the form definition page, the user has to enter a page name. Let's say that they enter the text “Planting flower garden” and press “Create or edit”. Figure 17 shows what the resulting form page, defined by the “Project” form definition, would look like in action (after the user also presses the “Add another” button once).
Figure 17.4: A Page Forms-based form
It's very important to note that this form can be used to both create new pages and edit existing ones; the form will look the same in both cases, other than having its values pre-populated for existing pages.
Now, let's go through the form-definition syntax.

Form markup language

Forms are defined using a set of tags that specify templates and fields within those templates. Wikitext, and some HTML, can be freely embedded anywhere outside of the tags. Page Forms tags are always surrounded by three curly braces, have pipes to separate their “parameters”, and usually contain at least one extra parameter, to define the name. The text “{{{field|Start date}}}” from the previously-shown form definition is a PF tag, for instance. They differ from template calls because they have three curly brackets instead of two. And they differ from parameters within template definitions, which have three curly brackets, because those can only be used in the “Template:” namespace, whereas PF tags can only be used within the “Form:” namespace.
'info' tag
The 'info' tag holds special information about the form. This tag is optional, but should be placed at the top of the form if it is present. Allowed parameters of this tag are:
'for template' tag
The 'for template' tag specifies a template name, and declares that all of the following fields (until 'end template' is reached) will be those of this template. The text immediately following the 'for template' declaration is the name of the template. Allowed parameters of this tag are:
'end template' tag
The 'end template' tag ends the range of a template. There are no parameters for this tag.
'field' tag
The 'field' tag specifies a field to be placed in a form, corresponding to a template field. The text immediately following the field declaration is the name of the template field. There are a large variety of possible parameters to this tag, some of which can only be used for certain input types.
Parameters that can be applied to any field are:
For all input type-specific parameters, and a lot more information about configuring form fields, see the upcoming “Input types” section.
'section' tag
The 'section' tag specifies a textarea to be placed in a form, that corresponds to a page section. The name immediately following “section|” is the name of the section. For the most part, this tag takes in all the same parameters that the textarea input type can take in - see page 17. There are two additional parameters:
'standard input' tag
The 'standard input' tag is used for nine different inputs that usually appear at the bottom of every form. The text immediately after “standard input|” is the name of each input. The most notable of these inputs is 'free text', which is a textarea that holds all the non-template text in a page. The other seven are form elements such as the "Save" and "Preview" buttons; see here for the full list. The 'free text' input has more elaborate handling than the other standard inputs; see “The free text input” for its allowed parameters.
For the other standard input types, the allowed parameters are:
In addition, the 'watch' input type can take in the parameter 'checked', which checks the “Watch this page” checkbox by default.

Input types

The input types

text

The default input type; corresponds to the HTML "text" input.
Special parameters:

textarea

Corresponds to the HTML <textarea> tag.
Special parameters:

rating

This input type displays a star rating, as usually used for reviews.
Special parameters:
  • num stars= - the number of stars; default is 5.
  • allow half stars - allow the user to select half a star, for ratings like 3.5.

combobox

The "combobox" input type provides a combo box interface: an input that functions like a regular autocomplete field, but has an additional down-arrow icon, like that of a dropdown, to let the user see all the available values at once.
Special parameters:
  • size= - Specifies the width of the input, in characters.
  • existing values only - Disallows arbitrary values in the field.
  • placeholder= - Specifies help text that is displayed in the input until the user clicks on it.

tokens

This input type "tokenizes" the values in the field, i.e puts a block around each value to make it a single unit instead of just a string of characters. These "tokens" can then also be rearranged.
Special parameters:
  • size= - Specifies the width of the input, in characters.
  • max values= - Specifies the maximum number of allowed values.
  • existing values only - Disallows arbitrary values in the field.
  • placeholder= - Specifies help text that is displayed in the input until the user clicks on it.

radiobutton

The "radiobutton" input corresponds to the HTML "radio" input. It shows a set of values from which the user can only choose one.
By default, the first radiobutton value is "None", which lets the user choose a blank value. To prevent "None" from showing up, you must make the field "mandatory", as well as making one of the allowed values the field's "default=" value.

dropdown

The "dropdown" input corresponds to the HTML <select> tag. It shows a dropdown list of values, from which the user can only choose one.

checkboxes

The "checkboxes" input displays checkboxes to let the user choose any number of values.

listbox

The "listbox" input corresponds to the HTML <select> tag, with the "multiple" attribute added. It shows a vertical list of options, where the user can select any number of values.
Special parameters:
  • size= - Specifies the height of the listbox.

tree

The "tree" input type allows for a hierarchical, tree-style input, where all the values have either radiobuttons or checkboxes next to them, depending on whether the field can hold one item or many. Values can either come from a category tree within the wiki, or be set manually within the form definition.
How does this input know whether it can hold one or multiple values, and should thus display radiobuttons vs. checkboxes? It checks whether the field in the template is defined as holding a list of values (using #arraymap) or not. This check is not perfect, though. If the tree input is showing radiobuttons instead of checkboxes, you just need to add the parameter "|list" to the field tag in the form definition, to establish that this is a list.
Depending on the source of the values, you need to specify one of these two additional parameters:
  • top category= - sets the name of the category at the top of the "tree".
  • structure= - sets the entire tree structure; should use wikitext-style bullets to set the depth level.
If you use the "structure" parameter, it should look something like this:
{{{field|Location|input type=tree
|structure=*Universe
**Milky Way Galaxy
***Solar system
**Andromeda Galaxy
...etc.
}}}
You can also optionally set these parameters:
  • height= - sets the height, in pixels, of the box in which the tree appears.
  • width= - sets the width, in pixels, of the box in which the tree appears.
  • delimiter= - sets the delimiter when the field can hold a list of values. Default is ','.
  • hideroot - hides the name of the top category.
  • depth= - sets the number of levels of the three that are shown at the beginning. Default is 10.
If you're using the "tree" input type to display a category tree, note that this input will print out only the names of the categories selected, without the "Category:" namespace before it; so if you want that to show up in the page as well, the template will have to add it.
If the field specifies multiple categories, and the template uses #arraymap to do it, the call to #arraymap should look something like:
{{#arraymap:{{{Categories|}}}|,|x|[[Category:x]] |<nowiki> </nowiki>}}
...in other words, you need to specify the final "delimiter" parameter for #arraymap, and make it a space, blank or something similar, to avoid printing commas between the category tags.

checkbox

A single checkbox, used for boolean values.

date

This input contains three separate entries, for the year, month and day.

datetime

The "datetime" input is similar to the "date" input, but includes additional entries for hours, minutes, seconds and AM/PM.
Special parameters:
  • include timezone - specifies that a time zone entry should also be included.

year

"year" is a simple text input that is used to get a year-only value for a date field.

datepicker, datetimepicker

"datepicker" lets the user pick a date with the help of a JavaScript-based popup calendar. “datetimepicker” extends the datepicker input by also including a popup input for the time. Both of these inputs have many optional parameters, but most likely you will not need to use any of them.

googlemaps, leaflet, openlayers

The "googlemaps", "leaflet" and "openlayers" input types let you display a map to get a coordinate value, using the Google Maps, Leaflet or OpenLayers services, respectively.
You can also optionally set these parameters for these input types:
  • height= - sets the height, in pixels, of the map.
  • width= - sets the width, in pixels, of the map.
  • starting bounds= - takes in a pair of coordinates to set the bounds of the map displayed; this parameter only applies if the input does not have a value. (Example value for this parameter: "-20,-15;50,55".)
  • image= - available only for the “leaflet” input type; sets an image (must be an image that has been uploaded to the wiki) to be the background of the map, instead of a standard map of the world.

regexp

The "regexp" input type is not a true input type, but rather the ability to display another input (most often "text") with additional, regular-expression-based validation.
Special parameters:
  • base type - The base type to be used. May be any input type that generates an HTML form element of type input or select (e.g. text (with or without values), listbox, dropdown, etc.). Defaults to text.
  • base prefix - Prefix for the parameters of the base type (see example)
  • regexp - The regular expression the input has to match to be valid. This value must include the slashes! It defaults to /.*/, i.e. any value.

Allowed input types for data types

Each defined Semantic MediaWiki or Cargo data type has a default input type, and, when applicable, a default input size as well. Additionally, some data types have special handling if the field holds a delimited list of values, instead of just a single value.
Here are the defaults and the other allowed input types for each data type, for single values:
Data type
Default input type
Other allowed input types
Page
combobox
text, textarea, tree
String
text
combobox, textarea, tree
Text
textarea
text
URL
text
textarea
Integer, Float
text
textarea
Date, Start date, End date
date
datepicker, year (simply a text input)
Datetime, Start datetime, End datetime
datetime
datetimepicker
Enumeration
dropdown
radiobutton
Boolean
checkbox
dropdown, radiobutton
Coordinates
openlayers
googlemaps, leaflet
And here are the default and other allowed input types for delimited lists of a certain data type:
Data type
Default input type
Other allowed input types
Page
tokens
text, textarea
String
text
tokens, textarea
Enumeration
checkboxes
listbox
Hierarchy
N/A
tree

Setting values and mappings

For inputs that have a predetermined set of values, whether they are hardcoded (like the "dropdown" input) or suggested (like "combobox"), the values must be defined somewhere. If you are using SMW or Cargo, these values may already be defined outside the form. However, you can always override them within the form - or set them for a field that otherwise has no values defined for it. Here are some of the parameters that can be used in the "field" tag:
There are several more options for the autocompletion-based inputs; see the next subsection, "Autocompletion".
You can also set "mappings", if you want the set of values displayed to the user to be different from the set of values that actually show up in the page's wikitext. The following parameters enable such mappings:
  • mapping template=template name - Takes in the name of a "mapping template" (a template that takes in a single, unnamed parameter, i.e. {{{1|}}}, and displays a "mapped" string as a result), and uses that template to map every potential value, so that the values' "aliases" appear on the screen, and not the values themselves.
  • mapping property=property name - Used for fields that select pages with 'combobox', 'tokens', 'listbox', and 'dropdown' input types. For each possible value, displays a SMW property from that page rather than the title of the page, but saves the title of the selected page(s) as the field value. Used in conjunction with the “values...” parameters to get the list of possible values.
  • mapping cargo table=table name/mapping cargo field=field name - Similar to mapping property=, except it is used for Cargo fields.

Autocompletion

Two of the input types – tokens and combobox – use autocompletion: as the user starts typing, the input shows a dropdown list of possible completions.
If a field represents a Semantic MediaWiki property, or Cargo field, of type "Page", autocompletion will be enabled by default — the field will autocomplete on the names of all pages that are already pointed to by that property or field. For any other type, there is no default autocompletion, but you can achieve this same effect simply by setting the input type to either "combobox" or "tokens".
You can manually set a field to autocomplete on one of various sets of values, by using one of the "values ..." parameters – see the previous subsection, "Setting values and mappings".
You can also autocomplete based on values outside the wiki, contained in web pages, databases, files, etc.; see "Autocompleting on outside values", below for the various ways to do this. If a field is specified to hold multiple values, autocompletion will, by default, support multiple values: after a value is entered, and a delimiter placed, a new autocompletion will start for the next value. You can manually specify that a field should have multiple-value autocompletion, by adding the "list" parameter to the field's definition. You can also specify the delimiter for this list of values, using the "delimiter=..." parameter (the default is a comma).
By default, the maximum number of autocompletion possibilities that a field will offer is 1,000; this is for performance reasons. To change this number, change the value of $wgPageFormsMaxAutocompleteValues in LocalSettings.php.

Matching on every character

By default, Page Forms autocompletion matches on the beginning of every word in the set of possible values. However, you can change autocompletion to instead match on every character, by adding the following line to LocalSettings.php:
$wgPageFormsAutocompleteOnAllChars = true;
This feature is especially important for wikis that have values with non-ASCII characters, such as wikis in languages with non-Roman alphabets; since the default, word-based autocompletion doesn't yet work with non-ASCII characters.

Autocompleting on outside values

Autocompleting on values from outside the wiki is currently a rather intensive process, because you have to massage the outside data to get it into exactly the right format. Ideally this will change in the future, so that arbitrary lists of values can be used within forms. Until then, to have a field autocomplete on outside values, you have to take the following steps:
  1. Create a page/web service that takes in a substring via the query string, and displays a set of autocompletion values; the values should be in JSON format, and look like the JSON returned by the MediaWiki API (see here). This also makes it easy to autocomplete on the values from another wiki.
  2. Decide on a short string to represent this URL.
  3. Add a line to LocalSettings.php that looks like this:
$wgPageFormsAutocompletionURLs['URL-identifier-string'] = 'URL';
The URL in this line should look like a call to that web service, but with the substring replaced by the string "<substr>".
  1. Add the parameter "values from url=URL-identifier-string" to the relevant field in the form definition.

Uploading files

If the field is configured to contain a list of values, the new file name will be appended to whatever was there before; otherwise, the file name will overwrite whatever the field contained before.
Parameters that can only be applied to fields that hold a list of uploaded files are:

“show on select”

For inputs of type 'checkbox', 'checkboxes', 'radiobutton', 'dropdown' and 'listbox', the parameter show on select= can be used to specify that one or more elements on the page should only be displayed to the user if a certain value (or values) is selected within that input. The syntax for this parameter is:
For inputs of type 'checkbox', simply “show on select=element ID” should be used.

Multiple values for the same field

Page Forms supports having multiple values within a given field, and some form input types – like “checkboxes” and “listbox” – are specifically geared for fields that contain multiple values. Text and textarea fields can also support autocompletion for multiple values. If a form field is meant to hold multiple values, the corresponding template field should most likely contain a call to either #arraymap or #arraymaptemplate – see here. Regardless of what is contained in the template, though, the fact that a field is meant to hold multiple values can be hard-coded in the form definition by adding the parameter "list" to the {{{field}}} tag. The parameter "delimiter=" can also be helpful, if the delimiter between values is meant to be something other than the default (a comma).

Multiple-instance templates

If you add the 'multiple' parameter to a template, it will allow for multiple (or no) instances of this template in the form, and therefore in the generated page. The sample form on here is a good example of a form with multiple-instance templates. There's a button labeled "Add another"; clicking on it will create a new instance of that template and its fields. Instances can be removed, by clicking on the “Remove” button, and they can also be rearranged, by clicking on the “ribbed arrow” icon on the right-hand side and dragging the instance up or down within the set.
You can rename the "Add another" button to any other text, using the "add button text=" parameter. For instance, to change the button to read “Add another occupation” for a template called “Occupation”, you could have:
{{{for template|Occupation|multiple|add button text=Add another occupation}}}

Embedded templates

You can choose to have all instances of a multiple-instance template be stored as the value of a parameter for some other template, so that the calls to that template will not look like:
{{Skill|Name=Cooking|Level=5}}
{{Skill|Name=Guitar|Level=2}}
{{Skill|Name=Karate|Level=4}}
...but instead like:
{{Person ... |Skills={{Skill|Name=Cooking|Level=5}} {{Skill|Name=Guitar|Level=2}}{{Skill|Name=Karate|Level=4}} ... }}
In order to accomplish this example, you would just need to:
  • Add a tag like "{{{field|Skills|holds template}}}" within the "Person" template part of the form definition
  • Add "{{{Skills|}}}" somewhere inside the page Template:Person, so that it gets displayed in pages
  • Add "|embed in field=Person[Skills]" to the "{{{for template|Skill|multiple" part of the form definition
There are several advantages to this approach:
  • You have much greater control over where the multiple-instance template goes, in both the form and the resulting pages - so you can have it placed between any two fields in the "main" template.
  • You can easily place special text before and after the multiple-instance template, like a table header and footer, without the need for special header and/or footer templates.
  • No spaces get placed between calls to the template, which may potentially help with formatting.
Note that you cannot embed multiple-instance templates inside other (regular or embedded) multiple-instance templates.

Defining the bottom of the form

The user inputs at the bottom of the form can be customized using the “standard input” tag. The layout, inclusion and text of each input can be modified. Each user input is defined as a “standard input” tag with its own value; the allowed values are:
  • save (for the “Save page” button)
  • preview (for the “Show preview” button)
  • save and continue (for the “Save and continue” button – this lets users save the page without leaving the form)
  • changes (for the “Show changes” button)
  • summary (for the “Summary” text field)
  • minor edit (for the “This is a minor edit” checkbox)
  • watch (for the “Watch this page” checkbox)
  • cancel (for the “Cancel” link)
  • run query (for the “Run query” button in query forms)
So, for example, the button for “Save page” could be specified with “{{{standard input|save|label=Save this page}}}”, which would place the button where it was defined, with the text on the button reading “Save this page”. If no standard input tags are included in the form definition, the basic seven inputs (all except for “save and continue” and “run”) will appear at the bottom of the form, just as they do for regular "Edit" pages. However, if even one such tag is included, then only those inputs which have been included will be displayed, in the order, and with the wikitext, that they appear in in the form definition.

Enabling multiple field values

There are two parser functions defined by Page Forms, #arraymap and #arraymaptemplate, that enable holding multiple values within the same field, by applying the same semantic property to each element of a comma- (or otherwise-) delimited list (a comma-delimited list is a piece of text in which distinct values are separated by commas). There is nothing form-specific, or even semantic-specific, about these functions; but they seem to have not been necessary until Page Forms was created, which is why they're stored there. Of these, #arraymap is the more important: it's used much more frequently, and it's the one applied automatically within templates by both Special:CreateClass and Special:CreateTemplate when a field is specified to hold a list of values. #arraymaptemplate is useful when the mapping required is too complex for #arraymap.

#arraymap

The generic call for this function is:
{{#arraymap:value |delimiter |var |formula |new delimiter}}
The function splits the 'value' by the 'delimiter', and then, for each one, applies the same mapping that 'formula' does to 'var', and finally joins all the values again using the 'new delimiter'. For example, if you have a form that populates the field 'author', and you want that field to be able to hold multiple values, separated by commas; and you want each value to also be bolded, you could add the following to the template code:
{{#arraymap:{{{author|}}}|,|x|'''x'''}}
Essentially this function “maps” the formatting onto each comma-delimited value in the field. (The 'delimiter' parameter defaults to "," and 'new delimiter' defaults to ", " (note the extra space) if they are not set.) The user can thus enter all the values on the same line, with or without spaces around the commas. (Note, by the way, that the "x" is used here as an internal variable: if the property name itself contains the letter "x", that will lead to problems, and you should replace the letter "x" with some character or string that does not appear in the property name, like "@@@@".)
The 'new delimiter' parameter sets the text that's placed between values in the resulting output. It is optional, and is usually not set, because its default value – a comma plus a space – is generally what's needed. However, this parameter is useful in certain cases. It's especially helpful if none of the resulting values are actually displayed, because in that case you wouldn't want the output to be a string of commas. A common example of that is if the original value holds a list of category names, and each name gets turned into a category tag, but is not actually displayed. To avoid displaying commas in that case, you should set the 'new delimiter' value equal to a space, using something like "&#32;", the HTML encoding for a space. (Using just "| " at the end won't work, because the MediaWiki parser will ignore it.) Here is how such a thing would be called:
{{#arraymap:{{{categories|}}}|,|x|[[Category:x]]|&#32;}}
If you use the 'CreateTemplate' or 'CreateClass' pages to create a template, and you specify that a field that can take more than one value, then an #arraymap call will be automatically added to the generated template.

#arraymaptemplate

There are some kinds of mapping that are complex enough that they cannot be placed in the #arraymap function. For this purpose, you can instead use the similar #arraymaptemplate function. To use this function, create a template that takes in a single field and applies the mapping you would like to that field. Then apply #arraymaptemplate onto the main template field just as you would with #arraymap, using the following format:
{{#arraymaptemplate:value |template |delimiter |new delimiter}}
...where 'template' is the name of the mapping template in question.

\n delimiter

For both #arraymap and #arraymaptemplate, the string “\n” in the value of either delimiter or new delimiter will get converted into a newline. If you want an actual line break to appear between values, you should have two newlines (i.e, "\n\n") as the delimiter, since MediaWiki requires two newlines in order to display a line break.

The “edit with form” tab

If a user is not allowed to edit a page that is form-editable, the tab will show up for them as "view form" instead; clicking on the tab will show the disabled form.

Getting "edit with form" to appear

There are three ways to get the 'edit with form' tab to appear for specific pages:

Based on category

The first, and recommended, way, is to use categories. To enable a page to have a tab in this way, you must do the following two steps:
  1. First define that page as belonging to a specific category. The best way to match pages with a category is to place a 'Category' tag inside the main template that defines this page type; that way, every page that uses this template will become part of this category.
  2. Once you have done that, place a function call like {{#default_form:form_name}} in the page for that category. (You can do this automatically if you create the category using the 'CreateCategory' page.)

Based on namespace

The second possible way is to match the pages' namespace to a form. You can do that by placing a #default_form function in the page defining that namespace. If, for instance, your wiki is called 'MyWiki', and the namespace you want to associate with a form is 'User', the page in which you need to add the #default_form cal will probably be called 'MyWiki:User' (you will probably need to create this page). If the namespace you want a default form for is the main one (i.e., the one with no name), you will need to create and add #default_form to the page called 'MyWiki:Main', or whatever the main namespace is called in the language of this wiki.
Once you've added this function, every page within that namespace will have that form associated with it, unless it already belongs to a category that has an associated form (categories take precedence over namespaces).

Within the page

You can also add a call to #default_form to any regular page, to set the form just for that page. This is especially useful when the category and namespace options aren't possible, such as when pages belong to multiple categories that have different default forms.

Configuring the editing tabs

For pages that have an “edit with form” tab, you may want the regular “edit” tab to be renamed or even removed altogether. There are flags you can set in "LocalSettings.php" to change the appearance of the editing tabs:
  • $wgPageFormsRenameEditTabs - if set to true, renames the “edit with form” tab to “edit”, and the “edit” tab to “edit source” (in whatever language the wiki is being viewed in)
  • $wgPageFormsRenameMainEditTab - if set to true, renames only the “edit” tab to “edit source” (in whatever language the wiki is being viewed in)
  • $wgGroupPermissions[...]['viewedittab'] - can be set, for different types of viewers, to toggle whether each type will see the regular edit tab. One common modification is to set it to false normally (i.e. for viewer type '*'), and to true for 'sysop' viewers:
    • $wgGroupPermissions['*']['viewedittab'] = false;
    • $wgGroupPermissions['sysop']['viewedittab'] = true;
If these settings are added to LocalSettings.php, they should be placed in the file after the inclusion of Page Forms.

Linking to forms

How do you get users to forms to create the pages in the first place? The standard way is via the #forminput parser function call, which displays a single input for users to enter the name of a page; if they enter such a name and click the button, they are sent to a form to create that page – unless a page with that name already exists, in which case they are sent to a form for editing the existing page. This is what is known as the "two-step process". The reason for the initial step, of having the user first enter the page name, is to ensure that users don't accidentally overwrite existing pages. This process is so standard that it is built into the default forms produced by Page Forms' Special:CreateForm and Special:CreateClass helper pages: any form-definition page created by Page Forms includes, at the top, a call to #forminput, so that users who go to that form page can automatically start to use the form.
However, it's also possible to skip the first step, of entering the page name – that's what you should do if the form contains a formula for setting the page name based on the user input. That's the "one-step process", and it uses the parser function #formlink instead of #forminput.

The two-step process

The two-step process, i.e. the standard way to get users to forms, is done using the #forminput parser function.

Using #forminput

Here is the syntax of the #forminput parser function:
{{#forminput:form= |size= |default value= |button text= |query string= |query string parameters |autocomplete on category= |autocomplete on namespace= |remote autocompletion |placeholder= |popup}}
All arguments are optional. An explanation of the parameters:

Adding pages of a specific namespace

You can have a page-input form create pages within a specific namespace (like 'User:') by default, without forcing users to type in that namespace every time. To do that, add “namespace=namespace-name” to the query string= parameter.

Adding subpages

In MediaWiki, you can create subpages by including a slash in the page name (see here). To have the page that's added automatically be a subpage, you can add a value for “super_page=” in the query string. To make it a subpage of the current page, you can set this value to “super_page={{FULLPAGENAME}}”. This will prepend a “current-page-name/” onto the beginning of the page name that the user types in.

The one-step process

You can have the name of the page created by the form be set automatically, by adding a "page name" parameter within the form definition's "info" tag. There are two types of "variables" one can include in the value for this parameter:
Note that the "page name=" value cannot start with "<unique number>", due to a bug in Page Forms; there has to be some text before that. And it cannot contain the character "#", because MediaWiki does not allow pound signs in page titles.
As an example, imagine a form for storing notable quotes. Its {{{info}}} tag could have a parameter of "page name=<Quote[Author name]> quote <unique number;start=1>". This would include the author's name in the name of every quote page, as well as a number to guarantee the uniqueness of every opinion-item page added. A user could then go to the URL "http://mywiki.com/wiki/Special:FormEdit/Quote" and fill out the form; if they set the author to be "Ernest Hemingway", and no other quotes in the wiki had him as an author, then hitting the "Save page" button would result in a new page called "Ernest Hemingway quote 1" .
The "start" value can have leading zeroes; a value of "001", for instance, would lead to pages that had the value "001", then "002", etc.
The "page name=" value gets parsed by the MediaWiki parser, so you can also add parser functions, pre-defined variables, etc. into the value.
Note that users must be sent to the page "Special:FormEdit/form-name" for this automatic page-setting to work; if they somehow end up at a #forminput call and are prompted for a page name, that name will override whatever the automatic page name would be.

Using #formlink

If you want, you can generate a link to a “one-step process” form using the "#formlink" parser function, instead of creating the URL directly. This function is called as:
{{#formlink:form= |link text= |link type= |query string= |query string parameters |target= |tooltip= |popup |reload |new window |returnto=}}
The "form=", query string, "popup", “reload” and “returnto=” arguments work much the same way that their equivalents in #forminput work, and "link text=" works like #forminput's "button text=". The "link type=" argument sets the display of the link: if it's set to "button", the link will show up as a button; if it's set to "post button", it will be a button that sends the query-string value(s) using "POST" instead of via the URL – this is helpful when a lot of data has to be preloaded, and it is more robust with special characters like line breaks in the query string; if it's set to blank or anything else, it will show up as a regular link. The "target=" parameter shouldn't usually be used, but it sets the target page to be edited, if you want to link to the editing of a specific page. The "tooltip=" parameter displays a "tooltip", displayed if a user hovers the link. The “new window” parameter opens the form in a new window or tab, depending on the browser.
An example call to #formlink would be:
{{#formlink:form=Quote
|link text=Add a quote for this author
|link type=button
|query string=Quote[Author]={{PAGENAME}}
}}
This will link from the page, via a button, to a form for adding a quote, with the "Author" field filled in with the current page name. If there are multiple values, they should be separated by "&".

Pointing red links to a form

In MediaWiki, links to nonexistent pages are called “red links”, because they are usually colored red. By default, these links go to a page for adding the article to the wiki using the standard edit interface. However, if that nonexistent page is being pointed to by a semantic property, the red link can instead take the user to the correct PF form to add the page.
To have a specific link (either on its own, or within a template) point to a form if the page it is pointing to does not exist, use the #formredlink parser function. A typical call to #formredlink will go inside a template, and will look like:
{{#formredlink:
target={{{PageNameParameter|}}}
|form=FormName}}
The overall syntax of #formredlink is:
{{#formredlink:form=|link text=|existing page link text=|link type=|query string=|target=|tooltip=|popup|new window|create page}}
These parameters are very similar to those of #formlink (see above). It has two additional parameters:
  • existing page link text= - sets the text of the link when the target page being pointed to exists already (the "link text=" parameter takes effect only when the target does not exist).
  • create page - causes red-linked pages to get automatically created by the system.
There may be times when you are not sure which form a linked-to page will use; it could be one of a number of choices. You can set it so that the user gets other possibilities when they click on the red link, by adding one or more "alt_form" parameters to the #formredlink call, each with its own number.

Preloading data

You may want a form to already contain some data when the user goes to it. (Note that this only applies to adding new data, or to query forms; for editing an existing page, there is no way to set the contents of the form to anything other than the current contents of that page.) There are various ways to do this:
  • Specify a "default" value for whatever fields you want to have a value for in the form.
  • Specify a "preload" page for the "free text" input, which will preload the free text field with the contents of that page.
  • Add 'preload=preload-page-name' to the query string value in the #forminput call; this will preload the entire form with the contents of that page.
  • Similarly, you can add a "preload=..." value to the query string for a 'FormStart' or 'FormEdit' URL.
  • Add "template-name[field-name]=field-value" to the query string value in the 'forminput' call, to set the value for a specific field. To preload values for more than one field, use "&": "template1[field1]=val1&template1[field2]=val2".
  • Similarly, you can add a value for a specific field to the URL query string for 'FormStart' or 'FormEdit'.
  • Finally, you can create your own custom handling, using the “PageForms::EditFormPreloadText” hook. If another extension calls this hook, it can preload data however it wants. The function registered with this hook should have a header like:
function-name(&$page_contents, $page_title, $form_title)

Creating query forms

Forms can also be used for querying, as opposed to adding or editing data. In other words, you can create a form that will not modify any pages, but will instead be used for searching existing data – in which a user enters values in different fields and then sees some set of pages that match those fields.
To have query forms, you need to use the Special:RunQuery page, which displays a form in a manner similar to Special:FormEdit, but with no associated target page. Instead, when the user submits the form by hitting the "Run query" button, the user stays on the Special:RunQuery page, but now the page shows what the template looks like when displayed with the values they entered. The template that the form uses should most likely contain one or more Semantic MediaWiki inline queries, to query data using values the user entered.

The "Run query" button

By default, a button called "Run query" shows up at the bottom of forms if they are accessed via Special:RunQuery. You can change the location and text of this button, using the tag "{{{standard input|run query}}}" within the form definition. (This tag can also accept other parameters, like “label=” and “class=”.)

Creating links to query forms

Once a query form has been created, you can link to it using syntax that looks like this:
[[Special:RunQuery/query form name]]
However, the preferred solution, because it's easier and more powerful, is to use the #queryformlink parser function. A basic call to that function would look like:
{{#queryformlink:form=query form name}}
Here's the complete syntax of #queryformlink:
{{#queryformlink:form= |link text= |link type= |query string= |query string parameters |tooltip= |popup}}

Embedding query forms

You can also embed a query form within another page. To do that, add the following in a page where you want the query form to appear:
{{Special:RunQuery/query form name}}

Modifying pages automatically

You can create links that, when clicked on, create or edit pages automatically in the background, with a preloaded set of values, using the #autoedit parser function. This function is called, and is displayed, in a very similar manner to #formlink – the difference is that the link only performs an action in the background, instead of bringing the user to a form. The syntax for #autoedit is
{{#autoedit:form= |target= |link text= |link type= |query string= |query string parameters |reload }}
All these parameters but 'reload' work in the same way as they do in #formlink; 'reload', if added to the call, reloads the current page after the link is clicked.
As an example, let's say you want to create a simple voting scheme, letting users vote between "Vanilla", "Chocolate" and "Strawberry". You have a page for each, and each one contains a template called "Flavor", with a field called "Num votes" – that field, in turn, sets a semantic property called "Has number of votes". And there is a form, also called "Flavor", to edit such pages. To create a link that, when clicked, increments the number of votes in the "Vanilla" page by one, you could place the following call on the page:
{{#autoedit:form=Flavor
|target=Vanilla
|link text=Vote for Vanilla
|query string=Flavor[Num votes]={{#expr:{{#show:Vanilla|?Has number of votes}} + 1}} }}
What happens when a user clicks on such a link? They'll stay on that page, but the link will turn into text that reads “Successfully modified target page using form form name.” If the user refreshes the page, or goes to that page later, they'll see the original link again – and they can click on it; there's no limit to the number of times a user can click on an #autoedit link. (Though you can embed an #autoedit call within an #if call, if you have ParserFunctions installed, to only display it for certain users, or in certain situations.)
This functionality is also available via the MediaWiki API (here), as the "pfautoedit" action – this enables outside scripts, and bots, to modify template calls within wiki pages. You can find the full documentation on this by searching for "pfautoedit" on your wiki's api.php file; essentially the parameters are the same as for #autoedit.