Help:Semantic Forms
From Edge of Darkness Wiki
Description
Semantic Forms is an extension to MediaWiki that allows users to add, edit and query data using forms. It is heavily tied in with the Semantic MediaWiki extension, and is meant to be used for structured data that has semantic markup. Having Semantic MediaWiki installed is a precondition for the Semantic Forms extension; the code will not work without it (and you must have version 1.4 or higher of SMW).
Very simply, Semantic Forms allows you to have forms for adding, editing and querying data on your wiki, without any programming. Forms can be created and edited not just by administrators, but by users themselves.
The main components of Semantic Forms functionality are form definition pages, which exist in a new namespace, 'Form:'. These are pages consisting of markup code which gets parsed when a user goes to add or edit data. Since forms are defined strictly through these definition pages, users can themselves create and edit forms, without the need for any actual programming.
The Semantic Forms extension enforces the use of templates in creating semantic data. It does not support direct semantic markup in data pages; instead, all the semantic markup is meant to be stored indirectly through templates. A form allows a user to populate a pre-defined set of templates for a page (behind the scenes, that data is turned into semantic properties once the page is saved).
Forms can also be used to edit the data in an existing page, and you can enable an 'edit with form' tab to show up on any page; see The 'edit with form' tab.
Semantic Forms also supports autocompletion of fields, so users can easily see what the previously-entered values were for a given field. This greatly helps to avoid issues of naming ambiguity, spelling, etc.
Data in a page that doesn't fit into the form, like a free-form text description of the page's subject, isn't ignored when the page is edited with a form; rather, it is placed into a separate input box called "free text".
Semantic Forms also provides hooks to let outside code easily define new input types; this is useful for, among other things, new extensions to define input types that use code that they provide.
Semantic Forms also provides other features: a form to create semantic properties, a form to create templates, a form to create user forms, pages that list all the templates and all the user forms on the site, and others. This documentation covers all the features, but see especially the Special pages section.
Portions of the development of this software were funded by ontoprise GmbH and others.
Structure
Code structure
For the complete listing of files in Semantic Forms and a short description of each one, see Extension:Semantic Forms/Code structure.
To view the code online, including version history for each file, you can go here.
Special pages
The extension defines various "special" MediaWiki pages:
- Special:CreateForm - lets a user create a new form for adding/editing data. (See example of page)
- Special:CreateTemplate - lets a user create a new template. (See example of page)
- Special:CreateProperty - lets a user create a new property. (See example of page)
- Special:CreateCategory - lets a user create a new category. (See example of page)
- Special:CreateClass - a page that creates all the elements for a single "class" at the same time - properties, template, form and category (See example of page). Access to this page is dictated by the 'createclass' MediaWiki permission; by default, it is available to all logged-in users.
- Special:FormEdit - lets a user either create or edit a page using a user-defined form. (See example of page.) (This page was, until version 1.9, two separate pages: "Special:AddData" and "Special:EditData".)
- Special:FormStart - used to route a user to either 'FormEdit' or the relevant page's "edit with form" tab. This page should not be accessed directly by users. (This page was known until version 1.9 as "Special:AddPage".)
- Special:Forms - lists all form pages on the site. (See example of page)
- Special:RunQuery - lets a user run a query, using a form (See example of page)
- Special:Templates - lists all templates on the site. (See example of page)
- Special:UploadWindow - lets a user upload a file; very similar to the standard Special:Upload page, but without the skin. This page is called from within a form, and should not be accessed directly by users.
Getting started
So, you've set up all the software on your site. Now what? Now it's time to create the structures to hold, display and enable adding and editing of your data; thankfully all of this can be done simply by creating various wiki pages. You should take the following steps:
- Figure out your data structure. What types of pages will the site have? What data will be contained on each one? You can change all of this around later, but it's good to have a starting plan.
- Create properties. The basic building blocks of any semantic site are the connections between data, which in Semantic MediaWiki are known as properties. A property is used to specify a single piece of information about the topic of this page; the value of a property can either be a standalone value, or the name of a page on the wiki. Every property should be defined on your wiki, with a page in the "Property:" namespace. The easiest way to do that is using the 'CreateProperty' special page (see above).
- Create templates. A template sets the display of the data on a page, holds the markup to turn the data into actual semantic information, and (often) defines the page as being of a certain category, and thus of a certain page type. There will generally be one template per page type, although sometimes a single page type will contain more than one template. A template can also be used for aggregation, by displaying a list of all other pages that have a certain relationship to this page (see the inline queries documentation for much more information on this). The easiest way to create templates is using the 'CreateTemplate' special page (see above).
- Create forms. Now you can create forms to allow users to easily add and edit pages of various types. There should be one form per page type; a form should populate the template or templates that this page type contains. As before, there's a special page to create new forms: 'CreateForm' (see above). See below for documentation on the special markup language used to define forms. One common request is for these three special pages ('CreateProperty', 'CreateTemplate' and 'CreateForm') to be able to edit existing property/template/form pages, and not just create new ones. However, this is programatically much harder to implement than creating new pages, because it requires parsing. For the foreseeable future, modifying existing properties, templates and forms will have to be done by hand. In other words, go to the properties, templates or forms pages (which are listed in special pages) and select what you want to modify. Clicking on the edit tab will allow you to do what you want by editing the source code.
- Create categories. One template in each form should define each article that the form creates as being part of a certain category. You should create a page for each such category, and specify a default form for it so that every article is automatically editable with the same form that created it. The easiest way to do that is using the 'CreateCategory' special page (see above).
- Enable links to forms. Besides creating categories that have a default form, there are other steps you should take to enable users to access the forms that you have created. These include adding links to add data in the sidebar and elsewhere, and setting default forms and alternate forms on properties, to have red-links to nonexistent pages point to a form for creating them. These actions are all explained further below.
- Add data. You should also add data to the site, using your new forms, to make sure that forms, templates and categories are working the way you want them to.
- Add links on sidebar and elsewhere. The sidebar (which, for English-language wikis, can be edited at the page "MediaWiki:Sidebar") should hold links to add each of the data types, and to the categories for each of these data types as well. You can also include such links on the main page and elsewhere.
- Customize. Once the structure is in place, you can customize all you want - changing the look-and-feel of the entire wiki, of the various templates, and of the forms, adding and changing fields and adding and changing inline queries for queries.
...conversely, instead of creating properties, templates, forms and categories separately, you can create them all at once, using the 'CreateClass' special page (see above). This page does not allow as much flexibility as creating all these pages independently, but it can be run much faster.
Example
To see this process in action, see the example of how these steps would be followed for an actual wiki.
Quick reference guide
A two-page quick reference guide, or "cheat sheet", for Semantic MediaWiki, Semantic Forms and a variety of other extensions, exists, suitable for printing. It can be found here, in PNG (image), PDF and SVG formats.
Defining forms
Form markup language
Forms are defined using a set of tags that specify templates and fields within those templates. Wiki-text, and some HTML, can be freely embedded anywhere outside of the tags. The allowed tags are:
-
info
- 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:-
partial form
- Indicates that this form is a partial form; see "Partial forms", below. -
create title=
title - Sets the title for the 'FormEdit' page, if the form is being used to create a new page -
edit title=
title - Sets the title for the 'FormEdit' page, if the form is being used to edit an existing page -
page name=
formula - Sets a formula for automatic setting of the name of the page being added; see "The one-step process", below. -
onlyinclude free text
- Indicates that the free text in the page generated by the form should be placed within an "<onlyinclude>" tag, so that pages created by the form can be transcluded in other pages without affecting those other pages' semantic properties
-
-
for template
- Specifies a template name, and declares that all of the following fields (until end template is reached) will be those of this template. The name immediately following the for template declaration is the name of the template. Allowed parameters of this tag are:-
label=
label text - Specifies a label to be placed in a square around the entire set of this template's fields in the form. -
multiple
- Specifies that the user can change the number of instances of this template in the form, allowing multiple (or zero) occurrences; see "Multiple-instance templates", below. -
chooser=
dropdown name - Similar to multiple, but allows for a single dropdown input in the form to add instances of each template labelled as chooser, instead of each such template requiring its own 'Add' button. -
chooser caption=
caption - Sets the caption in the form's dropdown for adding instances of this template; must be set in conjunction with chooser option. -
strict
- Specifies that only fields in the form that correspond to fields used by the template should get turned into form elements.
-
-
end template
- Ends the range of a template. There are no parameters for this tag.
-
field
- Specifies a field to be placed in a form, corresponding to a template field. The name immediately following the field declaration is the name of the template field. Allowed parameters of this tag are:-
input type=
input type - Specifies the type of input this field will have in the form: allowed values are text, textarea, date, datetime, datetime with timezone, radiobutton, checkbox, checkboxes, dropdown and listbox. If a field corresponds to a semantic property, the form will usually have the correct input type by default; otherwise the default is text. If the corresponding semantic property cannot be automatically determined (e.g. if it's in a subtemplate), you can use the parameter "property" to manually specify it (see below). -
size=
size - Used for text entries and listbox. Specifies the width of a text entry, or the height of a listbox. -
maxlength=
maximum length - Used for text and textarea entries. Specifies the maximum allowed length of the input. -
rows=
num rows - Used for textarea entries. Specifies the number of rows. -
cols=
num cols - Used for textarea entries. Specifies the number of columns. -
mandatory
- Specifies that this field must be filled in by the user. Notemandatory
should not be used in conjunction withhidden
. Use of both in any field will cause the mandatory check on any field to fail when the form is saved. -
hidden
- Specifies that this field will be hidden in the form: used to preserve values in edited pages. -
restricted
- Specifies that this field will be editable only by admins/sysops and disabled for all other users. -
uploadable
- Specifies that a link should be placed next to this field, that opens a popup window to let the user upload a file; see "Uploading files", below. -
autocomplete
- Specifies that this field will be autocompleted based on previous values entered for the semantic property that it covers. This declaration is not necessary for fields that handle properties of type "Page", since this kind of autocompletion happens for them by default. In practice, this parameter only makes sense for fields of type "String". -
no autocomplete
- Disables autocompletion for a field, if it's on by default. -
autocomplete on property=
property - Used for text entries. Specifies that autocompletion should use the set of pages or values pointed to by a certain property. -
autocomplete on category=
category name - Similar toautocomplete on property=
, but autocompletes on the names of pages within the specified category (and all its subcategories). -
autocomplete on concept=
concept name - Similar toautocomplete on property=
, but autocompletes on the names of pages within the specified concept. -
autocomplete on namespace=
namespace name - Similar toautocomplete on category=
, but autocompletes on the names of pages that belong to a certain namespace. -
autocomplete from url=
URL identifier - Specifies that autocompletion should be based on the values retrieved from an outside URL; see Autocompleting on outside values for how to do this. -
remote autocompletion
- Specifies that autocompletion values should be retrieved using Ajax calls to the server, instead of directly from a list of values hidden within the page's HTML. -
property=
property name - Specifies that the field corresponds to a certain semantic property, and should thus get the corresponding input type, autocompletion, etc. -
default=
default value - Specifies a default value for this field. For date-related fields, default=now will set the value to the current date and possibly time. For text fields, default=current user will set the value to the username of the user adding this page. -
values=
possible values - Specifies a set of possible values that this field can have, overriding whatever set of values may have been set from the semantic property. If this parameter is added, the field will, by default, show up as a dropdown. -
values from category=
category name - Similar tovalues=
, but gets its values from the names of all pages belonging to a specific category. -
values from concept=
concept name - Similar tovalues=
, but gets its values from the names of all pages belonging to a specific concept. -
list
- Specifies that this field contains a list of values; used for autocompletion. -
delimiter=
delimiter - Specifies the delimiter character or string this field should use, if it represents a list of values; the default is ",". -
class=
class name - Specifies a CSS class that the input for this field should have. -
show on select=
value=>
div ID - Can be used for inputs of type 'checkbox', 'checkboxes', 'radiobutton', 'dropdown' and 'listbox' to specify that a <div> tag with a certain ID should only be displayed to the user if a certain value (or values) is selected within that input. See here for an example of this feature in use (note what happens when you select different values for the "Publication type" dropdown), and see here for how it was implemented in the form. For inputs of type 'checkbox', simply "show on select=
div ID" should be used. It should be noted that show on select performs a simple Javascript hide/unhide to achieve the above. It does not actually limit what fields get processed in a form. It would be very hard to have parts of the form only get parsed when they need to be displayed.
-
-
choosers
- Specifies the input for selecting the 'chooser' fields (see above), if any, for this form. This tag should appear no more than once, if at all, in a form.
-
standard input
- One of eight inputs that usually appear in 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 Defining the bottom of the form for the full list.
- For the 'free text' input, the allowed parameters are rows, cols, hidden, restricted, default and preload. The first five work just as they do for field declarations. The new parameter is;
-
preload=
page title - Specifies a page whose contents should be preloaded into this field.
-
- For the other standard input types, the only allowed parameters are
-
label=
label name - Specifies the text associated with this input on the form. -
class=
label name - Specifies the CSS class for this input. -
style=
label name - Specifies the CSS style for this input.
-
Allowed input types for data types
Each defined Semantic MediaWiki data type has a default input type, and in some cases 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 | Default size | Other allowed input types |
---|---|---|---|
Page | text (with autocompletion) | 35 | textarea, category |
String | text | 35 | textarea |
Text | textarea | 5 x 30 | text |
Code | textarea | 5 x 30 | text |
URL | text | 100 | textarea |
Number | text | 10 | textarea |
Date | date | datetime (includes hours, minutes, seconds and AM/PM indicator), datetime with timezone (includes all of those, and a timezone), year (year only) | |
Enumeration (any property with defined "allowed values") | dropdown | radiobutton | |
Boolean | checkbox |
And here are the default and other allowed input types for delimited lists of a certain data type, enabled by the use of the "#arraymap" function:
Data type | Default input type | Default size | Other allowed input types |
---|---|---|---|
Page | text (with multiple-value autocompletion) | 100 | textarea, categories |
String | text | 100 | textarea |
Enumeration | checkboxes | listbox |
In addition, several other extensions define additional form input types: most notably, Semantic Maps defines map inputs for properties of type Geographic coordinate, while Semantic Forms Inputs defines a 'combobox' input for enumerations, a 'datepicker' input for dates, and a 'regexp' input for regular strings.
Autocompletion
One of the big strengths of Semantic Forms is that it supports autocompletion - you can enable a field to show a dropdown list of possible completions when the user starts typing. Semantic Forms' autocompletion matches the beginning of every word in the set of possible values. It is enabled by the Yahoo! User Interface (YUI) Javascript library.
If a field represents a semantic property 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. For fields representing a semantic property of type "String", there is no default autocompletion, but you can achieve this same effect simply by adding the parameter "autocomplete" to the field's definition. You can also autocomplete on other sets of values:
- to autocomplete on all the values of a specific property, add "autocomplete on property=property-name" to the field definition
- to autocomplete on the names of all pages in a category, add "autocomplete on category=category-name"
- to autocomplete on the names of all pages in a namespace (like "File"), add "autocomplete on namespace=namespace-name" (if you want to autocomplete on the main namespace, just add "autocomplete on namespace=").
- finally, you can autocomplete based on the values in an external URL; which lets you get autocompletion values from essentially any outside system. See Autocompleting on outside values for how to do this.
If a field is specified to hold multiple values (see below), 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).
The set of a field's possible values for autocompletion is, by default, contained right within the form's HTML page, in a Javascript declaration. For performance reasons, there is a limit to how many values can be placed in the page; this number is defined in the SF's "SF_Settings.php" file, as the variable $sfgMaxAutocompleteValues, and by default it is set to 1000. If you have more than this number of possible values for a field, you may want to use remote autocompletion instead, where autocompletion happens through an Ajax call to the server, based on what the user has typed. This type of autocompletion is slower, but always returns a comprehensive set of results. You can enable this by adding the "remote autocompletion" parameter to the field's definition.
Finally, you can disable autocompletion, if it's enabled by default for a field, by adding the parameter "no autocomplete" to the field's definition.
Multiple values for the same field
There may be fields for which you want the user to be able to enter multiple values. You can allow a single field in a template to hold many values, separated by commas or some other string. To do this, the template should contain the Semantic Forms parser function '#arraymap', which applies a mapping on each section of a delimited string. The generic call for this function is:
{{#arraymap:value|delimiter|var|formula|new_delimiter}}
The function splits the value by the delimiter, 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 the values for that field to be separated by commas and to each get the semantic property 'Has author', you could add the following to the template code, in place of a regular semantic tag:
{{#arraymap:{{{author|}}}|,|x|[[Has author::x]]}}
Essentially this function 'maps' the property tag onto each comma-delimited value in the field. (The 'delimiter' defaults to "," and 'new_delimiter' defaults to ", " 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.)
If you use the 'CreateTemplate' page to create a template, an option exists to let you automatically add this parser function in the template for any field that can take more than one value.
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.
For both #arraymap and #arraymaptemplate, the string "\n" in the value of either 'delimiter' or 'new_delimiter' will get converted into a newline. It should be noted that, 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.
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 below, for the 'Item' form, contains two such templates. If you look at the form that this definition generates, you can see that there are two buttons labeled 'Add another'. Clicking on either of these will create a new instance of that template and its field(s).
If you want to semantically store all the data contained in these multiple-instance templates, it is recommended to use the Semantic Internal Objects extension.
Uploading files
If a field in the form is meant to hold the name of an uploaded file (say, an image), you can allow users to upload this file directly through the form. This is done simply by adding the parameter "uploadable" to that field's declaration in the form definition. This will add a link reading "Upload file" next to this field in the form; if the user clicks on this link, it will pop up a "lightbox"-style window (using the Floatbox Javascript library) that lets the user upload a file. Once the user has done so, the window will close, and the field will contain the name of the uploaded file. 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.
For uploadable fields, you can also set the default filename of the uploaded files, by setting the "upload filename=" parameter in the field definition. The value of this parameter can also include the variable "<page name>", which gets substituted with the name of the page being added or edited. So adding to the field definition the parameter "default filename=Image for <page name>", for instance, for a page called "Abc", would set the default name of any uploaded file to "Image for Abc".
You can see a demonstration of file uploading here.
Category inputs
Two input types allow for a category-tree-style input: 'category' and 'categories'. 'category' is used for a single value in a field, and uses radiobuttons; while 'categories' is used for a multiple-value field, and uses checkboxes. Both input types use the code of the MediaWiki CategoryTree extension, so this extension must be installed for these inputs to work. You also need to specify an additional parameter: "top category=...", which sets the name of the category at the top of the "tree". You can also optionally set the parameters "height=" and "width=", to set the dimensions of the box in which the category tree appears.
It should be noted that these two input types print 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.
You can see a sample form that uses the 'category' input type here.
The free text input
The 'free text' input sets a textarea that holds all the non-template text in a page. The height, width and CSS style of this field can be set just as they would for any textarea input. If it is left out of the form definition, any free text in a page will be preserved in the form as a hidden field, not viewable or modifiable by the user. It is possible to have a WYSIWYG editor for the free text input: if your wiki has the MediaWiki FCKeditor extension installed, and it shows up correctly in regular 'edit' pages, then it should show up automatically as well for the free text input (currently, this is the only form input for which the FCKeditor can be made to work).
If you are using the FCKeditor, you can remove the links for users to disable it in the form, if you think those links will be distracting; you can do that by adding the following to LocalSettings.php: <source lang="php">$wgDefaultUserOptions['riched_start_disabled'] = false; $wgDefaultUserOptions['riched_use_toggle'] = false;</source>
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 seven allowed values are:
- "save" (for the "Save page" button)
- "preview" (for the "Show preview" button)
- "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, all six 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 wiki-text, that they appear in in the form definition.
Sample form
Here is the source code for the 'Item' form definition page at Discourse DB:
{{{info|add title=Add an opinion item|edit title=Edit an opinion item}}} <div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div> {{{for template|Item}}} {| class="formtable" ! Author: | {{{field|author|mandatory}}} |- ! Source: | {{{field|source|mandatory}}} |- ! Date: | {{{field|date}}} |- ! URL: | {{{field|url}}} |- ! Quote: | {{{field|quote|input type=textarea}}} |} {{{end template}}} {{{for template|Opinion|label=Opinions for this item|multiple}}} '''Topic:''' {{{field|1}}} '''Position:''' {{{field|2|size=55}}} '''Stance:''' {{{field|3|size=10}}} {{{end template}}} {{{for template|Reference|label=Previous opinion items this item refers to|multiple}}} '''Item name:''' {{{field|1|autocomplete on category=Items}}} {{{end template}}} '''Free text:''' {{{standard input|free text}}} {{{standard input|summary}}} {{{standard input|minor edit}}} {{{standard input|watch}}} {{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}}
Note the presence of both wiki-text and some limited HTML (the 'div' tag) within the code. This markup was created using the Create Form page, and based around the templates Item, Opinion and Reference. You can see the working form at this add data page; the form itself is created on-the-fly from the form definition file. In the 'Items' category page, if you click on any of the pages, you can see the 'edit with form' tab on the top right-hand side. If you click on that tab, you can see this same form, this time populated with the data contained in that page.
The 'wikiPreview' div tag, by the way, is included so that, when the user hits the "Preview" button, they'll be shown the preview directly within the form page, instead of being taken to another page.
Links for adding and editing
Adding data
Adding data is usually structured as a two-step process: first the user inputs a page title, and then he/she is sent to a form for either adding or editing that page, depending on whether or not the page already exists; this ensures that users don't accidentally overwrite existing pages. However, it's also possible to skip the first step, if the form contains a formula for setting the page title based on the user input.
The two-step process
There are two ways to let users add data in this way:
1) Use the 'forminput' parser function - adding this tag to any page will make an input that will let the user specify a title for adding or editing. By default, this input is included in every form created by the 'CreateForm' page. Here is the generic call for the tag:
Form:
- All arguments are optional. An explanation of the parameters:
-
form=
- the name of the SF form to be used; if it is left empty, a dropdown will appear, letting the user choose among all existing forms. -
size=
- the size of the text input (default is 25). -
default value=
- the starting value of the input (default is blank). -
button text=
- the text that will appear on the "submit" button (default is up to the browser). -
query string=
- the set of values that you want passed in through the query string to the form. It should look like a typical URL query string; an example would be "query string=namespace=User&User[Is_employee]=yes". -
autocomplete on category=
- adds autocompletion to the input, using the names of all pages in a specific category. -
autocomplete on namespace=
- adds autocompletion to the input, using the names of all pages in a specific namespace (only one can be used).
-
2) Use 'FormStart' - the user can go to /Special:FormStart; a form name can optionally be specified in the URL, so it looks like /Special:FormStart/form-name. If no form name is specified, a dropdown of all available forms in the wiki will appear next to the input for the page name, letting the user choose. (This approach is not recommended.)
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. If you're using the 'forminput' tag, the "query_string" value should include 'namespace=namespace-name'. If you're using 'FormStart', you can do so by setting the URL to something like "http://mywiki.com/Special:FormStart/form-name/Namespace:namespace-name".
Adding sub-pages
In MediaWiki, you can create sub-pages by including a slash in the page name. To have the page that's added automatically be a sub-page, you can add a value for "super_page=" in the query string. To make it a sub-page of the current page, you can set this value to "super_page={{PAGENAME}}". 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 created 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 field:
- '<TemplateName[FieldName]>' - gets replaced with the value for the specified field in the specified template. Note that the template specified is not "executed" - defaults applied, subtemplates processed - before the page name is set. Hence, the page name formula can ONLY utilize values given for template's input parameters.
- '<unique number>' - gets replaced by the lowest number for which the page title that's generated is unique. Normally, this value starts out as blank, then goes to 2, then 3, etc. However, one can manually set the starting number for this value, by adding a "start=" parameter; this number must be 0 or higher. For instance, to have the number start at 1 and go upward, you should set the tag to be "<unique number;start=1>". Note that the parameter is delimited by a semicolon.
For example, the form described above could have a declaration of "page name=<Item[Author]> opinion item <unique number;start=1>". This would include the author's name in the name of every opinion item, as well as a number to guarantee the uniqueness of every opinion-item page added. A user could then go to the URL "http://discoursedb.org/wiki/Special:FormEdit/Item" and fill out the form; if they set the author to be "Ernest Hemingway", and no other opinion items in the wiki had him as an author, then hitting the "Save page" button would result in a new page called "Ernest Hemingway opinion item 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 go instead to the regular form page, or to "Special:FormStart", they will be prompted for a page name, which will override whatever the automatic page name would be. (Though it should be noted that you can also change the form page to link to "Special:FormEdit/form-name", in place of having the #forminput input.)
If you want, you can generate this link using the "#formlink" parser function, instead of creating the URL directly. This function is called as:
The 'form=
' and 'query string=
' arguments work much the same way that their equivalents in "#forminput" work, and 'link text=
' works like 'button text=
' (see above). 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.
Example:
This will link from the page, via a button, to a form, and specifically the form's "Summary" tab (assuming you've set up tabs in the form using the Header Tabs extension).
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; 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 "&": "template-name[field-name-1]=field-value-1&template-name[field-name-2]=field-value-2"
- 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 'sfEditFormPreloadText' 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)".
The 'edit with form' tab
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 - categories are the standard Semantic MediaWiki approach to defining a page's type. 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, you should place the semantic property 'Has default form' in the page for that category; the tag should look like [[Has default form::form-name]]. You can do this automatically if you create the category using the 'CreateCategory' page.
As an example of this approach,
1) see the "Magazine" template source code on Discourse DB, which defines any page that includes it to be of category "Magazines";
2) Then see the "Magazines" category source code, which specifies the "Magazine" form as the default form for this category.
3) Finally, see the page for Newsweek magazine, which uses the "Magazine" template, and thus belongs to category "Magazines", and thus gets an "edit with form" tab at the top; this tab then links to editing with the "Magazine" form. And there you have it.
Based on namespace
The second possible way is to match the pages' namespace to a form. You can do that by placing a 'Has default form' property 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 property will probably be called 'MyWiki:User' (you may 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 this property to the page called 'MyWiki:Main', or whatever the main namespace is called in the language of this wiki. Once you've added this property, 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).
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.
Within the page
Pages can set their own form, by including a "Page has default form" property placed either directly within the page or in a template that the page calls, e.g.[[Page has default form::form-name]]. This is especially useful when the category and namespace options aren't possible, such as if pages belong to multiple categories that have different default forms; or for editing category pages themselves.
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 either "LocalSettings.php" or "SF_Settings.php" to change the appearance of the editing tabs:
-
$sfgRenameEditTabs
- renames the "edit with form" tab to "edit", and the "edit" tab to "edit source" (in whatever language the wiki is being viewed in) -
$sfgRenameMainEditTab
- 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.
If these settings are added to LocalSettings.php, they should be placed in the file after the include of Semantic Forms.
Pointing red links to a form
On 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 form. However, if the red link results from a new value for a semantic property, it can point to the correct Semantic Form to add the page.
- Simply add the semantic property 'Has default form' (see "The 'edit with form' tab") to the page for the property.
- Note: if your version of MediaWiki is older than 1.13, you must make a small modification to a file in the main MediaWiki code - the code change can be found here.
- You can also add one or more 'Has alternate form' properties to the property page, so that the user gets other possibilities when they click on the red link.
You can set either a default form, or alternate forms, or both, for a property; setting the default form can be done directly within the 'CreateProperty' page.
As an example, see this page. Both the author and the source are red-linked, but the links take you to forms for adding these two pages (please do not actually fill out and submit these forms, because that would ruin the example). When you get to the forms for each page, you can see, at the top, that there are alternative forms that you can select for adding each page. That is enabled by 'Has default form' and 'Has alternate form' properties in the pages for both the properties 'Was written by' and 'Was published by'.
Note also that, if you've made that MediaWiki code change, and you've defined a namespace as having a default form, red-links that go to a page within that namespace will also go to the right 'add data' form, without any extra work needed.
Sometimes, when a page with red links is first created, the red links will point (incorrectly) to the standard edit URL, and not to the form URL; the correct URL will only appear at some point later. That happens because of caching on the wiki. If you want to get around this problem you can very easily disable caching (see the instructions here).
Populating red-linked pages automatically
It's nice to have red links point to the right form for creating the page, but this still calls for work on the part of users - they have to click to the form, fill out the fields and save the page. This is especially bothersome when the form contains few or no fields, and/or if there are many such pages to be created. You can instead have such red-linked pages get automatically created by the system. To do this, instead of 'Has default form' or 'Has alternate form', you should add the special property 'Creates pages with form' to the property that you want pointing to those automatically-created pages. For instance, if you have pages that point with the property "Has country" to other pages, and you want those other pages to automatically be created using a form called "Country". You just need to add the following to the "Has country" property's page:
[[Creates pages with form::Country]]
It should be noted that it may take a while for each page to be created, since page creation is done through MediaWiki "jobs", which can take anywhere from a few seconds to several hours or more to run, depending on the length of the job queue.
Querying data
Forms can also be used for querying, as opposed to adding or editing data. To do so, 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, they see what the template looks like when displayed with the values they entered. The template that the form uses should contain one or more Semantic MediaWiki inline queries, to query data using values the user entered. You can see an example of a query form here.
In case query data need to be pre-loaded, the 'Special:RunQuery' should follow the convention Special:RunQuery/form-name?template-name[item-name]=value as in the example http://discoursedb.org/wiki/Special:RunQuery/Item_query?ItemQuerier[author]=Joe. The construction [item-name] might cause a problem in connection with the wiki markup therefore [ and ] can be replaced with %5B and %5D.
Other topics
Turning forms into tabbed sections
If you think a form is too long for users to fill out comfortably, you can turn into sections, with a tab interface to navigate between them, using the Header Tabs extension. If you install this extension, it is very easy to add tabs to a form: just add a top-level section wherever you want a tab to appear, of the form "=Tab 1="; and then add the tag""
near the bottom of the form, right above the "standard input" declarations. You can place tab declarations between templates, or within templates, to split up the fields of a template into different tabs. You can see a simple example of a form in tabbed sections here; the form definition used to create it is here.
Such tabs can also be used, in a similar way, to display data pages themselves.
Partial forms
You can specify a form to be a partial form by adding the property "partial form" to its {{{info}}} tag. This will make the form cover only the single or multiple templates that it contains, and not modify any part of the page before or after these templates. A partial form is not recommended as a default form for a category or namespace, but rather as a tool to modify parts of pages after they have already been created. You can see an example of a partial form here, and you can see it in action here, by clicking on the link reading "Add or change this opinion item's references".
Reusing form elements
If you have a set of forms that all contain the same text or sections, you can avoid duplication by creating templates that are used within those forms. Simply place all the text that you want repeated within a template, and call that template within each form. If that template contains form elements (like field definitions), the characters within the form elements simply need to be HTML-escaped - replace '{' with '{', '|' with '|' and '}' with '}'.
Caching form definitions
When a form is displayed, the form definition is parsed twice - first to turn the wiki-text into HTML, and then to handle the SF-specific tags like "{{{field}}}". If a form on your wiki takes a long time to display, it might be due to the first parse, which has been known to take seconds to run. You can have form definitions be cached, so the (mostly) HTML version can be retrieved directly, eliminating the first parse. To do this, add the following line to LocalSettings.php:
<source lang="php">$sfgCacheFormDefinitions = true;</source>
You then just need to re-save the relevant form page(s).
Hosting the YUI library locally
By default, Semantic Forms retrieves the Yahoo! UI Javascript files it needs directly from yahoo.com. For various reasons, you may not want your wiki to access an external website; if so, you can download the entire library from the YUI homepage, place it on the local web server, and then, in your LocalSettings.php file, below the inclusion of Semantic Forms, add the following line:
<source lang="php">$sfgYUIBase=...;</source>
where, in place of '...', you should have the URL of the local YUI library's "build" directory; it should include a "/" at the end.
Note that this change applies only to the Semantic Forms extension, and will not affect other extensions, like HeaderTabs, that also make use of the YUI library.
Defining new inputs
You can use hooks to define inputs, for either a new input type or a new semantic type; see Defining new inputs.
Common problems
MediaWiki issues
- If you've just set up your wiki and you want the URL of every page to look shorter and more like Wikipedia's, this short URL page explains how.
- If a template contains section headings (like "==Section 1=="), when the template is displayed on a page each section heading will have its own "Edit" link. Such links are not desirable, since they will take the user to editing the template, rather than the actual page in question. The easiest way to avoid this problem is to place the string "__NOEDITSECTION__" anywhere within that template; this will remove all section-edit links from any page that contains that template.
- If you encounter an error like "Memory Size Exhausted", it may help to increase the memory limit for PHP, by adding the following to LocalSettings.php: "ini_set( 'memory_limit', '32M' );"
Semantic MediaWiki issues
- To get rid of the "error" image that appears for incorrect property values (for versions of SMW before 1.4.3, this includes blank values as well), add the following line to your 'LocalSettings.php' file: "$smwgInlineErrors = false;"
Semantic Forms issues
- You can change the way dates are entered in, and outputted by, the forms by adding the line "$wgAmericanDates = true;" to the main MediaWiki LocalSettings.php file. By default, dates are printed out as "2007/06/20"; making this change will set dates to instead be printed out as "June 20, 2007" (with the month name dependent on the language of the wiki).
- Similarly, you can change the way times are entered and displayed. If you have a form field with input type 'datetime', by default it will use the 12-hour format, with "AM" and "PM". You can change this to 24-hour format by adding the line "$sfg24HourTime = true;" in your LocalSettings.php file.
- If a page (which we'll call Page A) gets transcluded in another page (which we'll call Page B), and Page A belongs to a category that's associated with a form, it can have the unfortunate side effect of making Page B a member of that category as well, thus giving Page B an "edit with form" tab at the top, even if such a tab is not appropriate. You can solve this problem by putting the category declaration in Page A within a "<noinclude>" block, which will make Page A a member of that category but not Page B.
- If, when you go to the special pages 'CreateProperty' or 'CreateTemplate', you see a database error message that looks like "Access denied for user...", it means your database account lacks permission to create temporary tables.
- If dates before 1970 and after 2037 are not displayed correctly in the form, that is most likely because you have a version of PHP older than 5.1; consider upgrading, if possible.
- If you want to do any processing on a list of values before calling #arraymap on it, such as sorting it, splitting it up or printing its size, it may help you to use the ArrayExtension extension.
- Semantic Forms only handles forms for adding and editing data in wiki pages. You may want forms for other purposes: fortunately, there are other form extensions you can use. EmailForm allows you to create forms for emailing data, and Simple Forms allows you to create generic forms for a variety of purposes. See also the MediaWiki forms manual for other such extensions.
- It is best to urlencode all elements of query strings, otherwise special characters like ampersands (&) cause trouble. An example #forminput call with urlencoded query string elements:
{{#forminput:form=Car|query string=Car[Manufacturer]={{urlencode:{{{Manufacturer}}} }}&Car[Colour]={{urlencode:{{{Colour}}} }} }}
Note, that the ampersands dividing the query string elements must not be urlencoded.
You can also see other tips and hints for using Semantic Forms in the tips section of the SMW Community Wiki.
Data design issues
- One common issue is how to use categories. The Wikipedia approach is to have many categories on each page, to identify all aspects of that page's subject. Semantic MediaWiki was created in part to eliminate the need for categories, by allowing for semantic properties to represent this data. The general Semantic Forms approach is to only have one category per page, and have this category be set by the main template in the page: in other words, it is recommended that users not enter category declarations directly. The one exception to this rule is when there's a need for "hierarchical tagging", i.e. being able to add a page within different levels of a category tree. For this purpose, the 'category' and 'categories' input types exist.
- When creating a semantic property connecting any two "classes", or pages represented by different categories, you may be unsure about which way to point the property. Usually such relationships will be of the one-to-many variety, also known as parent-child relationships, in which each page of type A has a relationship to any number of pages of type B, while each page of type B always has a relationship to exactly one page of type A. An example is countries and cities: a country can have many cities, but a city always belongs to exactly one country. In such a case, you may not know whether it should be country pages that have a "Has city" property, or city pages that have a "Belongs to country" property, or even whether both properties should exist. In this situation, it is recommended that you specify the relationship only from the child to the parent, i.e. use a "Belongs to country" property for cities and not the other way around. This is for two reasons: first, it lets you guarantee the rule that every child has exactly one parent, by setting this property through a field within the child's main template; and second, it makes page-name autocompletion more reliable, since parent pages are usually created before their children's pages are.
- You may not be sure about whether to create one form or many for a set of related page types. For instance, in a wiki about restaurants, should you have a separate form/template/category set for regular restaurants, fast-food restaurants, diners etc., or a single form called "Restaurant", with a corresponding single template and category, that just uses a field to indicate the type of restaurant it is? A good rule of thumb is to look at the set of data that you want to be entered and displayed for each type of page. If it's the same across all the types, then you could probably use a single form/template/category set for all of them. However, if there's even one difference in the set of fields being displayed for any page type, then it probably makes sense to give such a page type its own form, template and category.
- It is possible to create a different namespace for each page type. Wikisource does this with an "Author:" namespace, for instance, and several SMW-based wikis have one or more namespaces for different page types. Whether you do this on your wiki is up to you, but it is not recommended that you do it unless there is a real possibility of naming ambiguity otherwise. A massive wiki like Wikipedia will have a great deal of pages that require disambiguation, but most small wikis will barely have any, and so having separate namespaces will probably be a needless complication. (Currently the only common examples of ambiguity in SMW wikis are caused by having pages for both cities and states in the United States: "New York" and "Washington" both fit into either category. There are various solutions to this problem, but the simplest may be to have all states referred to by their two-letter abbreviation, e.g. "NY" and "WA".)
Testing the extension
The best place to try out Semantic Forms is on the "Referata scratchpad" wiki, at scratchpad.referata.com. There you can create all the properties, templates, forms, etc. that you want, and see how they all interact. You do not need to register to make edits.
Sites that use Semantic Forms
Here is a small sampling of sites that use Semantic Forms in conjunction with Semantic MediaWiki, subdivided by type. For a more comprehensive listing, see the list of sites that use Semantic Forms on the Semantic MediaWiki Community Wiki, which is itself an SMW-based wiki that contains additional information on each site.
Culture: Politics and government: Place listings: |
Goods and services: Science and technology: |
Individual organizations: Ontologies: Environment: Research: |
Mailing list
Please use the Semantic MediaWiki mailing list, semediawiki-user, for any questions, suggestions or bug reports about Semantic Forms; if possible, please add "[SF]" at the beginning of the subject line, to clarify the subject matter.
Until July 2009, Semantic Forms had its own mailing list - you can see the archives here.
Work for hire
A number of people and companies can be hired to set up, or help with the design of, a wiki that uses Semantic Forms - for a listing, see the work for hire page on semantic-mediawiki.org.
Hosting
Currently three wiki hosting sites offer support for Semantic Forms:
- Referata - a site created and run by Yaron Koren. Wikis on Referata can use Semantic MediaWiki, Semantic Forms and a variety of related extensions; basic usage is free.
- Wikia - wikis on Wikia can request Semantic MediaWiki, Semantic Forms and Semantic Drilldown to be turned on (they are not enabled by default). Be aware that these extensions can be several versions behind on Wikia; see here, for example, for the current version numbers. Additional SMW-based extensions are currently not available on Wikia.
- YourWiki - similarly to Wikia, Semantic Forms and related extensions can be turned on by request.
Contributing to the project
Bugs and feature requests
You can submit bug reports and requests for new features at MediaWiki's Bugzilla, here.
The current list of known bugs and requested features for Semantic Forms can be found here.
Contributing patches to the project
If you found some bug and fixed it, or if you wrote code for a new feature, please create a patch by going to the main "SemanticForms" directory, and typing:
svn diff >descriptivename.patch
Then go to the relevant bug report in Bugzilla, or create one if one doesn't exist (note, again, that Bugzilla is used for both bugs and feature requests), and attach this patch file to it.
If, for any reason, you don't wish to use Bugzilla, feel free to simply send this patch, with a description, to the semediawiki-devel mailing list.
Translating
Translation of Semantic Forms is done through translatewiki.net. The translation for this extension can be found here. To add language values or change existing ones, you should create an account on translatewiki.net, then request permission from the administrators to translate a certain language or languages on this page (this is a very simple process). Once you have permission for a given language, you can log in and add or edit whatever messages you want to in that language.