Skip to content
This repository has been archived by the owner on Sep 5, 2019. It is now read-only.

Commit

Permalink
Document onegov.form grammar
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Krienbühl committed May 18, 2015
1 parent 4c97239 commit 610e42e
Showing 1 changed file with 201 additions and 10 deletions.
211 changes: 201 additions & 10 deletions onegov/form/parser/grammar.py
@@ -1,4 +1,187 @@
# -*- coding: utf-8 -*-
""" onegov.form includes it's own markdownish form syntax, inspired by
https://github.com/maleldil/wmd
The goal of this syntax is to enable the creation of forms through the web,
without having to use javascript, html or python code.
Also, just like Markdown, we want this syntax to be readable by humans.
Syntax
======
Fields
------
Every field is identified by a label, an optional 'required' indicator and a
field definition. The Label can be any kind of text, not including ``*`` and
``=``.
The ``*`` indicates that a field is required. The ``=`` separates the
identifier from the definition.
A required field starts like this::
My required field * =
An optional field starts like this::
My optional field =
Following the identifier is the field definition. For example, this defines
a textfield::
My textfield = ___
All possible fields are documented further below.
Fieldsets
---------
Fields are grouped into fieldsets. The fieldset of a field is the fieldset
that was last defined::
# Fieldset 1
I belong to Fieldset 1 = ___
# Fieldset 2
I belong to Fieldset 2 = ___
If no fieldset is defined, the fields don't belong to a fieldset. To stop
putting fields in a fieldset, define an empty fieldeset::
# Fieldset 1
I belong to Fieldset 1 = ___
# ...
I don't belong to a Fieldset = ___
Buttons
-------
Buttons come in two versions. One without address, and one with. If there's no
address, the button POSTs to the current url. If there is an url, the button
POSTs the form the the given url.
For example::
[Submit to current URL]
[Submit to another URL](http://my-post-address.com)
You'll notice that this looks just like a Markdown link.
Available Fields
----------------
Textfield
~~~~~~~~~
A textfield consists of exactly three underscores::
I'm a textfield = ___
If the textfield is limited in length, the length can be given::
I'm a limited textfield = ___[50]
The length of such textfields is validated.
Textarea
~~~~~~~~
A textarea has no limit and consists of exactly three dots::
I'm a textarea = ...
Optionally, the number of rows can be passed to the field. This changes the
way the textarea looks, not the way it acts::
I'm a textarea with 10 rows = ...[10]
Password
~~~~~~~~
A password field consists of exactly three stars::
I'm a password = ***
Radio Buttons
~~~~~~~~~~~~~
Radio button fields consist of x radio buttons, out of which one may be
preselected::
Gender = ( ) Female ( ) Male (x) I don't want to say
To improve readability, radio buttons may be listed on multiple lines, as
long as they are properly indented::
Gender = ( ) Female
( ) Male
(x) I don't want to say
Radio buttons also have the ability to define optional form parts. Those
parts are only shown if a question was answered a certain way.
Form parts are properly nested if they lign up with the label above them.
For example::
Delivery Method = ( ) Pickup
Pickup Time = ___
(x) Address
Street * = ___
Town * = ___
Here, the street and the town only need to be provided, if the delivery method
is 'Address'. If the user selects a different option, the fields are not
shown and they will not be required.
On the other hand, if 'Pickup' is selected, the 'Pickup Time' needs to be
filled out and the address options are hidden.
This kind of nesting may continue ad infinitum. Meaning you can nest radio
buttons as deeply as you like. Note however, that this is discouraged and that
your users will not be too happy if you present them with a deeply nested
form.
More than one level of nesting is a clear indicator that your form is too
complex.
Checkboxes
~~~~~~~~~~
Checkboxes work exactly like radio buttons, just that you can select
multiple fields::
Extras = [x] Phone insurance
[ ] Phone case
[x] Extra battery
Just like radiobuttons, checkboxes may be nested to created dependencies::
Additional toppings = [ ] Salami
[ ] Olives
[ ] Other
Description = ___
Custom Fields
~~~~~~~~~~~~~
Custom fields are fields for which there's no special syntax, but which have
a specialized function.
For example::
E-Mail = /E-Mail
Stripe = /Stripe
Social Security Number = /Social-Security-Number
The availability of these fields depends on how onegov.form is used. The idea
is for external packages to define their own custom fields.
As of this writing there are no custom fields.
"""
from onegov.form.compat import unicode_characters
from pyparsing import (
col,
Expand Down Expand Up @@ -110,7 +293,8 @@ def mark_enclosed_in(characters):
def textfield():
""" Returns a textfield parser.
Example:
Example::
____[50]
The number defines the maximum length.
Expand All @@ -127,7 +311,7 @@ def textfield():
def textarea():
""" Returns a textarea parser.
Example:
Example::
...[5]
Expand All @@ -146,7 +330,8 @@ def textarea():
def password():
""" Returns a password field parser.
Example:
Example::
***
"""
Expand All @@ -163,7 +348,8 @@ def init(self, string, line, tokens):
def marker_box(characters, indent_stack=None):
""" Returns a marker box:
Example:
Example::
(x) Male
[x] Female
{x} What?
Expand All @@ -184,7 +370,8 @@ def marker_box(characters, indent_stack=None):
def radios():
""" Returns a radio buttons parser.
Example:
Example::
( ) Male (x) Female ( ) Space Alien
"""

Expand All @@ -194,7 +381,8 @@ def radios():
def checkboxes():
""" Returns a check boxes parser.
Example:
Example::
[] Android [x] iPhone [x] Dumb Phone
"""
Expand All @@ -207,7 +395,8 @@ def checkboxes():
def custom():
""" Returns a custom field parser.
Examples:
Examples::
/E-Mail
/Stripe
Expand All @@ -225,7 +414,8 @@ def custom():
def button():
""" Returns a buttons parser.
Examples:
Examples::
[Send]
[Send](http://my-post-address.com)
Expand All @@ -249,7 +439,7 @@ def button():

def fieldset_title():
""" A fieldset title parser. Fieldset titles are just like headings in
markdown:
markdown::
# My header
Expand All @@ -270,7 +460,8 @@ def fieldset_title():
def field_identifier():
""" Returns a field identifier parser:
Example:
Example::
My field *
"""
Expand Down

0 comments on commit 610e42e

Please sign in to comment.