Data Forms
df_dataform.jpg

Wikidot Data Forms is a very powerful feature that makes it possible to build everything from simple applications in your wikidot sites to a complete content management system (CMS) across your entire site.

A normal wiki page holds unstructured text. A wiki page with a data form holds structured data in "fields", the same as a database. In many cases structured data in a data form is easier for your users to edit, to understand and to work with.


Some uses for data forms

Some of the uses where data forms might work better than simple wiki pages are:

  • I'm collecting references for my thesis, and for each reference I want to record the title, author, ISBN, date of issue, publisher, and language. If I use a data form with one field for each piece of data, I can easily produce reference lists in any format.
  • I'm organizing my club membership and for each member I want a page with their name, email address and so on. By using a data form I can extract fields like the email address to send everyone a newsletter.
  • I'm cataloging my video game collection and using a data form means I can search on games by console, by publisher, by genre and so on.
  • I want my members to enter information about software, but I want to control what they enter by using lists they select from.
  • I want users of my site to be able to easily upload images and videos at the same time that they create a page.
  • I want to build a complete site where the user doesn't need to know any Wikidot syntax but can just fill in forms and press Save.

Live demo

  • A live demo is available to show the features of data forms that we have described in this documentation. The permissions have been relaxed so you can try out the form:

* main page for creating new pages in the band category and for listing bands: http://vineyard.wikidot.com/bands:main
* example page at http://vineyard.wikidot.com/band:queen
* live template at http://vineyard.wikidot.com/band:_template


How to create a new data form

Wikidot stores normal pages in categories and it is exactly the same when you use data forms. Each data form page is one page in a specific category. A category can have only one data form and that data form structure applies to all pages in that category, so you cannot mix data form pages and normal wiki pages in the same category.

To create a new data form you need to do the following:

1) create a live template page for the category the form will be in. For example if your category is band, the live template page must be called band:_template.

2) add a [[form]] ..[[/form]] section then your fields. The different types of fields you can have (text, select, checkbox, file, wiki, static, hidden and password are described in the reference section at the bottom of this page.

Please note that the indentation shown in the example below is important because if the different rows are not indented correctly the fields will not display. Your structure should look like the example below, but note that you don't have to enter a field type and a width; if you don't enter a field type it will default to a text field type. The width is also not mandatory.

Please note that for all fields you must have a space between the colon and the value, for example label: Music type is correct, but if you enter label:Music type you will get n error message when you try to save the page.

[[form]]
fields:
  type:
    label: Music type
    type: select
    values:
      0: Classical
      1: Country
      2: Folk
      3: Indie
      4: Jazz
      5: Pop
      6: Rock
    default: 6
  bandimage:
    label: Image
    type: file
  bandwebsite:
    label: Band website
    type: url
  current:
    label: Currently Recording
    type: select
    values:
      0: "Yes"
      1: "No"
    default: 0
[[/form]]

After you define a [[form]] ..[[/form]] structure like the one above, when you edit add or edit any page in the category it shows the form instead of the normal page editor.

Checking for errors

Wikidot used to be relaxed about whether there were spaces after the colon, but now a more strict version of the code is used which will give you an error if you have built your data form with incorrect spaces. However, there is an app developed by one of our gurus, tsangktsangk to test whether your data form has been built correctly and has the correct spacing. The app is at http://community.wikidot.com/app:convert. You just copy and paste your whole page into the app and it will convert the data form to the correct structure if it finds errors.


Setting up your Site Manager

You can configure category permissions for a category with a data form exactly as for normal categories so that, for example, only the author of a page can edit it.

It is sometimes a very good idea to autonumber the category containing the data form. This will remove the risk of duplicate page names. This is setup in the site manager > autonumbering of pages.


Creating a new page

You can create a new page in your data form category in three ways:

1) in your browser address bar, enter the category and pagename after the sitename, for example http://yoursite.wikidot.com/band:genesis. Then press Enter.

2) create a NewPage module button. This method allows you to set the category, parent page, any tags you want when the page is saved and the text of the button. for example:

Enter the name of the band and press the button:
[[module NewPage size="30" category="band" parent="bands" tags="rock" button="Add a new rock band"]]

3) use the NewPage Button at http://snippets.wikidot.com/code:newpage-button which is an excellent snippet created by James KanjoJames Kanjo. Using our band example, if you use this you will need to change the name of the band when you edit the form from Band to the actual name of the band.

[[include :snippets:newpage-button
|size=30
|category=band
|name=band
|parent=bands
|tags=rock
|button=Add a new band
]]


Displaying the results

If you just save the [[form]]..[[/form]] structure then create pages, each page will have simple layout with each field under the previous one in the order the form was structured. With this simple layout any images uploaded won't be displayed, just a link to the image.

But you can layout the fields that are displayed in any way you like and display uploaded images and videos. To do this you need to divide the live template page into 2 areas with ==== separator between them:

The [[form]]..[[/form]] data form goes at the bottom of the page. Above that is a separator, ====, and then above the separator is how you want the form to be displayed on the page. This might be just the fields, it might be a table or it might be a more complex layout using divs, modules, tables and css. You display the data for the form using the following syntax. In place of the word field use

To display.. Use..
the data %%form_data{field}%% (except for images, video and email)
images %%form_raw{field}%%
the label %%form_label{field}%%
the hint %%form_hint{field}%%
email addresses use a wiki field then display it using %%form_raw{field}%%.

Using the form we created above, the dataform structure, separator and layout are shown below with a very simple layout:

[[f<image %%form_raw{bandimage}%% width="150px"]]

++ %%title%%

Band type: %%form_data{type}%%
Band website: %%form_data{bandwebsite}%%
Is the band currently recording?: %%form_data{current}%%

====

[[form]]
fields:
  type:
    label: Music type
    type: select
    values:
      0: Classical
      1: Country
      2: Folk
      3: Indie
      4: Jazz
      5: Pop
      6: Rock
    default: 6
  bandimage:
    label: Image
    type: file
  bandwebsite:
    label: Band website
    type: url
  current:
    label: Currently Recording
    type: select
    values:
      0: "Yes"
      1: "No"
    default: 0
[[/form]]

The result is:

df_queen.jpg

Using the data in ListPages modules

The data that is produced by data forms can be used in the ListPages module (http://www.wikidot.com/doc:listpages-module). With the band example, a ListPages module could look like this:

[[module ListPages category="band" order="name"  separate="false" prependLine="||~ Band||~ Type ||~ Current ||" appendLine="||||||||~ ||"]]
|| %%title_linked%% || %%form_data{type}%% || %%form_data{current}%% ||
[[/module]]
df_bandlist.jpg

Selecting & Sorting by Data Form fields

Using the ListPages module you can select data from a field in the data form and you can also sort by the values within a data form field.

Selecting

Add a field to your data form or use an existing. With our band example we have added a field to note whether the band will visit Scotland on their next tour:

 scotland:
  label: Next tour will visit Scotland
  type: select
  values:
     info: No Info
     visit: "Yes"
     novisit: "No"

To list those where the value is "Yes" use a ListPages module and add a new parameter starting with an underscore then the fieldname, in this case _scotland followed by an = sign and the property of the field you want: _scotland="visit"

[[module ListPages category="band"  _scotland="visit" perPage="10" order="name"  separate="false" prependLine="||~ Band||~ Type ||" appendLine="||||||~ ||"]]
|| %%title_linked%% || %%form_data{type}%% ||
[[/module]]

That produces a list of just 2 bands:

df_scotland.png

You can combine several data form selection fields to narrow down your search. For example if we wanted to just select folk bands that will tour Scotland we would use the _scotland="visit" selection criteria and the _type="2" selection criteria (because type is the data form feld for the music type, and 2 is the property of the folk value).

 type:
   label: Music type
   type: select
   values:
     0: Classical
     1: Country
     2: Folk
     3: Indie
     4: Jazz
     5: Pop
     6: Rock
   default: 6

Combining different selection criteria uses the AND operator, so the result must match both of these criteria. The resulting ListPages code would look like this:

[[module ListPages category="band"  _scotland="visit" _type="2" perPage="10" order="name"  separate="false" prependLine="||~ Band||~ Type ||" appendLine="||||||~ ||"]]
|| %%title_linked%% || %%form_data{type}%% ||
[[/module]]

and the table that is produced is:

df_filter.png

You can search for pages where a particular field is empty by using _field=""

Sorting

You can also sort by data form field properties. In our band example we have created a field to store the number of albums/CDs released by the band:

 albums:
    label: Albums/CDs released
    type: select
    values:
      "00": 0
      "01": 1
      "02": 2
      "03": 3
      "04": 4
      "05": 5
      "06": 6
      "07": 7
      "08": 8
      "09": 9
..

To sort the number of albums into descending order, use a Listpages module with the order=parameter followed by an underscore then the name of the field then the desc attribute: order="_albums desc"

[[module ListPages category="band"  perPage="10" order="_albums desc" separate="false" prependLine="||~ Band||~ Albums ||" appendLine="||||||~ ||"]]
|| %%title_linked%% || %%form_data{albums}%% ||
[[/module]]

In order for the sort to work correctly, numbers below 10 must have a property of 01, 02, 03 etc. although the value can still be 1, 2, 3 etc as in the example data form field above. It is the value that is displayed in the ListPages module, as shown below. As (01, 02, 03, …) are treated as octal numbers you need to enclose them by semicolons ("01", "02", "03", …) because there is no 08 and 09 in octal and they both will be 0.

df_albums.png

Images in Data Forms

Data form field

To upload an image to your dataform you need to use a file field.

Layout

You display the image using %%form_raw{field}%%, not %%form_data{field}%%.

As with images on normal pages you can set parameters like a float or the width. For example:
[[f<image %%form_raw{field}%% width="150px"]]

You can also combine data forms with the image box snippet created by Timothy FosterTimothy Foster which will allow you to easily add a header, caption, a float left or float-right, specify the width and add a link for the image. In the data form use a file field for the image, a text field for the header and a text field for the caption.

Then to display them, above the ==== separator use the following snippet code with %%form_raw{field}%% for the image and %%form_data{field}%% for each of the header and caption. You do not need to have a value in each parameter line of the snippet code. An example of how it would look is below.

[[include :snippets:image
|image=%%form_raw{field}%%
|width=150px
|float=right
|heading=%%form_data{field}%%
|caption=%%form_data{field}%%
|link=*%%form_data{bandwebsite}%%
]]

Where images are stored

On normal wiki pages you can upload an image to the page. This is not the case with data forms. When you upload an image using a data form, it places the image on its own page in the file category and the page is called the name of the image. So for example if your user presses the browse button in the data form and uploads an image called queen.jpg, that image is saved on the page http://yoursite.wikidot.com/file:queen

Although the filecategory is used by default for images, you can change the category the images on a data form are saved in. To do this use the category attribute as follows:

[[form]]
fields:
  eventimage:
    label: Image
    type: file
    category: eventimages
[[/form]]

If you had specified this in the data form structure in your live template before uploading the queen.jpg image it would have saved it at http://yoursite.wikidot.com/eventimages:queen

Displaying a default image

If you don't upload an image to a file field in a data form, older browsers like IE8 will show a box with a red x or similar. This doesn't look good and makes it seem that a mistake has been made. So, instead you can display a default image which will be displayed instead. This could be a blank image or a general image related to the site. If an image is uploaded to the field in the data form then that image will be used instead..

It needs a css module in the live template and this example also uses the image box snippet from http://snippets.wikidot.com/code:image-box to display the relevant image:

[!-- Following CSS module is needed for the default image code below --]
[[module CSS]]
.form-image-default%%form_raw{bandimage}%%{ display: block !important; }
.form-image%%form_raw{bandimage}%%{ display: none !important; }
[[/module]]

[[div class="form-image"]]
[[include :snippets:image
|image=%%form_raw{bandimage}%%
|width=150px
|float=right
|heading=
|caption=%%form_data{band_caption}%%
|link=%%form_data{band_link}%%
]]
[[/div]]
[[div class="form-image-default" style="display: none;"]]
[[include :snippets:image
|image=/css:theme/blankjpg
|width=150px
|float=right
|heading=
|caption=
|link=
]]
[[/div]]


YouTube and other external content

Data form field

To upload a YouTube video to your data form you need to use a wiki field. The user pastes the html embed code into the field on the dat aform.

Layout

To display it, above the ==== separator use [[html]] tags and form_raw as follows:

[[html]]
%%form_raw{field}%%
[[/html]]

Example

  • add a wiki field to the data form:
  bandvideo:
    label: Video
    type: wiki
  • above the separator you add an [[html]] block and %%form_raw{bandvideo}%% to display the video:
[[html]]
%%form_raw{bandvideo}%%
[[/html]]
  • the user pastes the YouTube embed code into the field:
df_video.jpg
  • the result is
df_video2.jpg

Tags

It is not currently possible to set tags when saving the data form based on the values in the data form.

However a workaround is possible until a tag field is implemented. This workaround is described at http://community.wikidot.com/forum/t-402555/automatically-setting-tags-for-a-page-based-on-form-input


External Links

Data form field

To upload a url to your data form you need to use a url field. It defaults to http:// format so the user just needs to enter the url in the format www.wikidot.com

Layout

To display the link, above the ==== separator use %%form_data{field}%%.

You can have the link open in a new window by adding a * as follows: *%%form_data{file}%%


Internal Links

Data form field

To include an internal link in to your data form you use a text field. The user just enters the name of the page in the box on the form..

Layout

To display it, above the ==== separator use normal internal link syntax and form_data: [[[%%form_data{field}%%]]]


Styling the output of a field

You can set the color and other styles of a field on the form after it is saved. Create the field in your data form in the normal way as follows:

[[form]
fields
...
...
  priority:
    label: Priority
    type: select
    values:
      normal: Normal
      urgent: Urgent
      critical: Critical
....
[[/form]]

Above the ==== separator add a CSS module:

[[module css]]
.normal { color: green; }
.urgent { color: red; }
.critical { color: red; font-weight: bold;}
[[/module]]

Then use a css span class and a combination of form_raw and form_data to display the field in the relevant color:

[[span class="%%form_raw{priority}%%"]]%%form_data{priority}%%[[/span]]


The Pagepath concept

Wikidot data forms have a unique concept, the Page Tree and pagepath, which is a way of organizing data. It creates a page in a specific category for each pagepath entry you enter. Using our band example you could set the origin of the band. Band origins form a tree:

  • _root
    • USA
      • Chicago
      • Los Angeles
    • Australia
      • Melbourne
      • Sydney
    • Europe
      • UK
        • London
            • North-London
            • South-London
              • Dulwich
            • East-London
            • West-London
        • Newcastle
        • Glasgow
      • Germany
      • Sweden

Each part of the tree is a wiki page. Imagine this tree is held in a category called band-origin. Now we can use parent links to attach Dulwich to South-London to London to UK to Europe, and Chicago to USA etc.

The Wikidot data form system makes it easy to navigate, and edit such a tree. You define a 'pagepath' field and tell it to use the band-origin: category, as shown in part of a dataform below:

 origin:
   label: Origin
   type: pagepath
   category: band-origin

A page tree is always anchored to a page called _root that Wikidot creates automatically when you start using a page tree in forms.

When you and your users are entering data into the dataform, for the pagepath field they will initially see a single dropdown box. If there is already a value in the box they can select it or click on the create new entry in the dropdown and enter the value you want.

df_pagepath.png

After entering the value you must press Enter. That will then add the value you have selected or entered and open the next box. There is no limit to the number of these boxes (and the pages they create) that you can have.

In the layout of your page, above the ==== selector, you use %%form_data{origin}%% and the lowest value in the pagepath list of values will be displayed. So if you have Europe->UK->London, London will be displayed.

The pages that the pagepath creates can list each of the bands who have that value. To do this, create a live template page containing [[module Backlinks]].

A site dedicated to examples of the pagepath concept is at http://pagepath.wikidot.com/


Deleting a form

If you wish to remove a form from the live template, do not simply comment it out. Either delete it completely or change [[form]] to something like [[x-form]]. Otherwise the form will continue to be used.


Reference

The form definition is made in YAML, which is a simple structured markup language. A _template may have a single form. The form starts and ends with [[form]] and [[/form]] as for code blocks. Within those tags, we describe the form using YAML:

[[form]]
fields:                           #  This is always required at the start
  name-of-the-field:              #  Use a valid YAML name (i.e not starting with a number)
    label: Label                  #  This is what the user sees when using the form
    type: type-of-field           #  The field types
    property: value...            #  Depending on the field type
[[/form]]

The default field type is 'text', unless you specify one or more values, in which case it defaults to 'select'.

Always start name of the field form with a letter. Field names starting with a digit or some other character are invalid. In case of special YAML symbols like true, false, yes, no, you may need to surround those with simple quote signs like this: "yes".

Field Properties

Properties that apply to all field types

The 'label' property

If you specify a 'label' property then the field gets that text in the left column, or before the field for joined fields. If you do not specify a label then the field has an empty space in the left column, or is squashed up after the previous field, for joined fields. For example:

[[form]]
fields:
  address-line-1:
    label: Address
    width: 30
  address-line-2:
    width: 30
  address-line-3:
    width: 30
[[/form]]

The 'join' property

If you specify 'join: true' then the field is placed after the previous field, if any. This property has no effect if the field is the first in the form. For example:

[[form]]
fields:
  city:
    label: City
    width: 20
  postcode:
    label: Postcode
    width: 8
    join: true
[[/form]]

The 'before' property

Provides a string of plain text that displays before the field value

[[form]]
fields:
  phone:
    label: Phone
    width: 10
    before: +(1)
[[/form]]

The 'after' property

Provides a string of plain text that displays after the field value

[[form]]
fields:
  speed:
    label: Car speed
    width: 4
    after: kph
[[/form]]

Properties for specific field types

There are additional properties that only apply to specific field types. These are documented below with the field type(s) they apply to.

Field Types

The 'text' field type

Defines a text or text box field. Allows 'width' and 'height' as properties. If you don't specify a height you get a normal 1-line text field. If you do specify it, you get a text box. For example:

[[form]]
fields:
  name:
    label: Your name
    type: text
    width: 30
  comment:
    label: Your comment
    type: text
    width: 50
    height: 3
  email:
    label: email address
    match: /^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/
[[/form]]

The specific properties you can use on a text field:

  • width: specifies the visible field width in columns (fixed spaced characters, more or less).
  • height: specifies the field height in rows, 1 is normal text field, 2 or more is a text box.
  • match: specifies a regular expression (regex) that the field value must match.
  • match-error: specifies a custom error message.
  • hint: provides a string of text that is displayed in the field when empty.
  • default: defines a default value for the field shown on new pages.

In the hint, if you want to use special characters like a # then you need to escape the character using \. For example, hint: enter a colorname like white or a hex value like \#468259

Wiki syntax does not work in a text field.

The 'select' field type

Defines a multi-value selection field. Requires a set of values. If you specify two to four values, you get a horizontal radio field. If you specify five or more values, you get a drop-down select field. For example:

[[form]]
  type:
    label: Music type
    type: select
    values:
      0: Classical
      1: Country
      2: Folk
      3: Indie
      4: Jazz
      5: Pop
      6: Rock
    default: 6
[[/form]]

In the above example the properties of the select field were 0 to 6 with the default property of 6 which set the value to Rock. However, you can use words as properties, for example:

  type:
    label: Music type
    type: select
    values:
      cl: Classical
      co: Country
      fk: Folk
      in: Indie
      jz: Jazz
      po: Pop
      ro: Rock
    default: ro

The specific properties you can use on a select field:

  • default: defines a default value for the field shown on new pages. For example default:1

Reserved values in a select field:

The values of Yes, No, True and False are reserved values that have a special meaning in the YAML code that powers data forms. To use them in your data form you need to place them inside quotemarks as follows otherwise they will not work:

  done:
    label: Done?
    type: select
    values:
      not: "No"
      done: "Yes"
    default: not

The 'checkbox' field type

Defines a checkbox field, stored in the form data as 0 or 1. For example:

[[form]]
fields:
  onions:
    label: Do you want onions?
    type: checkbox
  salami:
    label: How about extra salami?
    type: checkbox
    default: 1
[[/form]]

The specific properties you can use on a checkbox field:

  • default: defines a default value for the field shown on new pages.

The 'pagepath' field type

Lets the user create and select from a page within a page tree; the 'path' is the list of all parents plus that page. It is visualized as page / page / page / page with at each level, the option of viewing that page, changing the page, or adding a new child. This does not affect the actual page parent, and a form can have many pagepath fields. The pagepath field value is stored as a page full name. Hidden pages are invisible to users when selecting and navigating the page tree.

 origin:
   label: Origin
   type: pagepath
   category: band-origin

The specific properties you can use on a pagepath field:

  • category: specifies the category that holds the page tree.
  • default: defines a default value for the field shown on new pages.

The 'hidden' field type

Adds data to the form that the user cannot see or edit. It takes no space visually. This is for putting data into the page so that data can be used later. The value of the field is defined by the 'value' property.

[[form]]
fields:
  version:
    type: hidden
    value: 1.0
[[/form]]

The specific properties you can use on a hidden field:

  • value: sets the value of the field

The 'wiki' field type

Works like text but lets the user enter wiki syntax.

[[form]]
fields:
  version:
    label: Fancy text field
    type: wiki
[[/form]]

The specific properties you can use on a wiki field:

  • width: specifies the width of the field in the dataform.
  • height: specifies the height of the field in the dataform.

The 'static' field type

This shows non-editable text and lets the form designer add text and formatting to the form. Static fields are not stored in the page. Static fields get their value from the 'value' property.

[[form]]
fields:
  version:
    type: static
    value: Non-storable field with with **bold**, //strike// and __underline__.
[[/form]]

The specific properties you can use on a static field:

  • value: sets the value of the field

The 'file' field type

This lets the user upload files directly from the data form. It is displayed as a link to the file.

Files are not uploaded to the same page. Instead, a separate page is created for each file in a different category, 'file' by default, with the pagename being the name of the image.

[[form]]
fields:
  document:
    type: file
    label: Upload document
    category: alternative-category
[[/form]]

The specific properties you can use on a file field:

  • category: specifies the category that the page will be created in ('file' category if not specified), and the uploaded file is attached to this page.

Note that images won't be treated like they are when attaching an image to simple (i.e. non-data form enabled) page. This means they won't be displayed by the [[gallery]] tag.

The 'url' field type

This lets the user enter URLs. This is displayed as a link.

[[form]]
fields:
  info_link:
    type: url
    default: ftp://example.com/files/
    match-error: Custom error msg.
    required: true
    default-schema: ftp://
[[/form]]

The specific properties you can use on a url field:

  • width: specifies the visible field width in columns (fixed spaced characters, more or less).
  • default: defines a default value for the field shown on new pages.
  • default-schema: define a default schema for URL ('http://' if not specified).
  • match-error: specifies a custom error message.
  • required: specifies if the field is mandatory [true/false] ('false' if not specified).

The 'password' field type

This lets the user enter masked text. To the user, each character they type is replaced by an asterisk ( * ).

[[form]]
fields:
  pass:
    type: password
[[/form]]

Important: Entered text is not encrypted, you can always read it in page source.

CSS Styling

You can modify the look and feel of your data forms using CSS (either per-site, or per page using the CSS module. This is the CSS model for data forms:

  • table
    class: form-table
    • tr
      class: form-row row-{row number}
    • td
      class: form-labels
    • span
      class: form-label
    • td
      class: form-values
    • span/div (div for wiki and static)
      class: form-value field-{name}
      class': form-error (added to field while save when there is matching error)
      • {field}
        class: form-{type}
      • span
        class: form-message

Styling the hint text

If you have a long hint text you might find that it is longer than the text box. This is because by default the text box is a partcular width. In this case you can either set the width of that particular field to be wider or you can use CSS to set the same width for all text input boxes and ensure the hint fits inside it by using:

input[type="text"], textarea {
    width:100%;
}

Hints & Tips

  • You can use dataform fields to set headings in your page.
  • The wiki fieldtype is very powerful as it allows the user to use all the formatting and other wiki syntax. It is therefore more useful than the text fieldtype
  • You can allow the user to set their own CSS for particular elements on the page by passing the contents of a dataform field into a css module.

If you want to know how to achieve any of these or other dataform features on your site, please contact us on the community site at http://community.wikidot.com/forum:start


Thanks

Thanks of course go to the Wikidot developers for releasing such a powerful addition to the feature set. Thanks also for the good ideas and solutions from my fellow admins, particularly Helmut_pdorfHelmut_pdorf and Ed JohnsonEd Johnson


RobElliottRobElliott November/December 2011

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License