Overview
********


Philosophy
==========

flatland’s design stems from a few basic tenets:

   * All input is suspect

   * Input can come from multiple sources and interfaces

   * Bad input isn’t exceptional: it is expected

With flatland, you describe exactly what elements your form may
contain. Forms extract and process only their known elements out of
the "(key, value)" input data.  Unexpected or malicious data will not
be processed.

The description of forms and their fields is data-centric rather than
HTML or interface-centric.  In a flatland form schema, a password
input field is simply a string, not a “PasswordInput” or the like. The
decision about how to represent that field is left up to another layer
entirely.  Maybe you do want an "<input type="password">" control, or
maybe "<input type="hidden">" in some cases, or sometimes the data is
coming in as JSON.  flatland can act as another type of M in your
M/VC, MC, MVC or MTV.

Humans are imperfect and filling out forms will always be error-prone.
flatland recognizes this and provides features to make error detection
and correction part of the regular workflow of a form.  By default,
validation routines will consider every element of a form and mark all
problematic fields, allowing users to take action on all issues at
once.


Introduction
============

Field schemas define all possible fields the form may contain.  A
schema may a single field, a collection of fields, or an even richer
structure.  Nested mappings and lists of fields are supported, as well
as compound fields and even more exotic types.

   from flatland import Form, String

   class SignInForm(Form):
       username = String
       password = String

Field schemas are long-lived objects similar to class definitions.
The instantiations of a flatland schema are called data elements, a
tree structure of data-holding objects.  The elements of a flatland
form may be initiated blank, using default values, or with values
taken from your objects.

   form = SignInForm.from_flat(request.POST)
   if form.validate():
       logging.info(u"sign-in: %s" % form['username'].value)
       redirect('/app/')
   else:
       render('login.html', form=form)

Elements are rich objects that validate and normalize input data as
well as hold field-level error and warning messages.  Elements can be
exported to a native Python structure, flattened back into Unicode
(key, value) pairs or used as-is in output templates for form layout,
redisplay and error reporting.

   >>> as_regular_python_data = form.value
   >>> type(as_regular_python_data)
   <type 'dict'>
   >>> as_regular_python_data['username']
   u'jek'
   >>> form2 = SignInForm(as_regular_python_data)
   >>> assert form['username'].value == form2['username'].value
