deform documentation - read the docs documentation, release 2.0a2 the preparer of a schema node is...

84
deform Documentation Release 2.0a2 Pylons Developers June 23, 2015

Upload: phungthu

Post on 19-May-2018

224 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform DocumentationRelease 2.0a2

Pylons Developers

June 23, 2015

Page 2: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value
Page 3: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

Contents

1 Topics 31.1 Basic Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Retail Form Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91.3 Common Needs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.4 Deform Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.5 Serialization and Deserialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161.6 Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191.7 Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221.8 Example App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291.9 Using Ajax Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311.10 Internationalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321.11 API Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321.12 Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521.13 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531.14 Deform Change History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541.15 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571.16 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571.17 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571.18 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571.19 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581.20 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581.21 Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581.22 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581.23 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591.24 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621.25 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621.26 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621.27 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621.28 Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621.29 Demo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621.30 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631.31 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631.32 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631.33 Backwards Incompatibilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641.34 Internal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641.35 Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651.36 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651.37 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

i

Page 4: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

1.38 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661.39 Bug Fixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661.40 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661.41 Backwards Incompatibilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

2 Demonstration Site 69

3 Support and Development 71

4 Index and Glossary 73

5 Thanks 75

Python Module Index 77

ii

Page 5: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

deform is a Python HTML form generation library. It runs under Python 2.6, 2.7, 3.2 and 3.3.

The design of deform is heavily influenced by the formish form generation library. Some might even say it’s ashameless rip-off; this would not be completely inaccurate. It differs from formish mostly in ways that make theimplementation (arguably) simpler and smaller.

deform uses Colander as a schema library, Peppercorn as a form control deserialization library, and Chameleon toperform HTML templating.

deform depends only on Peppercorn, Colander, Chameleon and an internationalization library named translation-string, so it may be used in most web frameworks (or antiframeworks) as a result.

Alternate templating languages may be used, as long as all templates are translated from the native Chameleon tem-plates to your templating system of choice and a suitable renderer is supplied to deform.

Warning: Despite the version number at the top, this documentation has not been updated for the 2.X release lineof Deform. Most of the documentation will still apply, but where it does not, see the Deform Change History foran overview of changes between 0.9.9 and this release. Also, please see http://deform2demo.repoze.org .

Contents 1

Page 6: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

2 Contents

Page 7: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

CHAPTER 1

Topics

1.1 Basic Usage

In this chapter, we’ll walk through basic usage of Deform to render a form, and capture and validate input.

The steps a developer must take to cause a form to be renderered and subsequently be ready to accept form submissioninput are:

• Define a schema

• Create a form object.

• Assign non-default widgets to fields in the form (optional).

• Render the form.

Once the form is rendered, a user will interact with the form in his browser, and some point, he will submit it. Whenthe user submits the form, the data provided by the user will either validate properly, or the form will need to bererendered with error markers which help to inform the user of which parts need to be filled in “properly” (as definedby the schema). We allow the user to continue filling in the form, submitting, and revalidating indefinitely.

1.1.1 Defining A Schema

The first step to using Deform is to create a schema which represents the data structure you wish to be captured via aform rendering.

For example, let’s imagine you want to create a form based roughly on a data structure you’ll obtain by reading datafrom a relational database. An example of such a data structure might look something like this:

1 [2 {3 'name':'keith',4 'age':20,5 },6 {7 'name':'fred',8 'age':23,9 },

10 ]

In other words, the database query we make returns a sequence of people; each person is represented by some data.We need to edit this data. There won’t be many people in this list, so we don’t need any sort of paging or batching tomake our way through the list; we can display it all on one form page.

3

Page 8: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Deform designates a structure akin to the example above as an appstruct. The term “appstruct” is shorthand for“application structure”, because it’s the kind of high-level structure that an application usually cares about: the datapresent in an appstruct is useful directly to an application itself.

Note: An appstruct differs from other structures that Deform uses (such as pstruct and cstruct structures): pstructsand cstructs are typically only useful during intermediate parts of the rendering process.

Usually, given some appstruct, you can divine a schema that would allow you to edit the data related to the appstruct.Let’s define a schema which will attempt to serialize this particular appstruct to a form. Our application has theserequirements of the resulting form:

• It must be possible to add and remove a person.

• It must be possible to change any person’s name or age after they’ve been added.

Here’s a schema that will help us meet those requirements:

1 import colander2

3 class Person(colander.MappingSchema):4 name = colander.SchemaNode(colander.String())5 age = colander.SchemaNode(colander.Integer(),6 validator=colander.Range(0, 200))7

8 class People(colander.SequenceSchema):9 person = Person()

10

11 class Schema(colander.MappingSchema):12 people = People()13

14 schema = Schema()

The schemas used by Deform come from a package named Colander. The canonical documentation for Colanderexists at http://docs.pylonsproject.org/projects/colander/dev/ . To compose complex schemas, you’ll need to read it toget comfy with the documentation of the default Colander data types. But for now, we can play it by ear.

For ease of reading, we’ve actually defined three schemas above, but we coalesce them all into a single schemainstance as schema in the last step. A People schema is a collection of Person schema nodes. As the result ofour definitions, a Person represents:

• A name, which must be a string.

• An age, which must be deserializable to an integer; after deserialization happens, a validator ensures that theinteger is between 0 and 200 inclusive.

Schema Node Objects

Note: This section repeats and contextualizes the Colander documentation about schema nodes in order to preventyou from needing to switch away from this page to another while trying to learn about forms. But you can also getmuch the same information at http://docs.pylonsproject.org/projects/colander/dev/

A schema is composed of one or more schema node objects, each typically of the class colander.SchemaNode,usually in a nested arrangement. Each schema node object has a required type, an optional preparer for adjusting dataafter deserialization, an optional validator for deserialized prepared data, an optional default, an optional missing, anoptional title, an optional description, and a slightly less optional name. It also accepts arbitrary keyword arguments,which are attached directly as attributes to the node instance.

The type of a schema node indicates its data type (such as colander.Int or colander.String).

4 Chapter 1. Topics

Page 9: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value forvalidation. Examples would be to prepend schemes that may be missing on url values or to filter html provided by arich text editor. A preparer is not called during serialization, only during deserialization.

The validator of a schema node is called after deserialization and preparation ; it makes sure the value matches aconstraint. An example of such a validator is provided in the schema above: validator=colander.Range(0,200). A validator is not called after schema node serialization, only after node deserialization.

The default of a schema node indicates the value to be serialized if a value for the schema node is not found in theinput data during serialization. It should be the deserialized representation.

The missing of a schema node indicates the value to be deserialized if a value for the schema node is not found inthe input data during deserialization. It should be the deserialized representation. If a schema node does not have amissing value, a colander.Invalid exception will be raised if the data structure being deserialized does notcontain a matching value.

The name of a schema node is used to relate schema nodes to each other. It is also used as the title if a title is notprovided.

The title of a schema node is metadata about a schema node. It shows up in the legend above the form field(s) relatedto the schema node. By default, it is a capitalization of the name.

The description of a schema node is metadata about a schema node. It shows up as a tooltip when someone hoversover the form control(s) related to a field. By default, it is empty.

The name of a schema node that is introduced as a class-level attribute of a colander.MappingSchema,colander.TupleSchema or a colander.SequenceSchema is its class attribute name. For example:

1 import colander2

3 class Phone(colander.MappingSchema):4 location = colander.SchemaNode(colander.String(),5 validator=colander.OneOf(['home','work']))6 number = colander.SchemaNode(colander.String())

The name of the schema node defined via location = colander.SchemaNode(..) within the schema aboveis location. The title of the same schema node is Location.

Schema Objects

In the examples above, if you’ve been paying attention, you’ll have noticed that we’re defining classes whichsubclass from colander.MappingSchema, and colander.SequenceSchema. It’s turtles all the waydown: the result of creating an instance of any of colander.MappingSchema, colander.TupleSchemaor colander.SequenceSchema object is also a colander.SchemaNode object.

Instantiating a colander.MappingSchema creates a schema node which has a type value ofcolander.Mapping.

Instantiating a colander.TupleSchema creates a schema node which has a type value of colander.Tuple.

Instantiating a colander.SequenceSchema creates a schema node which has a type value ofcolander.Sequence.

Creating Schemas Without Using a Class Statement (Imperatively)

See http://docs.pylonsproject.org/projects/colander/dev/basics.html#defining-a-schema-imperatively for informationabout how to create schemas without using a class statement.

1.1. Basic Usage 5

Page 10: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Creating a schema with or without class statements is purely a style decision; the outcome of creating a schemawithout class statements is the same as creating one with class statements.

1.1.2 Rendering a Form

Earlier we defined a schema:

1 import colander2

3 class Person(colander.MappingSchema):4 name = colander.SchemaNode(colander.String())5 age = colander.SchemaNode(colander.Integer(),6 validator=colander.Range(0, 200))7

8 class People(colander.SequenceSchema):9 person = Person()

10

11 class Schema(colander.MappingSchema):12 people = People()13

14 schema = Schema()

Let’s now use this schema to create, render and validate a form.

Creating a Form Object

To create a form object, we do this:

1 from deform import Form2 myform = Form(schema, buttons=('submit',))

We used the schema object (an instance of colander.MappingSchema) we created in the previous section asthe first positional parameter to the deform.Form class; we passed the value (’submit’,) as the value of thebuttons keyword argument. This will cause a single submit input element labeled Submit to be injected at thebottom of the form rendering. We chose to pass in the button names as a sequence of strings, but we could have alsopassed a sequence of instances of the deform.Button class. Either is permissible.

Note that the first positional argument to deform.Form must be a schema node representing a mapping object (astructure which maps a key to a value). We satisfied this constraint above by passing our schema object, whichwe obtained via the colander.MappingSchema constructor, as the schema argument to the deform.Formconstructor

Although different kinds of schema nodes can be present in a schema used by a Deform deform.Form instance, aform instance cannot deal with a schema node representing a sequence, a tuple schema, a string, an integer, etc. as thevalue of its schema parameter; only a schema node representing a mapping is permissible. This typically means thatthe object passed as the schema argument to a deform.Form constructor must be obtained as the result of usingthe colander.MappingSchema constructor (or the equivalent imperative spelling).

Rendering the Form

Once we’ve created a Form object, we can render it without issue by calling the deform.Field.render()method: the deform.Form class is a subclass of the deform.Field class, so this method is available to adeform.Form instance.

If we wanted to render an “add” form (a form without initial data), we’d just omit the appstruct while callingdeform.Field.render().

6 Chapter 1. Topics

Page 11: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

form = myform.render()

If we have some existing data already that we’d like to edit using the form (the form is an “edit form” as opposed toan “add form”). That data might look like this:

1 appstruct = [2 {3 'name':'keith',4 'age':20,5 },6 {7 'name':'fred',8 'age':23,9 },

10 ]

To inject it into the serialized form as the data to be edited, we’d pass it in to the deform.Field.render()method to get a form rendering:

form = myform.render(appstruct)

If, finally, instead we wanted to render a “read-only” variant of an edit form using the same appstruct, we’d pass thereadonly flag as True to the deform.Field.render() method.

form = myform.render(appstruct, readonly=True)

This would cause a page to be rendered in a crude form without any form controls, so the user it’s presented to cannotedit it.

Once any of the above statements runs, the form variable is now a Unicode object containing an HTML rendering ofthe edit form, useful for serving out to a browser. The root tag of the rendering will be the <form> tag representingthis form (or at least a <div> tag that contains this form tag), so the application using it will need to wrap it in HTML<html> and <body> tags as necessary. It will need to be inserted as “structure” without any HTML escaping.

Serving up the Rendered Form

We now have an HTML rendering of a form as the variable named form. But before we can serve it up successfullyto a browser user, we have to make sure that static resources used by Deform can be resolved properly. Some Deformwidgets (including at least one we’ve implied in our sample schema) require access to static resources such as imagesvia HTTP.

For these widgets to work properly, we’ll need to arrange that files in the directory named static within thedeform package can be resolved via a URL which lives at the same hostname and port number as the pagewhich serves up the form itself. For example, the URL /static/css/form.css should be willing to returnthe form.css CSS file in the static/css directory in the deform package as text/css content and return/static/scripts/deform.js as‘‘text/javascript‘‘ content. How you arrange to do this is dependent on yourweb framework. It’s done in pyramid imperative configuration via:

config = Configurator(...)...config.add_static_view('static', 'deform:static')...

Your web framework will use a different mechanism to offer up static files.

Some of the more important files in the set of JavaScript, CSS files, and images present in the static directory ofthe deform package are the following:

1.1. Basic Usage 7

Page 12: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

static/scripts/jquery-2.0.3.min.js A local copy of the JQuery javascript library, used by widgets andother JavaScript files.

static/scripts/deform.js A JavaScript library which should be loaded by any template which injects arendered Deform form.

static/css/form.css CSS related to form element renderings.

Each of these libraries should be included in the <head> tag of a page which renders a Deform form, e.g.:

1 <head>2 <title>3 Deform Demo Site4 </title>5 <!-- Meta Tags -->6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />7 <!-- CSS -->8 <link rel="stylesheet" href="/static/css/form.css" type="text/css" />9 <!-- JavaScript -->

10 <script type="text/javascript"11 src="/static/scripts/jquery-2.0.3.min.js"></script>12 <script type="text/javascript"13 src="/static/scripts/deform.js"></script>14 </head>

The deform.field.get_widget_resources() method can be used to tell you which static directory-relative files are required by a particular form rendering, so that you can inject only the ones necessary into the pagerendering.

The JavaScript function deform.load() must be called by the HTML page (usually in a script tag near the endof the page, ala <script..>deform.load()</script>) which renders a Deform form in order for widgetswhich use JavaScript to do proper event and behavior binding. If this function is not called, built-in widgets which useJavaScript will not function properly. For example, you might include this within the body of the rendered page nearits end:

1 <script type="text/javascript">2 deform.load()3 </script>

As above, the head should also contain a <meta> tag which names a utf-8 charset in a Content-Type http-equiv.This is a sane setting for most systems.

1.1.3 Validating a Form Submission

Once the user seen the form and has chewed on its inputs a bit, he will eventually submit the form. When he submitsit, the logic you use to deal with the form validation must do a few things:

• It must detect that a submit button was clicked.

• It must obtain the list of form controls from the form POST data.

• It must call the deform.Form.validate() method with the list of form controls.

• It must be willing to catch a deform.ValidationFailure exception and rerender the form if there werevalidation errors.

For example, using the WebOb API for the above tasks, and the form object we created earlier, such a dance mightlook like this:

8 Chapter 1. Topics

Page 13: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1 if 'submit' in request.POST: # detect that the submit button was clicked2

3 controls = request.POST.items() # get the form controls4

5 try:6 appstruct = myform.validate(controls) # call validate7 except ValidationFailure, e: # catch the exception8 return {'form':e.render()} # re-render the form with an exception9

10 # the form submission succeeded, we have the data11 return {'form':None, 'appstruct':appstruct}

The above set of statements is the sort of logic every web app that uses Deform must do. If the validation stage doesnot fail, a variable named appstruct will exist with the data serialized from the form to be used in your application.Otherwise the form will be rerendered.

Note that by default, when any form submit button is clicked, the form will send a post request to the same URL whichrendered the form. This can be changed by passing a different action to the deform.Form constructor.

1.1.4 Seeing it In Action

To see an “add form” in action that follows the schema in this chapter, visithttp://deform2demo.repoze.org/sequence_of_mappings/.

To see a “readonly edit form” in action that follows the schema in this chapter, visithttp://deform2demo.repoze.org/readonly_sequence_of_mappings/

The application at http://deform2demo.repoze.org is a pyramid application which demonstrates most of the featuresof Deform, including most of the widget and data types available for use within an application that uses Deform.

1.2 Retail Form Rendering

In the previous chapter we demonstrated how to use Deform to render a complete form, including the input fields, thebuttons, and so forth. We used the deform.Field.render() method, and injected the resulting HTML snippetinto a larger HTML page in our application. That is an effective and quick way to put a form on a page, but sometimesyou need more fine-grained control over the way form HTML is rendered. For example, you may need form elementsto be placed on the page side-by-side or you might need the form’s styling to be radically different than the formstyling used by the default rendering of Deform forms. Often it’s easier to use Deform slightly differently, where youdo more work yourself to draw the form within a template, and only use Deform for some of its features. We refer tothis as “retail form rendering”.

Note: This feature is new as of Deform 0.9.6.

1.2.1 A Basic Example

Our schema and form object:

1 import colander2

3 class Person(colander.MappingSchema):4 name = colander.SchemaNode(colander.String())5 age = colander.SchemaNode(colander.Integer(),6 validator=colander.Range(0, 200))

1.2. Retail Form Rendering 9

Page 14: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

7

8 schema = Person()9 form = deform.Form(schema, resource_registry=resource_registry)

We feed the schema into a template as the form value. It doesn’t matter what kind of templating system you use todo this, but this example will use ZPT. Below, the name form refers to the form we just created above:

<div class="row"tal:repeat="field form">

<div class="span2">${structure:field.title}<span class="req" tal:condition="field.required">*</span>

</div><div class="span2">

${structure:field.serialize()}</div><ul tal:condition="field.error">

<li tal:repeat="error field.error.messages()">${structure:error}

</li></ul>

</div>

The above template iterates over the fields in the form, using the attributes of each field to draw the title.

You can use the __getitem__ method of a form to grab named form fields instead of iterating over all of its fields.For example:

<div tal:define="field form['name']"><div class="span2">

${structure:field.title}<span class="req" tal:condition="field.required">*</span>

</div><div class="span2">

${structure:field.serialize()}</div><ul tal:condition="field.error">

<li tal:repeat="error field.error.messages()">${structure:error}

</li></ul>

</div>

You can use as little or as much of the Deform Field API to draw the widget as you like. The above examples usethe deform.Field.serialize() method, which is an easy way to let Deform draw the field HTML, but youcan draw it yourself instead if you like, and just rely on the field object for its validation errors (if any). Note that theserialize method accepts arbitrary keyword arguments that will be passed as top-level arguments to the Deformwidget templates, so if you need to change how a particular widget is rendered without doing things completely byhand, you may want to take a look at the existing widget template and see if your need has been anticipated.

In the POST handler for the form, just do things like we did in the last chapter, except if validation fails, just re-renderthe template with the same form object.

controls = request.POST.items() # get the form controls

try:appstruct = form.validate(controls) # call validate

except ValidationFailure as e: # catch the exception# .. rerender the form .. its field's .error attributes

10 Chapter 1. Topics

Page 15: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

# will be set

It is also possible to pass an appstruct argument to the deform.Form constructor to create “edit forms”.Form/field objects are initialized with this appstruct (recursively) when they’re created. This means that accessingform.cstruct will return the current set of rendering values. This value is reset during validation, so after avalidation is done you can re-render the form to show validation errors.

Note that existing Deform widgets are all built using “retail mode” APIs, so if you need examples, you can look attheir templates.

Other methods that might be useful during retail form rendering are:

• deform.Field.__contains__()

• deform.Field.start_mapping()

• deform.Field.end_mapping()

• deform.Field.start_sequence()

• deform.Field.end_sequence()

• deform.Field.start_rename()

• deform.Field.end_rename()

• deform.Field.set_appstruct()

• deform.Field.set_pstruct()

• deform.Field.render_template()

• deform.Field.validate_pstruct() (and the subcontrol argument todeform.Field.validate())

1.3 Common Needs

This chapter collects solutions for requirements that will often crop up once you start using Deform for real worldapplications.

1.3.1 Changing the Default Widget Associated With a Field

Let’s take another look at our familiar schema:

1 import colander2

3 class Person(colander.MappingSchema):4 name = colander.SchemaNode(colander.String())5 age = colander.SchemaNode(colander.Integer(),6 validator=colander.Range(0, 200))7

8 class People(colander.SequenceSchema):9 person = Person()

10

11 class Schema(colander.MappingSchema):12 people = People()13

14 schema = Schema()

1.3. Common Needs 11

Page 16: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

This schema renders as a sequence of mapping objects. Each mapping has two leaf nodes in it: a string and aninteger. If you play around with the demo at http://deform2demo.repoze.org/sequence_of_mappings/ you’ll noticethat, although we don’t actually specify a particular kind of widget for each of these fields, a sensible default widget isused. This is true of each of the default types in Colander. Here is how they are mapped by default. In the followinglist, the schema type which is the header uses the widget underneath it by default.

colander.Mapping deform.widget.MappingWidget

colander.Sequence deform.widget.SequenceWidget

colander.String deform.widget.TextInputWidget

colander.Integer deform.widget.TextInputWidget

colander.Float deform.widget.TextInputWidget

colander.Decimal deform.widget.TextInputWidget

colander.Boolean deform.widget.CheckboxWidget

colander.Date deform.widget.DateInputWidget

colander.DateTime deform.widget.DateTimeInputWidget

colander.Tuple deform.widget.Widget

Note: Not just any widget can be used with any schema type; the documentation for each widget usually indicateswhat type it can be used against successfully. If all existing widgets provided by Deform are insufficient, you can usea custom widget. See Writing Your Own Widget for more information about writing a custom widget.

If you are creating a schema that contains a type which is not in this list, or if you’d like to use a different widget for aparticular field, or you want to change the settings of the default widget associated with the type, you need to associatethe field with the widget “by hand”. There are a number of ways to do so, as outlined in the sections below.

As an argument to a colander.SchemaNode constructor

As of Deform 0.8, you may specify the widget as part of the schema:

1 import colander2

3 from deform import Form4 from deform.widget import TextInputWidget5

6 class Person(colander.MappingSchema):7 name = colander.SchemaNode(colander.String(),8 widget=TextAreaWidget())9 age = colander.SchemaNode(colander.Integer(),

10 validator=colander.Range(0, 200))11

12 class People(colander.SequenceSchema):13 person = Person()14

15 class Schema(colander.MappingSchema):16 people = People()17

18 schema = Schema()19

20 myform = Form(schema, buttons=('submit',))

12 Chapter 1. Topics

Page 17: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Note above that we passed a widget argument to the name schema node in the Person class above. When a schemacontaining a node with a widget argument to a schema node is rendered by Deform, the widget specified in the nodeconstructor is used as the widget which should be associated with that node’s form rendering. In this case, we’ll beusing a deform.widget.TextAreaWidget as the name widget.

Note: Widget associations done in a schema are always overridden by explicit widget assignments performed viadeform.Field.__setitem__() and deform.Field.set_widgets().

Using dictionary access to change the widget

After the deform.Form constructor is called with the schema you can change the widget used for a particular fieldby using dictionary access to get to the field in question. A deform.Form is just another kind of deform.Field,so the method works for either kind of object. For example:

1 from deform import Form2 from deform.widget import TextInputWidget3

4 myform = Form(schema, buttons=('submit',))5 myform['people']['person']['name'].widget = TextInputWidget(size=10)

This associates the String field named name in the rendered form with an explicitly createddeform.widget.TextInputWidget by finding the name field via a series of __getitem__ callsthrough the field structure, then by assigning an explicit widget attribute to the name field.

You might want to do this in order to pass a size argument to the explicit widget creation, indicating that the size ofthe name input field should be 10em rather than the default.

Although in the example above, we associated the name field with the same type of widget as its default we couldhave just as easily associated the name field with a completely different widget using the same pattern. For example:

1 from deform import Form2 from deform.widget import TextInputWidget3

4 myform = Form(schema, buttons=('submit',))5 myform['people']['person']['name'].widget = TextAreaWidget()

The above renders an HTML textarea input element for the name field instead of an input type=text field.This probably doesn’t make much sense for a field called name (names aren’t usually multiline paragraphs); but itdoes let us demonstrate how different widgets can be used for the same field.

Using the deform.Field.set_widgets() method

Equivalently, you can also use the deform.Field.set_widgets() method to associate multiple widgets withmultiple fields in a form. For example:

1 from deform import Form2 from deform.widget import TextInputWidget3

4 myform = Form(schema, buttons=('submit',))5 myform.set_widgets({'people.person.name':TextAreaWidget(),6 'people.person.age':TextAreaWidget()})

Each key in the dictionary passed to deform.Field.set_widgets() is a “dotted name” which resolves to asingle field element. Each value in the dictionary is a widget instance. See deform.Field.set_widgets() formore information about this method and dotted name resolution, including special cases which involve the “splat” (*)character and the empty string as a key name.

1.3. Common Needs 13

Page 18: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.3.2 Using Text Input Masks

The deform.widget.TextInputWidget and deform.widget.CheckedInputWidget widgets allowfor the use of a fixed-length text input mask. Use of a text input mask causes placeholder text to be placed in thetext field input, and restricts the type and length of the characters input into the text field.

For example:

When using a text input mask:

a represents an alpha character (A-Z,a-z)

9 represents a numeric character (0-9)

* represents an alphanumeric character (A-Z,a-z,0-9)

All other characters in the mask will be considered mask literals.

By default the placeholder text for non-literal characters in the field will be _ (the underscore character). To changethis for a given input field, use the mask_placeholder argument to the TextInputWidget:

form['date'].widget = TextInputWidget(mask='99/99/9999',mask_placeholder="-")

Example masks:

Date 99/99/9999

US Phone

999. 999-9999

US SSN 999-99-9999

When this option is used, the jquery.maskedinput library must be loaded into the page serving the form for the maskargument to have any effect. A copy of this library is available in the static/scripts directory of the deformpackage itself.

See http://deform2demo.repoze.org/text_input_masks/ for a working example.

Use of a text input mask is not a replacement for server-side validation of the field; it is purely a UI affordance. If thedata must be checked at input time a separate validator should be attached to the related schema node.

1.3.3 Using the AutocompleteInputWidget

The deform.widget.AutocompleteInputWidget widget allows for client side autocompletion from pro-vided choices in a text input field. To use this you MUST ensure that jQuery and the JQuery UI plugin are availableto the page where the deform.widget.AutocompleteInputWidget widget is rendered.

For convenience a version of the JQuery UI (which includes the autocomplete sublibrary) is included in thedeform static directory. Additionally, the JQuery UI styles for the selection box are also included in the deformstatic directory. See Serving up the Rendered Form and The (High-Level) deform.Field.get_widget_resources()Method for more information about using the included libraries from your application.

A very simple example of using deform.widget.AutocompleteInputWidget follows:

form['frozznobs'].widget = AutocompleteInputWidget(values=['spam', 'eggs', 'bar', 'baz'])

Instead of a list of values a URL can be provided to values:

form['frobsnozz'].widget = AutocompleteInputWidget(values='http://example.com/someapi')

14 Chapter 1. Topics

Page 19: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

In the above case a call to the url should provide results in a JSON-compatible format or JSONP-compatible responseif on a different host than the application. Something like either of these structures in JSON are suitable:

//Items are used as both value and label['item-one', 'item-two', 'item-three']

//Separate values and labels[

{'value': 'item-one', 'label': 'Item One'},{'value': 'item-two', 'label': 'Item Two'},{'value': 'item-three', 'label': 'Item Three'}

]

The autocomplete plugin will add a query string to the request URL with the variable term which contains the user’sinput at that moment. The server may use this to filter the returned results.

For more information, see http://api.jqueryui.com/autocomplete/#option-source - specifically, the section concerningthe String type for the source option.

Some options for the jquery.autocomplete plugin are mapped and can be passed to the widget. Seedeform.widget.AutocompleteInputWidget for details regarding the available options. Passing optionslooks like:

form['nobsfrozz'].widget = AutocompleteInputWidget(values=['spam, 'eggs', 'bar', 'baz'],min_length=1)

See http://deform2demo.repoze.org/autocomplete_input/ and http://deform2demo.repoze.org/autocomplete_remote_input/for working examples. A working example of a remote URL providing completion data can be found athttp://deform2demo.repoze.org/autocomplete_input_values/.

Use of deform.widget.AutocompleteInputWidget is not a replacement for server-side validation of thefield; it is purely a UI affordance. If the data must be checked at input time a separate validator should be attached tothe related schema node.

1.3.4 Creating a New Schema Type

Sometimes the default schema types offered by Colander may not be sufficient to model all the structures in yourapplication.

If this happens, refer to the Colander documentation on Defining a New Type.

1.4 Deform Components

A developer dealing with Deform has to understand a few fundamental types of objects and their relationships to oneanother. These types are:

• schema nodes

• field objects

• widgets

1.4.1 The Relationship Between Widgets, Fields, and Schema Objects

The relationship between widgets, fields, and schema node objects is as follows:

1.4. Deform Components 15

Page 20: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• A schema is created by a developer. It is a collection of schema node objects.

• When a root schema node is passed to the deform.Form constructor, the result is a field object. For each nodedefined by the developer in the schema recursively, a corresponding field is created.

• Each field in the resulting field tree has a default widget type. If the widget attribute of a field object isnot set directly by the developer, a property is used to create an instance of the default widget type whenfield.widget is first requested. Sane defaults for each schema type typically exist; if a sane default cannotbe found, the deform.widget.TextInputWidget widget is used.

Note: The Colander documentation is a resource useful to Deform developers. In particular, it details how a schema iscreated and used. Deform schemas are Colander schemas. The Colander documentation about how they work appliesto creating Deform schemas as well.

A widget is related to one or more schema node type objects. For example, a notional “TextInputWidget” may beresponsible for serializing textual data related to a schema node which has colander.String as its type into atext input control, while a notional “MappingWidget” might be responsible for serializing a colander.Mappingobject into a sequence of controls. In both cases, the data type being serialized is related to the schema node type towhich the widget is related.

A widget has a relationship to a schema node via a field object. A field object has a reference to both a widget and aschema node. These relationships look like this:

field object (``field``)|||----- widget object (``field.widget``)||\----- schema node object (``field.schema``)

1.5 Serialization and Deserialization

Serialization is the act of converting application data into a form rendering. Deserialization is the act of convertingdata resulting from a form submission into application data.

1.5.1 Serialization

Serialization is what happens when you ask Deform to render a form given a schema. Here’s a high-level overview ofwhat happens when you ask Deform to do this:

• For each schema node in the schema provided by the application developer, Deform creates a field. This happensrecursively for each node in the schema. As a result, a tree of fields is created, mirroring the nodes in the schema.

• Each field object created as a result of the prior step knows about its associated schema node (it has afield.schema attribute); each field also knows about an associated widget object (it has a field.widgetattribute). This widget object may be a default widget based on the schema node type or it might be overriddenby the application developer for a particular rendering.

• Deform passes an appstruct to the root schema node’s serializemethod to obtain a cstruct. The root schemanode is responsible for consulting its children nodes during this process to serialilize the entirety of the data intoa single cstruct.

16 Chapter 1. Topics

Page 21: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• Deform passes the resulting cstruct to the root widget object’s serialize method to generate an HTMLform rendering. The root widget object is responsible for consulting its children nodes during this process toserialilize the entirety of the data into an HTML form.

If you were to attempt to produce a high-level overview diagram this process, it might look like this:

appstruct -> cstruct -> form| |v v

schema widget

Peppercorn Structure Markers

You’ll see the default deform widget “serializations” (form renderings) make use of Peppercorn structure markers.

Peppercorn is a library that is used by Deform; it allows Deform to treat the form controls in an HTML form submissionas a stream instead of a flat mapping of name to value. To do so, it uses hidden form elements to denote structure.

Peppercorn structure markers come in pairs which have a begin token and an end token. For example, a given formrendering might have a part that looks like so:

1 <html>2 ...3 <input type="hidden" name="__start__" value="date:mapping"/>4 <input name="day"/>5 <input name="month"/>6 <input name="year"/>7 <input type="hidden" name="__end__"/>8 ...9 </html>

The above example shows an example of a pair of peppercorn structure markers which begin and end a mapping. Theexample uses this pair to means that a the widget related to the date node in the schema will be be passed a pstructthat is a dictionary with multiple values during deserialization: the dictionary will include the keys day , month, andyear, and the values will be the values provided by the person interacting with the related form controls.

Other uses of Peppercorn structure markers include: a “confirm password” widget can render a peppercorn mappingwith two text inputs in it, a “mapping widget” can serve as a substructure for a fieldset. Basically, Peppercorn makes itmore pleasant to deal with form submission data by pre-converting the data from a flat mapping into a set of mappings,sequences, and strings during deserialization.

However, if a widget doesn’t want to do anything fancy and a particular widget is completely equivalent to one formcontrol, it doesn’t need to use any Peppercorn structure markers in its rendering.

Note: See the Peppercorn documentation for more information about using peppercorn structure markers in HTML.

1.5.2 Deserialization

High-level overview of how “deserialization” (converting form control data resulting from a form submission to ap-plication data) works:

• For each schema node in the schema provided by the application developer, Deform creates a field. This happensrecursively for each node in the schema. As a result, a tree of fields is created, mirroring the nodes in the schema.

• Each field object created as a result of the prior step knows about its associated schema node (it has afield.schema attribute); each field also knows about an associated widget object (it has a field.widget

1.5. Serialization and Deserialization 17

Page 22: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

attribute). This widget object may be a default widget based on the schema node type or it might be overriddenby the application developer for a particular rendering.

• Deform passes a set of form controls to the parse method of Peppercorn in order to obtain a pstruct.

• Deform passes the resulting pstruct to the root widget node’s deserialize method in order to generate acstruct.

• Deform passes the resulting cstruct to the root schema node’s deserialize method to generate an appstruct.This may result in a validation error. If a validation error occurs, the form may be rerendered with error markersin place.

If you were to attempt to produce a high-level overview diagram this process, it might look like this:

formcontrols -> pstruct -> cstruct -> appstruct| | |v v v

peppercorn widget schema

When a user presses the submit button on any Deform form, Deform itself runs the resulting form controls through thepeppercorn.parse method. This converts the form data into a mapping. The structure markers in the form dataindicate the internal structure of the mapping.

For example, if the form submitted had the following data:

1 <html>2 ...3 <input type="hidden" name="__start__" value="date:mapping"/>4 <input name="day"/>5 <input name="month"/>6 <input name="year"/>7 <input type="hidden" name="__end__"/>8 ...9 </html>

There would be a date key in the root of the pstruct mapping which held three keys: day, month, and year.

Note: See the Peppercorn documentation for more information about the result of the peppercorn.parsemethodand how it relates to form control data.

The bits of code that are “closest” to the browser are called “widgets”. A chapter about creating widgets exists in thisdocumentation at Writing Your Own Widget.

A widget has a deserialize method. The deserialize method is passed a structure (a pstruct) which is shorthandfor “Peppercorn structure”. A pstruct might be a string, it might be a mapping, or it might be a sequence, dependingon the output of peppercorn.parse related to its schema node against the form control data.

The job of the deserialize method of a widget is to convert the pstruct it receives into a cstruct. A cstruct is a shorthandfor “Colander structure”. It is often a string, a mapping or a sequence.

An application eventually wants to deal in types less primitive than strings: a model instance or a datetime object.An appstruct is the data that an application that uses Deform eventually wants to deal in. Therefore, once a widgethas turned a pstruct into a cstruct, the schema node related to that widget is responsible for converting that cstruct toan appstruct. A schema node possesses its very own deserialize method, which is responsible for accepting acstruct and returning an appstruct.

18 Chapter 1. Topics

Page 23: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Raising Errors During Deserialization

If a widget determines that a pstruct value cannot be converted successfully to a cstruct value during deserialization, itmay raise an colander.Invalid exception.

When it raises this exception, it can use the field object as a “scratchpad” to hold on to other data, but it must pass avalue attribute to the exception constructor. For example:

1 import colander2

3 def serialize(self, field, cstruct, readonly=False):4 if cstruct is colander.null:5 cstruct = ''6 confirm = getattr(field, 'confirm', '')7 template = readonly and self.readonly_template or self.template8 return field.renderer(template, field=field, cstruct=cstruct,9 confirm=confirm, subject=self.subject,

10 confirm_subject=self.confirm_subject,11 )12

13 def deserialize(self, field, pstruct):14 if pstruct is colander.null:15 return colander.null16 value = pstruct.get('value') or ''17 confirm = pstruct.get('confirm') or ''18 field.confirm = confirm19 if value != confirm:20 raise Invalid(field.schema, self.mismatch_message, value)21 return value

The schema type associated with this widget is expecting a single string as its cstruct. The value passed to theexception constructor raised during the deserialize when value != confirm is used as that cstruct valuewhen the form is rerendered with error markers. The confirm value is picked off the field value when the form isrerendered at this time.

1.5.3 Say What?

Q: “So deform colander and peppercorn are pretty intertwingled?”

A: “Colander and Peppercorn are unrelated; Deform is effectively something that integrates colander and pep-percorn together.”

1.6 Templates

A set of Chameleon templates is used by the default widget set present in deform to make it easier to customize thelook and feel of form renderings.

1.6.1 Overriding the default templates

The default widget set uses templates that live in the templates directory of the deform package. If you arecomfortable using the Chameleon templating system, but you simply need to override some of these templates youcan create your own template directory and copy the template you wish to customize into it. You can then eitherconfigure your new template directory to be used for all forms or for specific forms as described below.

1.6. Templates 19

Page 24: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

For relevant API documentation see the deform.ZPTRendererFactory class and the deform.Field classrenderer argument.

Overriding for all forms

To globally override templates use the deform.Field.set_zpt_renderer() class method to change the set-tings associated with the default ZPT renderer:

from pkg_resources import resource_filenamefrom deform import Form

deform_templates = resource_filename('deform', 'templates')search_path = ('/path/to/my/templates', deform_templates)

Form.set_zpt_renderer(search_path)

Now, the templates in /path/to/my/templates will be used in preference to the default templates whenever aform is rendered. Any number of template directories can be put into the search path and will be searched in the orderspecified with the first matching template found being used.

Overriding for specific forms

If you only want to change the templates used for a specific form, or even for the specific rendering of a form, you canpass a renderer argument to the deform.Form constructor, e.g.:

from deform import ZPTRendererFactoryfrom deform import Formfrom pkg_resources import resource_filename

deform_templates = resource_filename('deform', 'templates')search_path = ('/path/to/my/templates', deform_templates)renderer = ZPTRendererFactory(search_path)

form = Form(someschema, renderer=renderer)

When the above form is rendered, the templates in /path/to/my/templates will be used in preference to thedefault templates. Any number of template directories can be put into the search path and will be searched in the orderspecified with the first matching template found being used.

1.6.2 Using an alternative templating system

A renderer is used by the each widget implementation in deform to render HTML from a set of templates. Bydefault, each of the default Deform widgets uses a template written in the Chameleon ZPT templating language. Ifyou’d rather use a different templating system for your widgets, you can. To do so, you need to:

• Write an alternate renderer that uses the templating system of your choice.

• Optionally, convert all the existing Deform templates to your templating language of choice. This is onlynecessary if you choose to use the widgets that ship as part of Deform.

• Set the default renderer of the deform.Form class.

20 Chapter 1. Topics

Page 25: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Creating a Renderer

A renderer is simply a callable that accepts a single positional argument, which is the template name, and a set ofkeyword arguments. The keyword arguments it will receive are arbitrary, and differ per widget, but the keywordsusually include field, a field object, and cstruct, the data structure related to the field that must be rendered bythe template itself.

Here’s an example of a (naive) renderer that uses the Mako templating engine:

1 from mako.template import Template2

3 def mako_renderer(tmpl_name, **kw):4 template = Template(filename='/template_dir/%s.mak' % tmpl_name)5 return template.render(**kw)

Note: A more robust implementation might use a template loader that does some caching, or it might allow thetemplate directory to be configured.

Note the mako_renderer function we’ve created actually appends a .mak extension to the tmpl_name it ispassed. This is because Deform passes a template name without any extension to allow for different templatingsystems to be used as renderers.

Our mako_renderer renderer is now ready to have some templates created for it.

Converting the Default Deform Templates

The deform package contains a directory named templates. You can see the current trunk contents of this direc-tory by browsing the source repository. Each file within this directory and any of its subdirectories is a ChameleonZPT template that is used by a default Deform widget.

For example, textinput.pt ZPT template, which is used by the deform.widget.TextInputWidget wid-get and which renders a text input control looks like this:

1 <span tal:define="name name|field.name;2 css_class css_class|field.widget.css_class;3 oid oid|field.oid;4 mask mask|field.widget.mask;5 mask_placeholder mask_placeholder|field.widget.mask_placeholder;6 style style|field.widget.style;7 "8 tal:omit-tag="">9 <input type="text" name="${name}" value="${cstruct}"

10 tal:attributes="class string: form-control ${css_class or ''};11 style style"12 id="${oid}"/>13 <script tal:condition="mask" type="text/javascript">14 deform.addCallback(15 '${oid}',16 function (oid) {17 $("#" + oid).mask("${mask}",18 {placeholder:"${mask_placeholder}"});19 });20 </script>21 </span>

If we created a Mako renderer, we would need to create an analogue of this template. Such an analogue should benamed textinput.mak and might look like this:

1.6. Templates 21

Page 26: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1 <input type="text" name="${field.name}" value="${cstruct}"2 % if field.widget.size:3 size=${field.widget.size}4 % endif5 />

Whatever the body of the template looks like, the resulting textinput.mak should be placed in a directory that ismeant to house other Mako template files which are going to be consumed by Deform. You’ll need to convert eachof the templates that exist in the Deform templates directory and its subdirectories, and put all of the resultingtemplates into your private mako templates dir too, retaining any directory structure (e.g., retaining the fact thatthere is a readonly directory and converting its contents).

Configuring Your New Renderer as the Default

Once you’ve created a new renderer and created templates that match all the existing Deform templates, you can nowconfigure your renderer to be used by Deform. In startup code, add something like:

1 from mymakorenderer import mako_renderer2

3 from deform import Form4 Form.set_default_renderer(mako_renderer)

The deform widget system will now use your renderer as the default renderer.

Note that calling deform.Field.set_default_renderer() will cause this renderer to be used by default byall consumers in the process it’s invoked in. This is potentially undesirable: you may need the same process to usemore than one renderer perhaps because that same process houses two different Deform-using systems. In this case,instead of using the set_default_renderer method, you can write your application in such a way that it passesa renderer to the Form constructor:

1 from mymakorenderer import mako_renderer2 from deform import Form3

4 ...5 schema = SomeSchema()6 form = Form(schema, renderer=mako_renderer)

1.7 Widgets

A widget is a bit of code that is willing to:

• serialize a cstruct into HTML for display in a form rendering

• deserialize data obtained from a form post (a pstruct) into a data structure suitable for deserialization by aschema node (a cstruct).

• handle validation errors

Deform ships with a number of built-in widgets. You hopefully needn’t create your own widget unless you’re trying todo something that the built-in widget set didn’t anticipate. However, when a built-in Deform widget doesn’t do exactlywhat you want, you can extend Deform by creating a new widget that is more suitable for the task.

22 Chapter 1. Topics

Page 27: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.7.1 Widget Templates

A widget needn’t use a template file, but each of the built-in widgets does. A template is usually assigned to a defaultwidget via its template and readonly_template attributes; those attributes are then used in the serializemethod of the widget, ala:

1 def serialize(self, field, cstruct, readonly=False):2 if cstruct in (null, None):3 cstruct = ''4 template = readonly and self.readonly_template or self.template5 return field.renderer(template, field=field, cstruct=cstruct)

The deform.field.renderer() method is a method which accepts a logical template name (such astexinput) and renders it using the active Deform renderer; the default renderer is the ZPT renderer, which usesthe templates within the deform/templates directory within the deform package. See Templates for moreinformation about widget templates.

1.7.2 Widget Javascript

Some built-in Deform widgets require JavaScript. In order for the built-in Deform widgets that require JavaScriptto function properly, the deform.load() JavaScript function must be called when the page containing a form isrenderered.

Some built-in Deform widgets include JavaScript which operates against a local input element when it is loaded. Forexample, the deform.widget.AutocompleteInputWidget template looks like this:

1 <span tal:omit-tag="">2 <input type="text"3 name="${field.name}"4 value="${cstruct}"5 tal:attributes="size field.widget.size;6 class field.widget.css_class"7 id="${field.oid}"/>8 <script tal:condition="field.widget.values" type="text/javascript">9 deform.addCallback(

10 '${field.oid}',11 function (oid) {12 $('#' + oid).autocomplete({source: ${values}});13 $('#' + oid).autocomplete("option", ${options});14 }15 );16 </script>17 </span>

field.oid refers to the ordered identifier that Deform gives to each field widget rendering. You can see thatthe script which runs when this widget is included in a rendering calls a function named deform.addCallback,passing it the value of field.oid and a callback function as oid and callback respectively. When it is executed,the callback function calls the autocomplete method of the JQuery selector result for $(’#’ + oid).

The callback define above will be called under two circumstances:

• When the page first loads and the deform.load() JavaScript function is called.

• When a sequence is involved, and a sequence item is added, resulting in a call to thedeform.addSequenceItem() JavaScript function.

The reason that default Deform widgets call deform.addCallback rather than simply using ${field.oid}directly in the rendered script is becase sequence item handling happens entirely client side by cloning an existing

1.7. Widgets 23

Page 28: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

prototype node, and before a sequence item can be added, all of the id attributes in the HTML that makes up thefield must be changed to be unique. The addCallback indirection assures that the callback is executed with themodified oid rather than the protoype node’s oid. Your widgets should do the same if they are meant to be used as partof sequences.

1.7.3 Widget Requirements and Resources

Some widgets require external resources to work properly (such as CSS and Javascript files). Deform provides mech-anisms that will allow you to determine which resources are required by a particular form rendering, so that yourapplication may include them in the HEAD of the page which includes the rendered form.

The (Low-Level) deform.Field.get_widget_requirements() Method

After a form has been fully populated with widgets, the deform.Field.get_widget_requirements()method called on the form object will return a sequence of two-tuples. When a non-empty sequence is returnedby deform.Field.get_widget_requirements(), it means that one or more CSS or JavaScript resourceswill need to be loaded by the page performing the form rendering in order for some widget on the page to functionproperly.

The first element in each two-tuple represents a requirement name. It represents a logical reference to one or moreJavascript or CSS resources. The second element in each two-tuple is the reqested version of the requirement. It maybe None, in which case the version required is unspecified. When the version required is unspecified, a default versionof the resource set will be chosen.

The requirement name / version pair implies a set of resources, but it is not a URL, nor is it a filenameor a filename prefix. The caller of deform.Field.get_widget_requirements() must use the re-source names returned as logical references. For example, if the requirement name is jquery, and theversion id is 1.4.2, the caller can take that to mean that the JQuery library should be loaded withinthe page header via, for example the inclusion of the HTML <script type="text/javascript"src="http://deformdemo.repoze.org/static/scripts/jquery-1.4.2.min.js"></script>within the HEAD tag of the rendered HTML page.

Users will almost certainly prefer to use the deform.Field.get_widget_resources() API (explained inthe succeeding section) to obtain a fully expanded list of relative resource paths required by a form rendering.deform.Field.get_widget_requirements(), however, may be used if custom requirement name to re-source mappings need to be done without the help of a resource registry.

See also the description of requirements in deform.Widget.

The (High-Level) deform.Field.get_widget_resources() Method

A mechanism to resolve the requirements of a form into relative resource filenames exists as a method:deform.Field.get_widget_resources().

Note: Because Deform is framework-agnostic, this method only reports to its caller the resource paths required for asuccessful form rendering, it does not (cannot) arrange for the reported requirements to be satisfied in a page rendering;satisfying these requirements is the responsibility of the calling code.

The deform.Field.get_widget_resources() method returns a dictionary with two keys: js and css.The value related to each key in the dictionary is a list of relative resource names. Each resource name is assumed tobe relative to the static directory which houses your application’s Deform resources (usually a copy of the staticdirectory inside the Deform package). If the method is called with no arguments, it will return a dictionary in the sameform representing resources it believes are required by the current form. If it is called with a set of requirements (the

24 Chapter 1. Topics

Page 29: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

value returned by the deform.Field.get_widget_requirements() method), it will attempt to resolve therequirements passed to it. You might use it like so:

1 import deform2

3 form = deform.Form(someschema)4 resources = form.get_widget_resources()5 js_resources = resources['js']6 css_resources = resources['css']7 js_links = [ 'http://my.static.place/%s' % r for r in js_resources ]8 css_links = [ 'http://my.static.place/%s' % r for r in css_resources ]9 js_tags = ['<script type="text/javascript" src="%s"></script>' % link

10 for link in js_links]11 css_tags = ['<link rel="stylesheet" href="%s"/>' % link12 for link in css_links]13 tags = js_tags + css_tags14 return {'form':form.render(), 'tags':tags}

The template rendering the return value would need to make sense of “tags” (it would inject them whole-sale into the HEAD). Obviously, other strategies for rendering HEAD tags can be devised using the result ofget_widget_resources, this is just an example.

deform.Field.get_widget_resources() uses a resource registry to map requirement names to resourcepaths. If deform.Field.get_widget_resources() cannot resolve a requirement name, or it cannot find aset of resources related to the supplied version of the requirement name, an ValueError will be raised. When thishappens, it means that the resource registry associated with the form cannot resolve a requirement name or version.When this happens, a resource registry that knows about the requirement will need to be associated with the formexplicitly, e.g.:

1 registry = deform.widget.ResourceRegistry()2 registry.set_js_resources('requirement', 'ver', 'bar.js', 'baz.js')3 registry.set_css_resources('requirement', 'ver', 'foo.css', 'baz.css')4

5 form = Form(schema, resource_registry=registry)6 resources = form.get_widget_resources()7 js_resources = resources['js']8 css_resources = resources['css']9 js_links = [ 'http://my.static.place/%s' % r for r in js_resources ]

10 css_links = [ 'http://my.static.place/%s' % r for r in css_resources ]11 js_tags = ['<script type="text/javascript" src="%s"></script>' % link12 for link in js_links]13 css_tags = ['<link type="text/css" href="%s"/>' % link14 for link in css_links]15 tags = js_tags + css_tags16 return {'form':form.render(), 'tags':tags}

An alternate default resource registry can be associated with all forms by calling thedeform.Field.set_default_resource_registry() class method:

1 registry = deform.widget.ResourceRegistry()2 registry.set_js_resources('requirement', 'ver', 'bar.js', 'baz.js')3 registry.set_css_resources('requirement', 'ver', 'foo.css', 'baz.css')4 Form.set_default_resource_registry(registry)

This will result in the registry registry being used as the default resource registry for all form instances createdafter the call to set_default_resource_registry, hopefully allowing resource resolution to work properlyagain.

See also the documentation of the resource_registry argument in deform.Field and the documentation of

1.7. Widgets 25

Page 30: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

deform.widget.ResourceRegistry .

Specifying Widget Requirements

When creating a new widget, you may specify its requirements by using the requirements attribute:

1 from deform.widget import Widget2

3 class MyWidget(Widget):4 requirements = ( ('jquery', '1.4.2'), )

There are no hard-and-fast rules about the composition of a requirement name. Your widget’s docstring should explainwhat its requirement names mean, and how map to the logical requirement name to resource paths within a a resourceregistry. For example, your docstring might have text like this: “This widget uses a library name of jquery.toolsin its requirements list. The name jquery.tools implies that the JQuery Tools library must be loaded beforerendering the HTML page containing any form which uses this widget; JQuery Tools depends on JQuery, so JQueryshould also be loaded. The widget expects JQuery Tools version X.X (as specified in the version field), which expectsJQuery version X.X to be loaded previously.”. It might go on to explain that a set of resources need to be addedto a resource registry in order to resolve the logical jquery.tools name to a set of relative resource paths, andthat the resulting custom resource registry should be used when constructing the form. The default resource registry(deform.widget.resource_registry) does not contain resource mappings for your newly-created require-ment.

1.7.4 Writing Your Own Widget

Writing a Deform widget means creating an object that supplies the notional Widget interface, which is describedin the deform.widget.Widget class documentation. The easiest way to create something that implements thisinterface is to create a class which inherits directly from the deform.widget.Widget class itself.

The deform.widget.Widget class has a concrete implementation of a constructor and the handle_errormethod as well as default values for all required attributes. The deform.widget.Widget class also has abstractimplementations of serialize and deserialize each of which which raises a NotImplementedErrorexception; these must be overridden by your subclass; you may also optionally override the handle_error methodof the base class.

For example:

1 from deform.widget import Widget2

3 class MyInputWidget(Widget):4 def serialize(self, field, cstruct=None, readonly=False):5 ...6

7 def deserialize(self, field, pstruct=None):8 ...9

10 def handle_error(self, field, error):11 ...

We describe the serialize, deserialize and handle_error methods below.

The serialize Method

The serialize method of a widget must serialize a cstruct value to an HTML rendering. A cstruct value is thevalue which results from a Colander schema serialization for the schema node associated with this widget. The result

26 Chapter 1. Topics

Page 31: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

of this method should always be a unicode type containing some HTML.

The field argument passed to serialize is the field object to which this widget is attached. Because a field objectitself has a reference to the widget it uses (as field.widget), the field object is passed to the serialize methodof the widget rather than the widget having a field attribute in order to avoid a circular reference.

If the readonly argument passed to serialize is True, it indicates that the result of this serialization should bea read-only rendering (no active form controls) of the cstruct data to HTML.

Let’s pretend our new MyInputWidget only needs to create a text input control during serialization. Itsserialize method might get defined as so:

1 from deform.widget import Widget2 from colander import null3 import cgi4

5 class MyInputWidget(Widget):6 def serialize(self, field, cstruct=None, readonly=False):7 if cstruct is null:8 cstruct = u''9 quoted = cgi.escape(cstruct, quote='"')

10 return u'<input type="text" value="%s">' % quoted

Note that every serialize method is responsible for returning a serialization, no matter whether it is provided databy its caller or not. Usually, the value of cstruct will contain appropriate data that can be used directly by thewidget’s rendering logic. But sometimes it will be colander.null. It will be colander.null when a formwhich uses this widget is serialized without any data; for example an “add form”.

All widgets must check if the value passed as cstruct is the colander.null sentinel value during serialize.Widgets are responsible for handling this eventuality, often by serializing a logically “empty” value.

Regardless of how the widget attempts to compute the default value, it must still be able to return a rendering whencstruct is colander.null. In the example case above, the widget uses the empty string as the cstruct value,which is appropriate for this type of “scalar” input widget; for a more “structural” kind of widget the default might besomething else like an empty dictionary or list.

The MyInputWidget we created in the example does not use a template. Any widget may use a template, but usingone is not required; whether a particular widget uses a template is really none of Deform’s business: deform simplyexpects a widget to return a Unicode object containing HTML from the widget’s serialize method; it doesn’treally much care how the widget creates that Unicode object.

Each of the built-in Deform widgets (the widget implementations in deform.widget) happens to use a templatein order to make it easier for people to override how each widget looks when rendered without needing to changeDeform-internal Python code. Instead of needing to change the Python code related to the widget itself, users of thebuilt-in widgets can often perform enough customization by replacing the template associated with the built-in widgetimplementation. However, this is purely a convenience; templates are largely a built-in widget set implementationdetail, not an integral part of the core Deform framework.

Note that “scalar” widgets (widgets which represent a single value as opposed to a collection of values) are notresponsible for providing “page furniture” such as a “Required” label or a surrounding div which is used to pro-vide error information when validation fails. This is the responsibility of the “structural” widget which is asso-ciated with the parent field of the scalar widget’s field (the “parent widget”); the parent widget is usually one ofdeform.widget.MappingWidget or deform.widget.SequenceWidget.

The deserialize Method

The deserialize method of a widget must deserialize a pstruct value to a cstruct value and return the cstructvalue. The pstruct argument is a value resulting from the parse method of the Peppercorn package. The fieldargument is the field object to which this widget is attached.

1.7. Widgets 27

Page 32: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1 from deform.widget import Widget2 from colander import null3 import cgi4

5 class MyInputWidget(Widget):6 def serialize(self, field, cstruct, readonly=False):7 if cstruct is null:8 cstruct = u''9 return '<input type="text" value="%s">' % cgi.escape(cstruct)

10

11 def deserialize(self, field, pstruct):12 if pstruct is null:13 return null14 return pstruct

Note that the deserialize method of a widget must, like serialize, deal with the possibility of being handed acolander.null value. colander.null will be passed to the widget when a value is missing from the pstruct.The widget usually handles being passed a colander.null value in deserialize by returning colander.null‘,which signifies to the underlying schema that the default value for the schema node should be used if it exists.

The only other real constraint of the deserialize method is that the serialize method must be able to reserialize thereturn value of deserialize.

The handle_error Method

The deform.widget.Widget class already has a suitable implementation; if you subclass fromdeform.widget.Widget, overriding the default implementation is not necessary unless you need special error-handling behavior.

Here’s an implementation of the deform.widget.Widget.handle_error() method in the MyInputWidgetclass:

1 from deform.widget import Widget2 from colander import null3 import cgi4

5 class MyInputWidget(Widget):6 def serialize(self, field, cstruct, readonly=False):7 if cstruct is null:8 cstruct = u''9 return '<input type="text" value="%s">' % cgi.escape(cstruct)

10

11 def deserialize(self, field, pstruct):12 if pstruct is null:13 return null14 return pstruct15

16 def handle_error(self, field, error):17 if field.error is None:18 field.error = error19 for e in error.children:20 for num, subfield in enumerate(field.children):21 if e.pos == num:22 subfield.widget.handle_error(subfield, e)

The handle_error method of a widget must:

• Set the error attribute of the field object it is passed if the error attribute has not already been set.

28 Chapter 1. Topics

Page 33: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• Call the handle_error methods of any subfields which also have errors.

The ability to override handle_error exists purely for advanced tasks, such as presenting all child errors of a fieldon a parent field. For example:

1 def handle_error(self, field, error):2 msgs = []3 if error.msg:4 field.error = error5 else:6 for e in error.children:7 msgs.append('line %s: %s' % (e.pos+1, e))8 field.error = Invalid(field.schema, '\n'.join(msgs))

This implementation does not attach any errors to field children; instead it attaches all of the child errors to the fielditself for review.

The Template

The template you use to render a widget will receive input from the widget object, including field, which will bethe field object represented by the widget. It will usually use the field.name value as the name input element ofthe primary control in the widget, and the field.oid value as the id element of the primary control in the widget.

1.8 Example App

An example is worth a thousand words. Here’s an example Pyramid application demonstrating how one might usedeform to render a form. For it to work you’ll need to have deform, pyramid, and pyramid_chameleoninstalled in your python environment.

Warning: deform is not dependent on pyramid at all; we use Pyramid in the examples below only to facilitatedemonstration of an actual end-to-end working application that uses Deform.

Here’s the Python code:

1 import os2

3 from wsgiref.simple_server import make_server4 from pyramid.config import Configurator5

6 from colander import (7 Boolean,8 Integer,9 Length,

10 MappingSchema,11 OneOf,12 SchemaNode,13 SequenceSchema,14 String15 )16

17 from deform import (18 Form,19 ValidationFailure,20 widget21 )

1.8. Example App 29

Page 34: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

22

23

24 here = os.path.dirname(os.path.abspath(__file__))25

26 colors = (('red', 'Red'), ('green', 'Green'), ('blue', 'Blue'))27

28 class DateSchema(MappingSchema):29 month = SchemaNode(Integer())30 year = SchemaNode(Integer())31 day = SchemaNode(Integer())32

33 class DatesSchema(SequenceSchema):34 date = DateSchema()35

36 class MySchema(MappingSchema):37 name = SchemaNode(String(),38 description = 'The name of this thing')39 title = SchemaNode(String(),40 widget = widget.TextInputWidget(size=40),41 validator = Length(max=20),42 description = 'A very short title')43 password = SchemaNode(String(),44 widget = widget.CheckedPasswordWidget(),45 validator = Length(min=5))46 is_cool = SchemaNode(Boolean(),47 default = True)48 dates = DatesSchema()49 color = SchemaNode(String(),50 widget = widget.RadioChoiceWidget(values=colors),51 validator = OneOf(('red', 'blue')))52

53 def form_view(request):54 schema = MySchema()55 myform = Form(schema, buttons=('submit',))56 template_values = {}57 template_values.update(myform.get_widget_resources())58

59 if 'submit' in request.POST:60 controls = request.POST.items()61 try:62 myform.validate(controls)63 except ValidationFailure as e:64 template_values['form'] = e.render()65 else:66 template_values['form'] = 'OK'67 return template_values68

69 template_values['form'] = myform.render()70 return template_values71

72 if __name__ == '__main__':73 settings = dict(reload_templates=True)74 config = Configurator(settings=settings)75 config.include('pyramid_chameleon')76 config.add_view(form_view, renderer=os.path.join(here, 'form.pt'))77 config.add_static_view('static', 'deform:static')78 app = config.make_wsgi_app()79 server = make_server('0.0.0.0', 8080, app)

30 Chapter 1. Topics

Page 35: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

80 server.serve_forever()

Here’s the Chameleon ZPT template named form.pt, placed in the same directory:

1 <!doctype html>2 <html>3 <head>4 <meta charset="utf-8">5 <title>Deform Sample Form App</title>6 <meta name="viewport" content="width=device-width, initial-scale=1">7

8 <!-- JavaScript -->9 <script src="static/scripts/jquery-2.0.3.min.js"></script>

10 <script src="static/scripts/bootstrap.min.js"></script>11 <tal:loop tal:repeat="js_resource js">12 <script src="${request.static_path(js_resource)}"></script>13 </tal:loop>14

15 <!-- CSS -->16 <link rel="stylesheet" href="static/css/bootstrap.min.css"17 type="text/css">18 <link rel="stylesheet" href="static/css/form.css" type="text/css">19 <tal:loop tal:repeat="css_resource css">20 <link rel="stylesheet" href="${request.static_path(css_resource)}"21 type="text/css">22 </tal:loop>23

24 </head>25 <body>26 <div class="container">27 <div class="row">28 <div class="col-md-12">29 <h1>Sample Form</h1>30 <span tal:replace="structure form"/>31 </div>32 </div>33 </div>34 </body>35 </html>

1.9 Using Ajax Forms

To create a form object that uses AJAX, we do this:

1 from deform import Form2 myform = Form(schema, buttons=('submit',), use_ajax=True)

Creating a Form Object indicates how to create a Form object based on a schema and some buttons. Creating an AJAXform uses the same constructor as creating a non-AJAX form: the only difference between the example provided in theCreating a Form Object section and the example above of creating an AJAX form is the additional use_ajax=Trueargument passed to the Form constructor.

If use_ajax is passed as True to the constructor of a deform.Form object, the form page is rendered in such away that when a submit button is pressed, the page is not reloaded. Instead, the form is posted, and the result of thepost replaces the form element’s DOM node.

1.9. Using Ajax Forms 31

Page 36: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Examples of using the AJAX facilities in Deform are showcased on the http://deform2demo.repoze.org demonstrationwebsite:

• Redirection on validation success

• No redirection on validation success

Note that for AJAX forms to work, the deform.js and jquery.form.js libraries must be included in therendering of the page that includes the form itself, and the deform.load() JavaScript function must be called bythe rendering in order to associate the form with AJAX. This is the responsibility of the wrapping page. Both librariesare present in the static directory of the deform package itself. See Widget Requirements and Resources for away to detect which JavaScript libraries are required for a particular form rendering.

1.10 Internationalization

Deform is fully internationalizable and localizable. gettext .mo. files exist in the deform and colander packageswhich contain (currently incomplete) translations to various languages for the purpose of rendering localized errormessages.

Following should get you started with i18n in pyramid:

import deform

from pkg_resources import resource_filenamefrom pyramid.i18n import get_localizerfrom pyramid.threadlocal import get_current_request

def main(global_config, **settings):config = Configurator(settings=settings)config.add_translation_dirs(

'colander:locale','deform:locale',

)

def translator(term):return get_localizer(get_current_request()).translate(term)

deform_template_dir = resource_filename('deform', 'templates/')zpt_renderer = deform.ZPTRendererFactory(

[deform_template_dir],translator=translator)

deform.Form.set_default_renderer(zpt_renderer)

See the Internationalization demo for an example of how deform error and status messages can be localized. Thisdemonstration uses the internationalization and localization features of Pyramid to render Deform error messages intoChameleon form renderings.

1.11 API Documentation

1.11.1 Form-Related

class deform.Field(schema, renderer=None, counter=None, resource_registry=None, app-struct=<colander.null>, parent=None, **kw)

Represents an individual form field (a visible object in a form rendering).

32 Chapter 1. Topics

Page 37: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

A deform.form.Field object instance is meant to last for the duration of a single web request. As a result,a field object is often used as a scratchpad by the widget associated with that field. Using a field as a scratchpadmakes it possible to build implementations of state-retaining widgets while instances of those widget still onlyneed to be constructed once instead of on each request.

Attributes

schema The schema node associated with this field.

widget The widget associated with this field. When no widget is defined in the schema node, a de-fault widget will be created. The default widget will have a generated item_css_class containingthe normalized version of the name attribute (with item prepended, e.g. item-username).

order An integer indicating the relative order of this field’s construction to its children and parents.

oid A string incorporating the order attribute that can be used as a unique identifier in HTML code(often for id attributes of field-related elements). A default oid is generated that looks like this:deformField0. A custom oid can provided, but if the field is cloned, the clones will getunique default oids.

name An alias for self.schema.name

title An alias for self.schema.title

description An alias for self.schema.description

required An alias for self.schema.required

typ An alias for self.schema.typ

children Child fields of this field.

parent The parent field of this field or None if this field is the root. This is actually a propertythat returns the result of weakref.ref(actualparent)() to avoid leaks due to circularreferences, but it can be treated like the field itself.

error The exception raised by the last attempted validation of the schema element associated withthis field. By default, this attribute is None. If non-None, this attribute is usually an instanceof the exception class colander.Invalid, which has a msg attribute providing a human-readable validation error message.

errormsg The msg attribute of the error attached to this field or None if the error attached tothis field is None.

renderer The template renderer associated with the form. If a renderer is not passed to the con-structor, the default deform renderer will be used (the default renderer).

counter None or an instance of itertools.counter which is used to generate sequentialorder-related attributes such as oid and order.

resource_registry The resource registry associated with this field.

Constructor Arguments

renderer, counter, resource_registry and appstruct are accepted as explicit key-word arguments to the deform.Field. These are also available as attribute values. renderer,if passed, is a template renderer as described in Using an alternative templating system. counter, ifpassed, should be an itertools.counter object (useful when rendering multiple forms on thesame page, see http://deform2demo.repoze.org/multiple_forms/. resource_registry, if passedshould be a widget resource registry (see also The (High-Level) deform.Field.get_widget_resources()Method).

If any of these values is not passed, a suitable default values is used in its place.

1.11. API Documentation 33

Page 38: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

The appstruct constructor argument is used to prepopulate field values related to this form’sschema. If an appstruct is not supplied, the form’s fields will be rendered with default values unlessan appstruct is supplied to the render method explicitly.

The deform.Field constructor also accepts arbitrary keyword arguments. When an ‘unknown’keyword argument is passed, it is attached unmodified to the form field as an attribute.

All keyword arguments (explicit and unknown) are also attached to all children nodes of the fieldbeing constructed.

__getitem__(name)Return the subfield of this field named name or raise a KeyError if a subfield does not exist namedname.

__iter__()Iterate over the children fields of this field.

__contains__(name)

translate(msgid)Use the translator passed to the renderer of this field to translate the msgid into a term and return the term.If the renderer does not have a translator, this method will return the msgid.

get_root()Return the root field in the field hierarchy (the form field)

clone()Clone the field and its subfields, retaining attribute information. Return the cloned field. The orderattribute of the node is not cloned; instead the field receives a new order attribute; it will be a number largerthan the last rendered field of this set. The parent of the cloned node will become None unconditionally.

deserialize(pstruct)Deserialize the pstruct into a cstruct and return the cstruct.

end_mapping(name=None)Create an end-mapping tag (a literal). If name is None, the name of this node will be used to generate thename in the tag. See the Peppercorn documentation for more information.

end_rename(name=None)Create a start-rename tag (a literal). If name is None, the name of this node will be used to generate thename in the tag. See the Peppercorn documentation for more information.

end_sequence(name=None)Create an end-sequence tag (a literal). If name is None, the name of this node will be used to generate thename in the tag. See the Peppercorn documentation for more information.

errormsgReturn the msg attribute of the error attached to this field. If the error attribute is None, the returnvalue will be None.

get_root()Return the root field in the field hierarchy (the form field)

get_widget_requirements()Return a sequence of two tuples in the form [(requirement_name, version), ..].

The first element in each two-tuple represents a requirement name. When a requirement name is returnedas part of get_widget_requirements, it means that one or more CSS or Javascript resources needto be loaded by the page performing the form rendering in order for some widget on the page to functionproperly.

34 Chapter 1. Topics

Page 39: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

The second element in each two-tuple is the requested version of the library resource. It may be None, inwhich case the version is unspecified.

See also the requirements attribute of deform.Widget and the explanation of widget requirementsin The (Low-Level) deform.Field.get_widget_requirements() Method.

get_widget_resources(requirements=None)Return a resources dictionary in the form {’js’:[seq], ’css’:[seq]}. js represents Javascriptresources, css represents CSS resources. seq represents a sequence of resource paths. Each path inseq represents a relative resource name, as defined by the mapping of a requirement to a set of resourcespecification by the resource registry attached to this field or form.

This method may raise a ValueError if the resource registry associated with this field or form cannotresolve a requirement to a set of resource paths.

The requirements argument represents a set of requirements as returned by a manual call todeform.Field.get_widget_requirements(). If requirements is not supplied, the re-quirement are implied by calling the deform.Field.get_widget_requirements() methodagainst this form field.

See also The (High-Level) deform.Field.get_widget_resources() Method.

render(appstruct=(Default), **kw)Render the field (or form) to HTML using appstruct as a set of default values and returns the HTMLstring. appstruct is typically a dictionary of application values matching the schema used by this form,or colander.null to render all defaults. If it is omitted, the rendering will use the appstruct passedto the constructor.

Calling this method passing an appstruct is the same as calling:

cstruct = form.set_appstruct(appstruct)form.serialize(cstruct, **kw)

Calling this method without passing an appstruct is the same as calling:

cstruct = form.cstructform.serialize(cstruct, **kw)

See the documentation for colander.SchemaNode.serialize() anddeform.widget.Widget.serialize() .

Note: Deform versions before 0.9.8 only accepted a readonly keyword argument to this function.Version 0.9.8 and later accept arbitrary keyword arguments.

render_template(template, **kw)Render the template named template using kw as the top-level keyword arguments (augmented withfield and cstruct if necessary)

serialize(cstruct=(Default), **kw)Serialize the cstruct into HTML and return the HTML string. This function just turns around and callsself.widget.serialize(**kw); therefore the field widget’s serialize method should be ex-pecting any values sent in kw. If cstruct is not passed, the cstruct attached to this node will be injectedinto kw as cstruct. If field is not passed in kw, this field will be injected into kw as field.

Note: Deform versions before 0.9.8 only accepted a readonly keyword argument to this function.Version 0.9.8 and later accept arbitrary keyword arguments. It also required that cstruct was passed;it’s broken out from kw in the method signature for backwards compatibility.

1.11. API Documentation 35

Page 40: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

set_appstruct(appstruct)Set the cstruct of this node (and its child nodes) using appstruct as input.

classmethod set_default_renderer(renderer)Set the callable that will act as a default renderer for instances of the associated class when no rendererargument is provided to the class’ constructor. Useful when you’d like to use an alternate templatingsystem.

Calling this method resets the default renderer.

classmethod set_default_resource_registry(registry)Set the callable that will act as a default resource registry for instances of the associated class when noresource_registry argument is provided to the class’ constructor. Useful when you’d like to usenon-default requirement to resource path mappings for the entirety of a process.

Calling this method resets the default resource registry.

set_pstruct(pstruct)Set the cstruct of this node (and its child nodes) using pstruct as input.

set_widgets(values, separator=’.’)set widgets of the child fields of this field or form element. widgets should be a dictionary in the form:

{'dotted.field.name':Widget(),'dotted.field.name2':Widget()}

The keys of the dictionary are dotted names. Each dotted name refers to a single field in the tree of fieldsthat are children of the field or form object upon which this method is called.

The dotted name is split on its dots and the resulting list of names is used as a search path into the childfields of this field in order to find a field to which to assign the associated widget.

Two special cases exist:

•If the key is the empty string (’’), the widget is assigned to the field upon which this method is called.

•If the key contains an asterisk as an element name, the first child of the found element is traversed.This is most useful for sequence fields, because the first (and only) child of sequence fields is alwaysthe prototype field which is used to render all fields in the sequence within a form rendering.

If the separator argument is passed, it is should be a string to be used as the dot character when splittingthe dotted names (useful for supplying if one of your field object has a dot in its name, and you need touse a different separator).

Examples follow. If the following form is used:

class Person(Schema):first_name = SchemaNode(String())last_name = SchemaNode(String())

class People(SequenceSchema):person = Person()

class Conference(Schema):people = People()name = SchemaNode(String())

schema = Conference()form = Form(schema)

The following invocations will have the following results against the schema defined above:

form.set_widgets({’people.person.first_name’:TextAreaWidget()})

36 Chapter 1. Topics

Page 41: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Set the first_name field’s widget to a TextAreaWidget.

form.set_widgets({’people.*.first_name’:TextAreaWidget()})

Set the first_name field’s widget to a TextAreaWidget.

form.set_widgets({’people’:MySequenceWidget()})

Set the people sequence field’s widget to a MySequenceWidget.

form.set_widgets({’people.*’:MySequenceWidget()})

Set the person field’s widget to a MySequenceWidget.

form.set_widgets({’’:MyMappingWidget()})

Set form node’s widget to a MyMappingWidget.

classmethod set_zpt_renderer(search_path, auto_reload=True, debug=True, encoding=’utf-8’,translator=None)

Create a Chameleon ZPT renderer that will act as a default renderer for instances of the associated classwhen no renderer argument is provided to the class’ constructor. The arguments to this classmethodhave the same meaning as the arguments provided to a deform.ZPTRendererFactory .

Calling this method resets the default renderer.

This method is effectively a shortcut for cls.set_default_renderer(ZPTRendererFactory(...)).

start_mapping(name=None)Create a start-mapping tag (a literal). If name is None, the name of this node will be used to generate thename in the tag. See the Peppercorn documentation for more information.

start_rename(name=None)Create a start-rename tag (a literal). If name is None, the name of this node will be used to generate thename in the tag. See the Peppercorn documentation for more information.

start_sequence(name=None)Create a start-sequence tag (a literal). If name is None, the name of this node will be used to generate thename in the tag. See the Peppercorn documentation for more information.

translate(msgid)Use the translator passed to the renderer of this field to translate the msgid into a term and return the term.If the renderer does not have a translator, this method will return the msgid.

validate(controls, subcontrol=None)Validate the set of controls returned by a form submission against the schema associated with this fieldor form. controls should be a document-ordered sequence of two-tuples that represent the form sub-mission data. Each two-tuple should be in the form (key, value). node should be the schema nodeassociated with this widget.

For example, using WebOb, you can compute a suitable value for controls via:

request.POST.items()

Or, if you’re using a cgi.FieldStorage object named fs, you can compute a suitable value forcontrols via:

controls = []if fs.list:

for control in fs.list:if control.filename:

controls.append((control.name, control))else:

controls.append((control.name, control.value))

1.11. API Documentation 37

Page 42: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Equivalent ways of computing controls should be available to any web framework.

When the validate method is called:

•if the fields are successfully validated, a data structure represented by the deserialization of the dataas per the schema is returned. It will be a mapping.

•If the fields cannot be successfully validated, a deform.exception.ValidationFailureexception is raised.

The typical usage of validate in the wild is often something like this (at least in terms of code foundwithin the body of a pyramid view function, the particulars will differ in your web framework):

from webob.exc import HTTPFoundfrom deform.exception import ValidationFailurefrom deform import Formimport colander

from my_application import do_something

class MySchema(colander.MappingSchema):color = colander.SchemaNode(colander.String())

schema = MySchema()

def view(request):form = Form(schema, buttons=('submit',))if 'submit' in request.POST: # form submission needs validation

controls = request.POST.items()try:

deserialized = form.validate(controls)do_something(deserialized)return HTTPFound(location='http://example.com/success')

except ValidationFailure as e:return {'form':e.render()}

else:return {'form':form.render()} # the form just needs rendering

Warning: form.validate(controls) mutates the form instance, so the form instanceshould be constructed (and live) inside one request.

If subcontrol is supplied, it represents a named subitem in the data returned bypeppercorn.parse(controls). Use this subitem as the pstruct to validate instead of usingthe entire result of peppercorn.parse(controls) as the pstruct to validate. For example, ifyou’ve embedded a mapping in the form named user, and you want to validate only the data contained inthat mapping instead if all of the data in the form post, you might use form.validate(controls,subcontrol=’user’).

validate_pstruct(pstruct)Validate the pstruct passed. Works exactly like the deform.field.validate method, except it ac-cepts a pstruct instead of a set of form controls. A usage example follows:

if 'submit' in request.POST: # the form submission needs validationcontrols = request.POST.items()pstruct = peppercorn.parse(controls)substruct = pstruct['submapping']try:

deserialized = form.validate_pstruct(substruct)do_something(deserialized)

38 Chapter 1. Topics

Page 43: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

return HTTPFound(location='http://example.com/success')except ValidationFailure, e:

return {'form':e.render()}else:

return {'form':form.render()} # the form just needs rendering

class deform.Form(schema, action=’‘, method=’POST’, buttons=(), formid=’deform’, use_ajax=False,ajax_options=’{}’, autocomplete=None, **kw)

Field representing an entire form.

Arguments:

schema A colander.SchemaNode object representing a schema to be rendered. Required.

action The form action (inserted into the action attribute of the form’s form tag when rendered). Default:the empty string.

method The form method (inserted into the method attribute of the form’s form tag when rendered). Default:POST.

buttons A sequence of strings or deform.form.Button objects representing submit buttons that willbe placed at the bottom of the form. If any string is passed in the sequence, it is converted todeform.form.Button objects.

formid The identifier for this form. This value will be used as the HTML id attribute of the rendered HTMLform. It will also be used as the value of a hidden form input control (__formid__) which will beplaced in this form’s rendering. You should pass a string value for formid when more than one Deformform is placed into a single page and both share the same action. When one of the forms on the page isposted, your code will to be able to decide which of those forms was posted based on the differing valuesof __formid__. By default, formid is deform.

autocomplete Controls this form’s autocomplete attribute. If autocomplete is None, no autocompleteattribute will be added to the form tag. If autocomplete is a true value, an autocomplete=’on’attribute will be added to the form tag. If autocomplete is a false value, an autocomplete=’off’attribute will be added to the form tag. Default: None.

use_ajax If this option is True, the form will use AJAX (actually AJAH); when any submit button is clicked,the DOM node related to this form will be replaced with the result of the form post caused by the sub-mission. The page will not be reloaded. This feature uses the jquery.form library ajaxForm featureas per http://jquery.malsup.com/form/. Default: False. If this option is True, the jquery.form.jslibrary must be loaded in the HTML page which embeds the form. A copy of it exists in the staticdirectory of the deform package.

ajax_options A string which must represent a JavaScript object (dictionary) of extra AJAX options as perhttp://jquery.malsup.com/form/#options-object. For example:

'{"success": function (rText, sText, xhr, form) {alert(sText)};}'

Default options exist even if ajax_options is not provided. By default, target points at the DOMnode representing the form and and replaceTarget is true.

A success handler calls the deform.processCallbacks method that will ajaxify the newly writtenform again. If you pass these values in ajax_options, the defaults will be overridden. If you want tooverride the success handler, don’t forget to call deform.processCallbacks, otherwise subsequentform submissions won’t be submitted via AJAX.

This option has no effect when use_ajax is False.

The default value of ajax_options is a string representation of the empty object.

1.11. API Documentation 39

Page 44: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

The deform.Form constructor also accepts all the keyword arguments accepted by the deform.Fieldclass. These keywords mean the same thing in the context of a Form as they do in the context of a Field (a Formis just another kind of Field).

class deform.Button(name=’submit’, title=None, type=’submit’, value=None, disabled=False,css_class=None)

A class representing a form submit button. A sequence of deform.widget.Button objects may be passedto the constructor of a deform.form.Form class when it is created to represent the buttons renderered at thebottom of the form.

Arguments:

name The string or unicode value used as the name of the button when rendered (the name attribute of thebutton or input tag resulting from a form rendering). Default: submit.

title The value used as the title of the button when rendered (shows up in the button inner text). Default:capitalization of whatever is passed as name. E.g. if name is passed as submit, titlewill be Submit.

type The value used as the type of button. The HTML spec supports submit, reset and button. Default:submit.

value The value used as the value of the button when rendered (the value attribute of the button or input tagresulting from a form rendering). Default: same as name passed.

disabled Render the button as disabled if True.

css_class The name of a CSS class to attach to the button. In the default form rendering, this string will beappended to btnText submit to become part of the class attribute of the button. For example,if css_class was foobar then the resulting default class becomes btnText submit foobar.Default: None (no additional class).

1.11.2 Type-Related

class deform.FileDataA type representing file data; used to shuttle data back and forth between an application and thedeform.widget.FileUploadWidget widget.

This type passes the value obtained during deserialization back to the caller unchanged (it will be an in-stance of deform.widget.filedict, which is a plain dictionary subclass; it is only a dict subclass soisinstance may be used against it in highly generalized persistence circumstances to detect that it is filedata). It serializes from a dictionary containing partial file data info into a dictionary containing full file datainfo, serializing the full file data (the widget receives the full file data).

serialize(node, value)Serialize a dictionary representing partial file information to a dictionary containing information expectedby a file upload widget.

The file data dictionary passed as value to this serialize method must include:

filename Filename of this file (not a full filesystem path, just the filename itself).

uid Unique string id for this file. Needs to be unique enough to disambiguate it from other files that mayuse the same temporary storage mechanism before a successful validation, and must be adequate forthe calling code to reidentify it after deserialization.

A fully populated dictionary may also include the following values:

fp File-like object representing this file’s content or None. None indicates this file has already beencommitted to permanent storage. When serializing a ‘committed’ file, the fp value should ideally notbe passed or it should be passed as None; None as an fp value is a signifier to the file upload widgetthat the file data has already been committed. Using None as an fp value helps prevent unnecessary

40 Chapter 1. Topics

Page 45: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

data copies to temporary storage when a form is rendered, however its use requires cooperation fromthe calling code; in particular, the calling code must be willing to translate a None fp value returnedfrom a deserialization into the file data via the uid in the deserialization.

mimetype File content type (e.g. application/octet-stream).

size File content length (integer).

preview_url URL which provides an image preview of this file’s data.

If a size is not provided, the widget will have no access to size display data. If preview_url is notprovided, the widget will not be able to show a file preview. If mimetype is not provided, the widget willnot be able to display mimetype information.

See also the type- and schema-related documentation in Colander.

1.11.3 Exception-Related

class deform.ValidationFailure(field, cstruct, error)The exception raised by deform.widget.Widget.validate() (most often called asform.validate(fields)) when the supplied field data does not pass the overall constraints of theschema associated with the widget.

Attributes

field The field deform.form.Field.validate() was called on (usually a deform.form.Formobject).

cstruct The unvalidatable cstruct that was returned from deform.widget.Widget.deserialize().

error The original colander.Invalid exception raised by deform.schema.SchemaNode.deserialize()which caused this exception to need to be raised.

render(**kw)Used to reserialize the form in such a way that the user will see error markers in the form HTML.

The **kw argument allows a caller to pass named arguments that are passed on to the template.

class deform.TemplateError

See also the exception-related documentation in Colander.

1.11.4 Template-Related

class deform.ZPTRendererFactory(search_path, auto_reload=True, debug=False, encoding=’utf-8’,translator=None)

Construct a custom Chameleon ZPT renderer for Deform.

If the template name is an asset spec (has a colon in it, e.g.mypackage:subdir/subdir2/mytemplate.pt), use pkg_resources.resource_filenameto resolve it. Otherwise, fall back to search-path-based machinery to resolve it.

Allowing an asset spec allows users to specify templates without the trouble of needing to add search paths tothe deform rendering machinery.

Arguments

search_path A sequence of strings representing fully qualified filesystem directories containing DeformChameleon template sources. The order in which the directories are listed within search_path isthe order in which they are checked for the template provided to the renderer. If every resource is an assetspec, however, the search path is never used.

1.11. API Documentation 41

Page 46: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

auto_reload If true, automatically reload templates when they change (slows rendering). Default: True.

debug If true, show nicer tracebacks during Chameleon template rendering errors (slows rendering). Default:True.

encoding The encoding that the on-disk representation of the templates and all non-ASCII values passed to thetemplate should be expected to adhere to. Default: utf-8.

translator A translation function used for internationalization when the i18n:translate attribute syntaxis used in the Chameleon template is active or a translationstring.TranslationString is en-countered during output. It must accept a translation string and return an interpolated translation. Default:None (no translation performed).

deform.default_rendererThe default ZPT template renderer (uses the deform/templates/ directory as a template source).

1.11.5 Widget-Related

class deform.widget.Widget(**kw)A widget is the building block for rendering logic. The deform.widget.Widget class is never instantiateddirectly: it is the abstract class from which all other widget types within deform.widget derive. It shouldlikely also be subclassed by application-developer-defined widgets.

A widget instance is attached to a field during normal operation. A widget is not meant to carryany state. Instead, widget implementations should use the field object passed to them duringdeform.widget.Widget.serialize() and deform.widget.Widget.deserialize() as ascratchpad for state information.

All widgets have the following attributes:

hidden An attribute indicating the hidden state of this widget. The default is False. If this attribute is notFalse, the field associated with this widget will not be rendered in the form (although, if the widget is astructural widget, its children will be; hidden is not a recursive flag). No label, no error message, nor anyfurniture such as a close button when the widget is one of a sequence will exist for the field in the renderedform.

readonly If this attribute is true, the readonly rendering of the widget should be output during HTML serializa-tion.

category A string value indicating the category of this widget. This attribute exists to inform structural widgetrendering behavior. For example, when a text widget or another simple ‘leaf-level’ widget is rendered as achild of a mapping widget using the default template mapping template, the field title associated with thechild widget will be rendered above the field as a label by default. This is because simple child widgets arein the default category and no special action is taken when a structural widget renders child widgetsthat are in the default category. However, if the default mapping widget encounters a child widget withthe category of structural during rendering (the default mapping and sequence widgets are in thiscategory), it omits the title. Default: default

error_class The name of the CSS class attached to various tags in the form renderering indicating an errorcondition for the field associated with this widget. Default: error.

css_class The name of the CSS class attached to various tags in the form renderering specifying a new class forthe field associated with this widget. Default: None (no class).

item_css_class The name of the CSS class attached to the li which surrounds the field when it is rendered insidethe mapping_item or sequence_item template.

style A string that will be placed literally in a style attribute on the primary input tag(s) related to the widget.For example, ‘width:150px;’. Default: None, meaning no style attribute will be added to the input tag.

42 Chapter 1. Topics

Page 47: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

requirements A sequence of two-tuples in the form ( (requirement_name, version_id), ...)indicating the logical external requirements needed to make this widget render properly within a form.The requirement_name is a string that logically (not concretely, it is not a filename) identifies oneor more Javascript or CSS resources that must be included in the page by the application performing theform rendering. The requirement name string value should be interpreted as a logical requirement name(e.g. jquery for JQuery, ‘tinymce’ for Tiny MCE). The version_id is a string indicating the versionnumber (or None if no particular version is required). For example, a rich text widget might declarerequirements = ((’tinymce’, ’3.3.8’),). See also: Specifying Widget Requirements andWidget Requirements and Resources.

Default: () (the empty tuple, meaning no special requirements).

These attributes are also accepted as keyword arguments to all widget constructors; if they are passed, they willoverride the defaults.

Particular widget types also accept other keyword arguments that get attached to the widget as attributes. Theseare documented as ‘Attributes/Arguments’ within the documentation of each concrete widget implementationsubclass.

deserialize(field, pstruct)The deserialize method of a widget must deserialize a pstruct value to a cstruct value and return thecstruct value. The pstruct argument is a value resulting from the parse method of the Peppercornpackage. The field argument is the field object to which this widget is attached.

handle_error(field, error)The handle_error method of a widget must:

•Set the error attribute of the field object it is passed, if the error attribute has not already beenset.

•Call the handle_error method of each subfield which also has an error (as per the error argu-ment’s children attribute).

serialize(field, cstruct, **kw)The serialize method of a widget must serialize a cstruct value to an HTML rendering. A cstructvalue is the value which results from a Colander schema serialization for the schema node associated withthis widget. serialize should return the HTML rendering: the result of this method should always bea string containing HTML. The field argument is the field object to which this widget is attached. The**kw argument allows a caller to pass named arguments that might be used to influence individual widgetrenderings.

class deform.widget.TextInputWidget(**kw)Renders an <input type="text"/> widget.

Attributes/Arguments

template

The template name used to render the widget. Default: textinput.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textinput.

strip If true, during deserialization, strip the value of leading and trailing whitespace (default True).

mask A jquery.maskedinput input mask, as a string.

a - Represents an alpha character (A-Z,a-z) 9 - Represents a numeric character (0-9) * - Represents analphanumeric character (A-Z,a-z,0-9)

All other characters in the mask will be considered mask literals.

Example masks:

1.11. API Documentation 43

Page 48: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Date: 99/99/9999

US Phone: (999) 999-9999

US SSN: 999-99-9999

When this option is used, the jquery.maskedinput library must be loaded into the page serving the form forthe mask argument to have any effect. See Using Text Input Masks.

mask_placeholder The placeholder for required nonliteral elements when a mask is used. Default: _ (under-score).

class deform.widget.MoneyInputWidget(**kw)Renders an <input type="text"/> widget with Javascript which enforces a valid currency input. Itshould be used along with the colander.Decimal schema type (at least if you care about your money).This widget depends on the jquery-maskMoney JQuery plugin.

Attributes/Arguments

template

The template name used to render the widget. Default: moneyinput.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textinput.

options A dictionary or sequence of two-tuples containing jquery-maskMoney options. The valid optionsare:

symbol the symbol to be used before of the user values. default: $

showSymbol set if the symbol must be displayed or not. default: False

symbolStay set if the symbol will stay in the field after the user exists the field. default: False

thousands the thousands separator. default: ,

decimal the decimal separator. default: .

precision how many decimal places are allowed. default: 2

defaultZero when the user enters the field, it sets a default mask using zero. default: True

allowZero use this setting to prevent users from inputing zero. default: False

allowNegative use this setting to prevent users from inputing negative values. default: False

class deform.widget.AutocompleteInputWidget(**kw)Renders an <input type="text"/> widget which provides autocompletion via a list of values using boot-strap’s typeahead plugin http://twitter.github.com/bootstrap/javascript.html#typeahead.

Attributes/Arguments

template The template name used to render the widget. Default: typeahead_textinput.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/typeahead_textinput.

strip If true, during deserialization, strip the value of leading and trailing whitespace (default True).

values A list of strings or string. Defaults to [].

If values is a string it will be treated as a URL. If values is an iterable which can be serialized to a jsonarray, it will be treated as local data.

If a string is provided to a URL, an xhr request will be sent to the URL. The response should be a JSONserialization of a list of values. For example:

44 Chapter 1. Topics

Page 49: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

[’foo’, ‘bar’, ‘baz’]

min_length min_length is an optional argument to jquery.ui.autocomplete. The number of characters towait for before activating the autocomplete call. Defaults to 1.

items The max number of items to display in the dropdown. Defaults to 8.

class deform.widget.HiddenWidget(**kw)Renders an <input type="hidden"/> widget.

Attributes/Arguments

template The template name used to render the widget. Default: hidden.

class deform.widget.TextAreaWidget(**kw)Renders a <textarea> widget.

Attributes/Arguments

cols The size, in columns, of the text input field. Defaults to None, meaning that the cols is not included inthe widget output (uses browser default cols).

rows The size, in rows, of the text input field. Defaults to None, meaning that the rows is not included in thewidget output (uses browser default cols).

template The template name used to render the widget. Default: textarea.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textinput.

strip If true, during deserialization, strip the value of leading and trailing whitespace (default True).

class deform.widget.RichTextWidget(**kw)Renders a <textarea> widget with the TinyMCE Editor.

To use this widget the TinyMCE Editor library must be provided in the page where the widget is rendered. Aversion of TinyMCE Editor is included in Deform’s static directory.

Attributes/Arguments

readonly_template The template name used to render the widget in read-only mode. Default:readonly/richtext.

delayed_load If you have many richtext fields, you can set this option to True, and the richtext editor willonly be loaded upon the user clicking the field. Default: False.

strip If true, during deserialization, strip the value of leading and trailing whitespace. Default: True.

template The template name used to render the widget. Default: richtext.

options A dictionary or sequence of two-tuples containing additional options to pass to the TinyMCE initfunction call. All types within such structure should be Python native as the structure will be con-verted to JSON on serialization. This widget provides some sensible defaults, as described below indefault_options.

You should refer to the TinyMCE Configuration documentation for details regarding all available configu-ration options.

The language option is passed to TinyMCE within the default template, using i18n machinery to deter-mine the language to use. This option can be overridden if it is specified here in options.

Note: the elements option for TinyMCE is set automatically according to the given field’s oid.

Default: None (no additional options)

Note that the RichTextWidget template does not honor the css_class or style attributes of the widget.

1.11. API Documentation 45

Page 50: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

default_options = ((‘height’, 240), (‘width’, 0), (‘skin’, ‘lightgray’), (‘theme’, ‘modern’), (‘mode’, ‘exact’), (‘strict_loading_mode’, True), (‘theme_advanced_resizing’, True), (‘theme_advanced_toolbar_align’, ‘left’), (‘theme_advanced_toolbar_location’, ‘top’))Default options passed to TinyMCE. Customise by using options.

options = NoneOptions to pass to TinyMCE that will override default_options.

class deform.widget.CheckboxWidget(**kw)Renders an <input type="checkbox"/> widget.

Attributes/Arguments

true_val The value which should be returned during deserialization if the box is checked. Default: true.

false_val The value which should be returned during deserialization if the box was left unchecked. Default:false.

template The template name used to render the widget. Default: checkbox.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/checkbox.

class deform.widget.CheckedInputWidget(**kw)Renders two text input fields: ‘value’ and ‘confirm’. Validates that the ‘value’ value matches the ‘confirm’value.

Attributes/Arguments

template The template name used to render the widget. Default: checked_input.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textinput.

mismatch_message The message to be displayed when the value in the primary field does not match the valuein the confirm field.

mask A jquery.maskedinput input mask, as a string. Both input fields will use this mask.

a - Represents an alpha character (A-Z,a-z) 9 - Represents a numeric character (0-9) * - Represents analphanumeric character (A-Z,a-z,0-9)

All other characters in the mask will be considered mask literals.

Example masks:

Date: 99/99/9999

US Phone: (999) 999-9999

US SSN: 999-99-9999

When this option is used, the jquery.maskedinput library must be loaded into the page serving the form forthe mask argument to have any effect. See Using Text Input Masks.

mask_placeholder The placeholder for required nonliteral elements when a mask is used. Default: _ (under-score).

class deform.widget.CheckedPasswordWidget(**kw)Renders two password input fields: ‘password’ and ‘confirm’. Validates that the ‘password’ value matches the‘confirm’ value.

Attributes/Arguments

template The template name used to render the widget. Default: checked_password.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/checked_password.

46 Chapter 1. Topics

Page 51: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

mismatch_message The string shown in the error message when a validation failure is caused by the confirmfield value does not match the password field value. Default: Password did not match confirm.

redisplay If true, on validation failure involving a field with this widget, retain and redisplay the providedvalues in the password inputs. If false, on validation failure, the fields will be rendered empty. Default::False.

class deform.widget.CheckboxChoiceWidget(**kw)Renders a sequence of <input type="check"/> buttons based on a predefined set of values.

Attributes/Arguments

values A sequence of two-tuples (the first value must be of type string, unicode or integer, the second valuemust be string or unicode) indicating allowable, displayed values, e.g. ( (’true’, ’True’),(’false’, ’False’) ). The first element in the tuple is the value that should be returned whenthe form is posted. The second is the display value.

template The template name used to render the widget. Default: checkbox_choice.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/checkbox_choice.

null_value The value used to replace the colander.null value when it is passed to the serialize ordeserialize method. Default: the empty string.

inline If true, choices will be rendered on a single line. Otherwise choices will be rendered one per line.Default: false.

class deform.widget.OptGroup(label, *options)Used in the values argument passed to an instance of SelectWidget to render an <optgroup> HTMLtag.

Attributes/Arguments

label The label of the <optgroup> HTML tag.

options A sequence that describes the <options> HTML tag(s). It must have the same structure as thevalues argument/parameter in the SelectWidget class, but should not contain OptGroup instancessince <optgroup> HTML tags cannot be nested.

class deform.widget.SelectWidget(**kw)Renders <select> field based on a predefined set of values.

Attributes/Arguments

values A sequence of items where each item must be either:

• a two-tuple (the first value must be of type string, unicode or integer, the second value must be stringor unicode) indicating allowable, displayed values, e.g. (’jsmith’, ’John Smith’). The firstelement in the tuple is the value that should be returned when the form is posted. The second is thedisplay value;

• or an instance of optgroup_class (which is deform.widget.OptGroup by default).

null_value The value which represents the null value. When the null value is encountered during serialization,the colander.null sentinel is returned to the caller. Default: ’’ (the empty string).

template The template name used to render the widget. Default: select.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/select.

multiple Enable multiple on the select widget ( default: False )

1.11. API Documentation 47

Page 52: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

optgroup_class The class used to represent <optgroup> HTML tags. Default:deform.widget.OptGroup.

long_label_generator A function that returns the “long label” used as the description for very old browsers thatdo not support the <optgroup> HTML tag. If a function is provided, the label attribute will receivethe (short) description, while the content of the <option> tag will receive the “long label”. The functionis called with two parameters: the group label and the option (short) description.

For example, with the following widget:

long_label_gener = lambda group, label: ' - '.join((group, label))SelectWidget(values=(('', 'Select your favorite musician'),OptGroup('Guitarists',

('page', 'Jimmy Page'),('hendrix', 'Jimi Hendrix')),

OptGroup('Drummers',('cobham', 'Billy Cobham'),('bonham', 'John Bonham'))),

long_label_generator=long_label_gener)

... the rendered options would look like:

<option value="">Select your favorite musician</option><optgroup label="Guitarists"><option value="page"

label="Jimmy Page">Guitarists - Jimmy Page</option><option value="hendrix"

label="Jimi Hendrix">Guitarists - Jimi Hendrix</option></optgroup><optgroup label="Drummers">

<option value="cobham"label="Billy Cobham">Drummers - Billy Cobham</option>

<option value="bonham"label="John Bonham">Drummers - John Bonham</option>

</optgroup>

Default: None (which means that the label attribute is not rendered).

size The size, in rows, of the select list. Defaults to None, meaning that the size is not included in the widgetoutput (uses browser default size).

class deform.widget.Select2Widget(**kw)

handle_error(field, error)The handle_error method of a widget must:

•Set the error attribute of the field object it is passed, if the error attribute has not already beenset.

•Call the handle_error method of each subfield which also has an error (as per the error argu-ment’s children attribute).

class deform.widget.RadioChoiceWidget(**kw)Renders a sequence of <input type="radio"/> buttons based on a predefined set of values.

Attributes/Arguments

values A sequence of two-tuples (the first value must be of type string, unicode or integer, the second valuemust be string or unicode) indicating allowable, displayed values, e.g. ( (’true’, ’True’),

48 Chapter 1. Topics

Page 53: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

(’false’, ’False’) ). The first element in the tuple is the value that should be returned whenthe form is posted. The second is the display value.

template The template name used to render the widget. Default: radio_choice.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/radio_choice.

null_value The value used to replace the colander.null value when it is passed to the serialize ordeserialize method. Default: the empty string.

inline If true, choices will be rendered on a single line. Otherwise choices will be rendered one per line.Default: false.

class deform.widget.MappingWidget(**kw)Renders a mapping into a set of fields.

Attributes/Arguments

template The template name used to render the widget. Default: mapping.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/mapping.

item_template The template name used to render each item in the mapping. Default: mapping_item.

readonly_item_template The template name used to render each item in the form. Default:readonly/mapping_item.

Note that the MappingWidget template does not honor the css_class or style attributes of the widget.

class deform.widget.SequenceWidget(**kw)Renders a sequence (0 .. N widgets, each the same as the other) into a set of fields.

Attributes/Arguments

template The template name used to render the widget. Default: sequence.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/sequence.

item_template The template name used to render each value in the sequence. Default: sequence_item.

add_subitem_text_template The string used as the add link text for the widget. Interpolation markers in thetemplate will be replaced in this string during serialization with a value as follows:

${subitem_title} The title of the subitem field

${subitem_description} The description of the subitem field

${subitem_name} The name of the subitem field

Default: Add ${subitem_title}.

min_len Integer indicating minimum number of acceptable subitems. Default: None (meaning no minimum).On the first rendering of a form including this sequence widget, at least this many subwidgets will berendered. The JavaScript sequence management will not allow fewer than this many subwidgets to bepresent in the sequence.

max_len Integer indicating maximum number of acceptable subwidgets. Default: None (meaning no maxi-mum). The JavaScript sequence management will not allow more than this many subwidgets to be addedto the sequence.

orderable Boolean indicating whether the Javascript sequence management will allow the user to explicitlyre-order the subwidgets. Default: False.

1.11. API Documentation 49

Page 54: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Note that the SequenceWidget template does not honor the css_class or style attributes of the widget.

class deform.widget.FileUploadWidget(tmpstore, **kw)Represent a file upload. Meant to work with a deform.FileData schema node.

This widget accepts a single required positional argument in its constructor: tmpstore. This argument shouldbe passed an instance of an object that implements the deform.interfaces.FileUploadTempStoreinterface. Such an instance will hold on to file upload data during the validation process, so theuser doesn’t need to reupload files if other parts of the form rendering fail validation. See alsodeform.interfaces.FileUploadTempStore.

Attributes/Arguments

template The template name used to render the widget. Default: file_upload.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/file_upload.

class deform.widget.DateInputWidget(**kw)Renders a date picker widget.

The default rendering is as a native HTML5 date input widget, falling back to pickadate(https://github.com/amsul/pickadate.js.)

Most useful when the schema node is a colander.Date object.

Attributes/Arguments

options Dictionary of options for configuring the widget (eg: date format)

template The template name used to render the widget. Default: dateinput.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textinput.

class deform.widget.DateTimeInputWidget(**kw)Renders a datetime picker widget.

The default rendering is as a pair of inputs (a date and a time) using pickadate.js(https://github.com/amsul/pickadate.js).

Used for colander.DateTime schema nodes.

Attributes/Arguments

date_options A dictionary of date options passed to pickadate.

time_options A dictionary of time options passed to pickadate.

template The template name used to render the widget. Default: dateinput.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textinput.

class deform.widget.DatePartsWidget(**kw)Renders a set of <input type=’text’/> controls based on the year, month, and day parts of the serializa-tion of a colander.Date object or a string in the format YYYY-MM-DD. This widget is usually meant to beused as widget which renders a colander.Date type; validation likely won’t work as you expect if you useit against a colander.String object, but it is possible to use it with one if you use a proper validator.

Attributes/Arguments

template The template name used to render the input widget. Default: dateparts.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/dateparts.

50 Chapter 1. Topics

Page 55: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

assume_y2k If a year is provided in 2-digit form, assume it means 2000+year. Default: True.

class deform.widget.FormWidget(**kw)The top-level widget; represents an entire form.

Attributes/Arguments

template The template name used to render the widget. Default: form.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/form.

item_template The template name used to render each item in the form. Default: mapping_item.

readonly_item_template The template name used to render each item in the form. Default:readonly/mapping_item.

class deform.widget.TextAreaCSVWidget(**kw)Widget used for a sequence of tuples of scalars; allows for editing CSV within a text area. Used with a schemanode which is a sequence of tuples.

Attributes/Arguments

cols The size, in columns, of the text input field. Defaults to None, meaning that the cols is not included inthe widget output (uses browser default cols).

rows The size, in rows, of the text input field. Defaults to None, meaning that the rows is not included in thewidget output (uses browser default cols).

template The template name used to render the widget. Default: textarea.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textarea.

class deform.widget.TextInputCSVWidget(**kw)Widget used for a tuple of scalars; allows for editing a single CSV line within a text input. Used with a schemanode which is a tuple composed entirely of scalar values (integers, strings, etc).

Attributes/Arguments

template The template name used to render the widget. Default: textinput.

readonly_template The template name used to render the widget in read-only mode. Default:readonly/textinput.

class deform.widget.ResourceRegistry(use_defaults=True)A resource registry maps widget requirement name/version pairs to one or more relative resources. A resourceregistry can be passed to a deform.Form constructor; if a resource registry is not passed to the form construc-tor, a default resource registry is used by that form. The default resource registry contains only mappings fromrequirement names to resources required by the built-in Deform widgets (not by any add-on widgets).

If the use_defaults flag is True, the default set of Deform requirement-to-resource mappings is loaded intothe registry. Otherwise, the registry is initialized without any mappings.

__call__(requirements)Return a dictionary representing the resources required for a particular set of requirements (as returnedby deform.Field.get_widget_requirements()). The dictionary will be a mapping from re-source type (js and css are both keys in the dictionary) to a list of asset specifications paths. Each assetspecification is a full path to a static resource in the form package:path. You can use the paths for eachresource type to inject CSS and Javascript on-demand into the head of dynamic pages that render Deformforms.

1.11. API Documentation 51

Page 56: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

set_css_resources(requirement, version, *resources)Set the CSS resources for the requirement/version pair, using resources as the set of relative resourcepaths.

set_js_resources(requirement, version, *resources)Set the Javascript resources for the requirement/version pair, using resources as the set of relativeresource paths.

deform.widget.default_resource_registryThe default resource registry (maps Deform-internal widget requirement strings to resource paths). Thisresource registry is used by forms which do not specify their own as a constructor argument, unlessdeform.Field.set_default_resource_registry() is used to change the default resource reg-istry.

1.12 Interfaces

The below are abstract interfaces expected to be fulfilled by various Deform implementations.

class deform.interfaces.FileUploadTempStoreThe deform.FileUploadWidget requires as its first argument a tmpstore. Such a tmpstore will imple-ment this interface: an object implementing the FileUploadTempStore interface should implement the methodsattached to this description.

Effectively, this interface is a subset of the dict interface plus an additional method named preview_url.In fact, the simplest possible implementation of this interface is:

class MemoryTmpStore(dict):def preview_url(self, name):

return None

However, the deform.FileUploadWidget does not remove data from the tempstore implementation ituses (it doesn’t have enough information to be able to do so), and it is job of the tempstore implementation itselfto expire items which haven’t been accessed in a while.

Therefore, the above MemoryTmpStore implementation is generally unsuitable for production, as the dataput into it is not automatically evicted over time and file upload data provided by untrusted users is usuallyunsuitable for storage in RAM. It’s more likely that an implementation in your application will center around asessioning library (such as Beaker) that does data eviction and which stores file upload data in persistent storage.

get(name, default=None)Same as dict.get.

__getitem__(name)Get a value.

__setitem__(name, value)Set a value.

__contains__(name)This should return True if we have a value for the name supplied, False otherwise.

preview_url(name)Return the preview URL for the item previously placed into the tmpstore named name or None if there isno preview for name available (or if this tmpstore does not support previewable items). This item shouldtypically return a URL to a thumbnail image.

52 Chapter 1. Topics

Page 57: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.13 Glossary

appstruct A raw application data structure (complex Python objects).

Chameleon chameleon is an attribute language template compiler which supports the ZPT (Zope Page Templates)templating specification. It is written and maintained by Malthe Borch.

Colander A schema package used by Deform to provide serialization and validation facilities.

cstruct Data serialized by Colander to a representation suitable for consumption by the serialize method of adeform widget, usually while a form is being rendered.

default renderer The template renderer used when no other renderer is specified. It uses the Chameleon templatingengine.

field An object in the graph generated by deform that has access to a schema node object and a widget object. Thescope of a field object is generally limited to the scope of a single HTTP request, so field objects are often usedto maintain state information during the request.

form controls A sequence of browser renderings of user interface elements. These are also known as “fields” as perthe the RFC 2388 definition of “field”, however Deform uses the term field for another concept, so we call themcontrols within the Deform documentation.

Gettext The GNU gettext library, used by the deform translation machinery.

jQuery jQuery is a JavaScript library for making client side changes to HTML.

JQuery UI A library used by Deform for various widget theming, effects and functionality: See http://jqueryui.com/.

jquery.autocomplete A jQuery plugin library that allows for autocompleting a value in a text input, making iteasier to find and select a value from a possibly large list. The data may be local or remote. See alsohttp://docs.jquery.com/Plugins/Autocomplete for more details.

jquery.maskedinput A JQuery plugin library that allows for input masks in text inputs. For example, a mask fora US telephone number might be (999)-999-9999. See also http://digitalbush.com/projects/masked-input-plugin/. Deform supports input masks in its default deform.widget.TextInputWidget widget.

jquery.ui.autocomplete A JQuery UI sublibrary for autocompletion of text fields. Seehttp://docs.jquery.com/UI/Autocomplete.

JSON JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read andwrite. See also http://www.json.org/.

Peppercorn A package used by Deform for structured form submission value deserialization.

pstruct Data deserialized by Peppercorn from one or more form controls to a representation suitable for consumptionby the deserialize method of a deform widget, usually while a form is being submitted.

renderer A callable with the signature (template_name, **kw) which is capable of rendering a template foruse in a deform widget.

renderer A function which accepts a logical template name and a set of keywords, and which returns the renderingof a widget template.

Resource registry An attribute of a Deform form which maps widget requirement declarations made by widgetsto relative file paths. Useful to obtain all the CSS and/or Javascript resources required by all the widgets in aconcrete form rendering. See also The (High-Level) deform.Field.get_widget_resources() Method.

schema A nested collection of schema node objects representing an arrangement of data.

schema node A schema node can serialize an appstruct to a cstruct and deserialize a cstruct to an appstruct (objectderived from colander.SchemaNode or one of the colander Schema classes). Schemas are a concept usedby Deform, but actually implemented and offered by the Colander package.

1.13. Glossary 53

Page 58: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

Sequence A widget which allows you to add multiple subwidgets, each of the same type.

TinyMCE Editor TinyMCE is a platform independent web based Javascript HTML WYSIWYG editor control re-leased as Open Source under LGPL by Moxiecode Systems AB. It has the ability to convert HTML TEXTAREAfields or other HTML elements to editor instances. TinyMCE is very easy to integrate into other Content Man-agement Systems.

validator A Colander validator callable. Accepts a node object and a value and either raises ancolander.Invalid exception or returns None. Used in deform as the validator= argument to a schemanode, ensuring that the input meets the requirements of the schema.

WebOb WebOb is a WSGI request/response library created by Ian Bicking.

widget Serializes a cstruct into a form rendering and deserializes a pstruct into a cstruct.

Widget requirement A sequence of tuples attached to a widget object representing the logical Javascript and/or CSSrequirements of the widget. See also Specifying Widget Requirements.

xhr xhr an XMLHTTPRequest. See also http://www.w3.org/TR/XMLHttpRequest/.

1.14 Deform Change History

1.14.1 Next release

• Make dateinput work again by using the fixed name “date” as expected by the pstruct schema. Seehttps://github.com/Pylons/deform/pull/221.

• Changed ISO8601_REGEX import to match change in colander

• Add support for Python 3.4, PyPy3.

• Raise Invalid rather than other errors when deserializing broken or malicious pstructs with invalid types. Seehttps://github.com/Pylons/deform/pull/203

• Readd a time widget.

• Fix a bug in the DateInputWidget. See https://github.com/Pylons/deform/pull/192.

• Ensured that None would not show up as a css class name in rendered template output. Seehttps://github.com/Pylons/deform/pull/191

• CSS class names normalized. Instead of camelCase names (e.g. deformSeq), we now use dashed-names (e.g.deform-seq). A full list of changes is below:

Old New

deformClosebutton deform-closebuttondeformFileupload deform-file-uploaddeformFormFieldset deform-form-fieldsetdeformInsertBefore deform-insert-beforedeformOrderbutton deform-orderbuttondeformProto deform-protodeformReplaces deform-replacesdeformSeq deform-seqdeformSeqAdd deform-seq-adddeformSeqContainer deform-seq-containerdeformSeqItem deform-seq-itemdeformSet-item deform-set-itemerrorMsg error-msgerrorMsgLbl error-msg-lbl

54 Chapter 1. Topics

Page 59: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• Fixed handling of buttons in nested sequences. See https://github.com/Pylons/deform/issues/197

1.14.2 2.0a2 (2013-10-18)

• PasswordWidget and CheckedPasswordWidget have grown an additional argument/attribute namedredisplay, which controls what happens on a validation failure of a form involving such a field. Ifredisplay is True (the default), the password will be re-rendered into the form when the form is re-rendered after validation failure. If redisplay is False, the password will not be re-rendered into theform. The default is False, which means that, as of this release, passwords will not be redisplayed;this changes the default behavior wrt previous releases. Values typed into password fields are not redis-played by default during validation failure, as a security measure (the value winds up in browser history).Use PasswordWidget(redisplay=True) or CheckedPasswordWidget(redisplay=True) tomake these widgets redisplay passwords on validation failures, matching the old behavior.

• When using the default Chameleon template renderer, template names can now be “asset speci-fications” e.g. mypackage:subdir1/subdir2/mytemplate.pt instead of extensionless pathsrelative to a search path. When template names are specified as asset specifications, thepkg_resources.resource_filename API is used to dereference them into an actual file path.

1.14.3 2.0a1 (2013-10-05)

This is an alpha release of Deform v2. Deform v2 is backwards incompatible with Deform v1. It requires the use ofTwitter Bootstrap v3, whereas deform v1 did not require Bootstrap.

A demonstration site that shows Deform 2 in action exists at http://deform2demo.repoze.org.

Both Deform 1 and Deform 2 will be maintained going forward. If you wish to continue using Deform 1, becauseyou cannot upgrade, or cannot depend on Bootstrap 3, please pin your deform distribution requirement to somethingbelow 2.0a1, e.g. deform<=1.999.

This first alpha release is missing formal documentation updates. Apologies, we needed to get a release out ontoPyPI, as not having one is holding back the development of a number of platforms and applications that dependon the changes in v2+. Documentation updates will be forthcoming over the lifetime of future alpha/beta releases.However, below is a list of known issues that need to be addressed to make a final release of Deform 2, as wellas information about new features, and migration notes. You may also be able to make use of the demo site athttp://deform2demo.repoze.org to divine how things have changed, and what CSS and JavaScript resources you’llneed to include in your pages to make use of this release.

TODO

• docs

• decide how to explain form.css (include in requirements or?)

• horizontal/inline forms + structural things

• assets for templates: deform should provide a tool to resolve that?

• placeholder support for all textual inputs (and required/maxlength see alsohttps://github.com/Pylons/deform/pull/116)

• display help-blocks for readonly fields?

• maybe readonly should be a property of the schema, not the widget.

• consider whether “style”/”css_class” on multi-input widgets should apply to a container or each element.

• audit use of e.g. string:${css_class} so we don’t see unexpected class=”None” in widget rendering output.

• some sort of test for mapping_item input_prepend/input_append

1.14. Deform Change History 55

Page 60: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• Currently description shows up as both tooltip of label and as help-block. Maybe make these two things separateor at least don’t show them both using the same value.

• normalize CSS class names to deform-foo rather than deformFoo

• sequence_of_sequences: js that processes close/order buttons has to be less promiscuous (it uses e.g. “find”);symptom: buttons appear/disappear, act on the wrong element, etc... ugh 2013/10/05 cannot replicate, but stillbelieve there may be an issue, but maybe iElectric fixed it

NICE TO HAVE

• structural widget (mapping_item.pt) - do we need that or not or what? + add a demo

• prepend/append t.bootstrap stuff

• https://github.com/Pylons/deform/pull/116#issuecomment-23210460

• group demos by widget type

• handle ajax demo more UX friendly

• Put drag handles in panel headers: https://github.com/Pylons/deform/issues/180

NEW FEATURES:

• input_prepend/input_append in mapping_item widget.

• field.parent

• field.get_root

• inline attr of checkboxchoice and radiochoice widgets (see https://github.com/Pylons/deform/pull/182)

• http://deform2demo.repoze.org/

MIGRATION NOTES:

• removed deprecated height, width, skin, theme parameters from RichTextWidget (use “options” instead)

• removed deprecated render_initial_item from SequenceWidget

• removed deprecated deform.Set (use colander.Set instead)

• DateInputWidget renamed parameter dateFormat to format (dateFormat now unsupported).

• DateTimeInputWidget now renders as two fields: one for a date and one for a time, using pickadate.

• We no longer bother trying to use the native datetimeinput widget on any browser, because the support is sospotty.

• DateTimeInputWidget takes two options now: date_options and time_options instead of a single options dictio-nary. The options are pickadate date/time options respectively.

• It is no longer possible to do DateTimeWidget().options[’a’] = ‘foo’ or DateTimeWidget().date_options[’a’] =‘foo’. If you need to change options imperatively, set the entire .options/.date_options dictionary.

• merged TypeaheadInputWidget to AutocompleteInputWidget (removed delay parameter)

• AutocompleteInputWidget now accepts string type for “values”

• widgets no longer accepts “size” (instead use style=”width: x”), except SelectWidget (it means the size of thedropdown)

• get_widget_resources now returns asset specifications rather than deform-static-relative paths

• deform 2.0 requires users to manually load TB 3.0 and jquery 2.0

• required labels no longer insert an asterisk inside a <span class=”req”> inside themselves. instead the labelelement has a required class if the field is required; use form.css to display this as an asterisk.

56 Chapter 1. Topics

Page 61: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• min_length of AutocompleteInputWidget now defaults to 1 (was 2)

1.14.4 0.9.9 (2013-09-23)

1.15 Bug Fixes

• rename country specific locales to only include language [iElectric]

• Un-break single select widget. See https://github.com/Pylons/deform/issues/181

1.15.1 0.9.8 (2013-09-01)

1.16 Features

• deform.widget.RichTextWidget now accepts a dict/two-tuple options for specifying arbitrary op-tions to pass to TinyMCE’s init function. All default options are now part of the class itself (where possible)and can be customised by using options. [davidjb]

• Widgets now accept an item_css_class argument. This argument, when provided, sets a class value on thetop level element of the item template which surrounds the widget (usually an <li>).

• DateTime widget now handles stripping timezones from ISO-formatted strings that include microseconds. Pre-viously it would just choke.

1.17 Bug Fixes

• Trigger a change event when adding/removing sequence items.

• Add optional label to checkbox widget.

• Raise a ValueError exception when the prototype for a field in a sequence has no name. Seehttps://github.com/Pylons/deform/issues/149

• Worked on the templates to make as many widgets be proper HTML. Deformdemo now includes a validatorwhich can be used for checking. The major changes involve ensuring that only <li> can be children of <ul>and that labels always refer to distinct fields. Also labels are set around fields to provide better touch targets:you can click on the label as well as the field. Validation still raises some errors about invalid attributes such asprototype but these can be safely ignored: browsers will ignore things they don’t know about - this is defined inHTML 5 (it used to be guess work). Having the right <label> added a wart to mappings where the first itemdoesn’t get a counter because the label is already assigned. This may be revisited as it seems to affect onlymappings. See https://github.com/Pylons/deformdemo/pull/20 for further context.

1.17.1 0.9.7 (2013-03-06)

1.18 Bug Fixes

• Readonly checkbox template had a logic error.

1.15. Bug Fixes 57

Page 62: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.19 Documentation

• Corrected the expected server response when using the Autocomplete widget.

1.19.1 0.9.6 (2013-01-10)

1.20 Bug Fixes

• Fixed remove bug in nested sequences. See https://github.com/Pylons/deform/pull/89

• Fixed bug wherein items added to a sequence nor the initial items rendered in a sequence would not reflect thecorrect defaults of the item widget. See https://github.com/Pylons/deform/pull/79

• Fix bug where native datetime/date widget rendering competed with jQuery datetime/date widget rendering.See https://github.com/Pylons/deform/pull/142

1.21 Dependencies

• Depend on and use zope.deprecation to deprecate Set class.

• Deform now depends on Colander >= 1.0a1 (previously it depended on >= 0.8). It requires Colander 1.0a1’snewer cstruct_children and appstruct_children methods of schema objects as well as being ableto import objects from Colander that don’t exist in earlier versions.

• Deform now depends on Chameleon >= 2.5.1 (previously it depended on >= 1.2.3). It requires the Markup classsupplied by this version or better.

• Deform no longer has a setup_requires dependency on setuptools_git (useless, as the version on PyPI is broken).

• Setup.py now includes all testing requirements in tests_require that are in testing extras and vice versa.

1.22 Features

• Allow SelectWidget to produce <optgroup> HTML tags. See https://github.com/Pylons/deform/pull/87

• Allow deform.form.Form constructor to accept an autocomplete keyword argument, which controlsthe autocomplete attribute of the form tag.

• Add Python 3.3 Trove classifier.

• Pass through unknown keys in a filedict FileData serialization (FBO of passing out of band information).

• deform.Set type deprecated in favor of use of colander.Set.

• Give the preview_url method of the tempstore access to the stored item. [tomster]

• Add style attribute/arguments to textinput-related widgets allowing you to set the style of the tag by hand.

• Allow deform.widget.SequenceWidget constructor to accept an orderable keyword argument. De-fault is False. If True, allow drag-and-drop reordering of SequenceWidget items (via jQuery UI Sortable).

• The default widget for the colander.Money type is now deform.widgets.MoneyInputWidget.

• Built-in widgets may have a ‘readonly’ attribute/constructor-argument, to indicate that a form field associatedwith the widget should use its readonly template instead of its normal readwrite template. A readonly key-word argument can still be passed to Field.serialize to render a field as readonly, like in older versions.

58 Chapter 1. Topics

Page 63: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• deform.field.Field now has a __contains__ method, which returns True if the named field is asubfield of the field on which it is called.

• deform.field.Field now has a validate_pstruct method which works like validate except itaccepts a pstruct directly instead of accepting a list of controls.

• deform.field.Field.validate now accepts a subcontrol argument for validating a submappingof a form.

• In support of “retail” form rendering, the serialize method of widgets now accepts arbitrary keyword argu-ments. These are used as top-level value overrides to widget templates.

• In support of “retail” form rendering, the serialize method of a Field now accepts arbitrary keyword argu-ments. These are passed along to it’s widget’s serialize method.

• It is now possible to pass an appstruct argument to the deform.Field (and by extension, thedeform.Form) constructor. When you do so, you can omit passing an appstruct argument to the rendermethod of the field/form. Fields set a cstruct value recursively when supplied with an appstruct argumentto their constructor. This is in support of “retail” form rendering.

• Form/field objects are now initialized with a cstruct (recursively) when created. This means that accessingform.cstruct will return the current set of rendering values. This value is reset during validation, so after avalidation is done you can re-render the form to show validation errors. This is in support of “retail” formrendering.

• Form/field objects now have peppercorn-field-outputting methods: start_mapping, end_mapping,start_sequence, end_sequence, start_rename, end_rename in support of retail form rendering.

• The deform.Field (and therefore deform.Form) classes now expose a render_template method,which injects field and cstruct into the dictionary passed to the template if they don’t already exist in the**kw passed. This is in support of retail form rendering.

• Add set_appstruct and set_pstruct methods to Field; these accept, respectively, an appstruct or apstruct and set the cstruct related to the field to the deserialized or serialized value.

1.23 Documentation

• Add a (weak) “Retail Form Rendering” chapter to the docs.

1.23.1 0.9.5 (2012-04-27)

• Add translations for TinyMCE. Thanks OCHIAI, Gouji.

• Japanese translation thanks to OCHIAI, Gouji.

• Modified Russian translation thanks to aleksandr.rakov

• Date(Time)Widget supports now options to configure it, thx to gaston tjebbes, kiorky

• FileUploadWidget now sanitizes IE/Windows whole-path filenames before passing them back to the caller dur-ing deserialization/validation.

• Add docs and dev setup.py aliases ala Pyramid.

• Add MoneyInputWidget widget type.

• Allow a custom i18n domain to be used for the “Add ${subitem_title}” link of a SequenceWidget. Seehttps://github.com/Pylons/deform/issues/85 .

• Allow the use of Integer values with SelectWidget. See https://github.com/Pylons/deform/issues/81 .

1.23. Documentation 59

Page 64: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• CheckedInputWidget and CheckedPasswordWidget now populate the “confirm” element with the cstruct value(for edit forms).

• Update to JQuery 1.7.2.

• Update to jquery.form 3.09.

1.23.2 0.9.4 (2012-02-14)

• No longer Python 2.5 compatible. Python 2.6+ is required.

• Python 3.2 compatible.

• Translate title attribute for remove button in sequence fields.

• Do not output empty error messages for sequence items. After translation these would insert the PO file meta-data.

• Update to lingua for translations, add french translation

• fix multiple i18n issues.

• Fix a bug where displaying error could lead on an error when you have imbricated Mapping objects

• Fix issue #54: form.pt does not show validation errors from the top node of the schema. Seehttps://github.com/Pylons/deform/issues/54 for more information.

• Previously, all CheckedInputWidget and CheckedPasswordWidget fields had hardcoded input[name] attributesof ‘value’ and ‘confirm’. When deserializing a form, this caused colander.null to be passed to the widget dese-rialization function since neither submitted value matched the name of the field. This change simply replaces‘value’ with the name of the field and ‘confirm’ with the name of the field with ‘-confirm’ appended.

• In select widget, add css_class to <select> rather than only <option>.

• Allow RichText fields to load their editor only after clicking on them

• There is no longer a deform_ajaxify global javascript function. Instead forms are AJAXified directly bythe javascript callback for the form.

1.23.3 0.9.3 (2011-08-10)

• Update Dutch translations.

• Translate title and description of items for sequence fields.

• Add a new API method to field objects: translate. This method will use the translator passed to the under-lying renderer to translate message ids into text.

1.23.4 0.9.2 (2011-07-22)

• Chameleon 2 compatibility.

• Use default widgets for a schema’s baseclass if known instead of always falling back to a text widget.

• Deform now includes a beautify.css (contributed by Ergo^) in its static directory, which can be used tomake form element styling prettier.

• Moved deformdemo into its own package and Github repository (https://github.com/Pylons/deformdemo).

60 Chapter 1. Topics

Page 65: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.23.5 0.9.1 (2011-06-23)

• Add Dutch translation.

• Add the deform.widget.DateTimeWidget widget, which uses the jQueryUI Timepicker add-on.

DateTimeWidget uses the ISO8601 combined date and time format internally, as expected bycolander.DateTime, but converts to the more friendly separate date and time format for display in thewidget.

This widget is now the default for colander.DateTime schema types.

• Upgrade to jquery-ui 1.8.11, as required by the timepicker.

• Compile all .po files to .mo in deform/locale and remove Texan locale (funny, but breaks pythonsetup.py compile_catalog with an UnknownLocale error.)

• Fix references to repoze.bfg and update obsoletes URLs in the demo application

• Remove unused jquery.autocomplete.min.js file from static directory.

• SelectWidget now has a size attribute to support single select widgets that are not dropdowns.

• The value fed to the deform.form.Button class as name would generate an invalid HTML idif it contained spaces. Now it converts spaces to underscores if they exist in the name. Seehttps://github.com/Pylons/deform/pull/14 .

• Deformdemo application now has a Time field demonstration.

• Deform Chameleon templates now contain i18n:translate tags.

• German translation updated.

• Fixed invalid HTML generated for “select” widget.

• When using an ajax form without a redirect, a submit overwrites the form. In the case of a form validationfailure on first submit, no event handlers were registered to submit the form via ajax on the second submit. Thisis now fixed. See https://github.com/Pylons/deform/pull/1 .

1.23.6 0.9 (2011-03-01)

• Moved to GitHub (https://github.com/Pylons/deform).

• Added tox.ini for testing purposes.

• Fix select dropdown behavior on Firefox by fixing CSS (closes http://bugs.repoze.org/issue152).

• Removed wufoo.css, minimized form.css. Changed templates around to deal with CSS changes.

• Sequence widgets now accept a min_len and a max_len argument, which influences its display of close and addbuttons.

• Convert demo application from repoze.bfg to Pyramid.

• Depend on Chameleon<1.999 (deform doesn’t yet work with Chameleon 2).

1.23. Documentation 61

Page 66: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.23.7 0.8.1 (2010-12-17)

1.24 Features

• Allow deform.form.Button class to be passed a disabled flag (false by default). If a Button is disabled,its HTML disabled setting will be set true.

1.24.1 0.8 (2010-12-02)

1.25 Features

• Added Polish locale data: thanks to Marcin Lulek.

1.26 Bug Fixes

• Fix dynamic sequence item adding on Chrome and Firefox 4. Previously if there was a validation error renderinga set of sequence items, the “add more” link would be rendered outside the form, which would cause it to notwork. Wrapping the sequence item <li> element in a <ul> fixed this.

1.26.1 0.7 (2010-10-10)

1.27 Features

• Added Danish locale.

• Added Spanish locale: thanks to David Cerna for the translations!

• DatePartsWidget now renders error “Required” if all blank or “Incomplete” if partially blank for consis-tency with the other widgets.

• Different styling involving <li> and <ul> for checkbox choice, checked input, radio choice, checked password,and dateparts widgets (via Ergo^). See http://bugs.repoze.org/issue165.

1.28 Dependencies

• Deform now depends on colander version 0.8 or better (the demo wants to use schema bindings).

• Deform now depends on Chameleon (uppercase) rather than chameleon to allow for non-PyPI servers.

1.29 Demo

• New addition to the demonstration application: schema binding.

62 Chapter 1. Topics

Page 67: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.29.1 0.6 (2010-09-03)

1.30 Features

• Sequence widgets are no longer structural by default; they now print the label of the sequence above thesequence adder.

• Radio buttons in a radio button choice widget are now spaced closer together and the button is on the left handside.

• The sequence remove button is no longer an image.

• The sequence widget now puts the sequence adding link after any existing items in the sequence (previously thelink was always beneath the sequence title).

• It is now possible to associate a widget with a schema node within the schema directly. For example:

import colanderimport deform.widget

class MySchema(Schema):description = colander.SchemaNode(

colander.String(),widget=deform.widget.RichTextWidget())

For more information, see “Changing the Default Widget Associated With a Field” in the documentation.

• The constructor of deform.Field objects (and thus deform.Form objects) now accept arbitrary keywordarguments, each of which is attached to the field or form object being constructed, as well as being attached toits descendant fields recursively.

• The form object’s template now respects the css_class argument / attribute of the form node.

• CheckboxChoice and RadioChoice widgets now use <ul> and <li> to display individual choice elements (thanksto Ergo^), and both widgets put the label after the element instead of before as previously.

• The deform.widget.AutocompleteInputWidget widget now uses JQuery UI’s autocomplete subli-brary <http://docs.jquery.com/UI/Autocomplete> instead of the jquery.autocomplete library to performits job in order to reduce the number of libraries needed by Deform. Some options have been changed as aresult, and the set of resources returned by form.get_widget_resources has changed.

This change also implies that when a widget which uses a remote URL as a values input, the remote URLmust return a JSON structure instead of a \n-delimited list of values.

1.31 Requirements

• This Deform version requires colander version 0.7.3 or better.

1.32 Bug Fixes

• RichTextWidget, AutocompleteInputWidget, TextInputWidget with input masks, andCheckedInputWidget with input masks could not be used properly within sequences. Now they can be.See also Internal and Backwards Incompatibilities within this release’s notes. This necessitatednew required deform.load() and deform.addCallback() JavaScript APIs.

1.30. Features 63

Page 68: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• Radio choice widgets included within a submapping no longer put their selections on separate lines.

• Rich text widgets are now 500 pixels wide by default instead of 640.

• RadioChoiceWidgets did not work when they were used within sequences. Making them work required somechanges to the its template and it added a dependency on peppercorn >= 0.3.

• To make radio choice widgets work within sequences, the deform.addSequenceItem JavaScript method neededto be changed. It will now change the value of name attributes which contain a marker that looks like anfield oid (e.g. deformField1), and, like the code which changes ids in the same manner, appends a randomcomponent (e.g. deformField1-HL6sgP). This is to support radio button groupings.

• The mapping and sequence item templates now correctly display errors with msg values that are lists. Previ-ously, a repr of a Python list was displayed when a widget had an error with a msg value that was a list; nowmultiple <p> nodes are inserted into the rendering, each <p> node containing an individual error message. (Notethat this change requires colander 0.7.3).

1.33 Backwards Incompatibilities

• The JavaScript function deform.load() now must be called by the HTML page (usually in a script tag nearthe end of the page, ala <script..>deform.load()</script>) which renders a Deform form in orderfor widgets which use JavaScript to do proper event and behavior binding. If this function is not called, built-inwidgets which use JavaScript will no longer function properly.

• The JavaScript function deformFocusFirstInput was removed. This is now implied bydeform.load().

• The closebutton_url argument to the SequenceWidget no longer does anything. Style the widget templatevia CSS to add an image.

1.34 Internal

• Provided better instructions for running the demo app and running the tests for the demo app indeformdemo/README.txt.

• Try to prevent false test failures by injecting sleep statements in things that use browser.key_press.

• Moved deformdemo/tests/test_demo.py to deformdemo/test.py as well as mov-ing deformdemo/tests/selenium.py to deformdemo/selenium.py. Removed thedeformdemo/tests subdirectory.

• The date input widget now uses JQueryUI’s datepicker functionality rather than relying on JQuery Tools’date input. The latter was broken for sequences, and the former works fine.

• The various deform* JavaScript functions in deform.js have now been moved into a top-level namespace.For example, where it was necessary to call deformFocusFirstInput() before, it is now necessary tocall deform.focusFirstInput().

• Make the TinyMCE rich text widget use mode: ’exact’ instead of mode: ’textareas’.

• richtext, autocomplete_input, textinput, checked_input, and dateinput, and form tem-plates now use the new deform.addCallback indirection instead of each registering their own JQuerycallback or performing their own initialization logic, so that each may be used properly within sequences.

• Change sequence adding logic to be slightly simpler.

• The sample app form page now calls deform.load() rather than deformFocusFirstInput().

64 Chapter 1. Topics

Page 69: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• Added new demo app views for showing a sequence of autocompletes, a sequence of dateinputs, a sequence ofrichtext fields, a sequence of radio choice widgets and a sequence of text inputs with masks and tests for same.

1.35 Documentation

• Added a note about get_widget_resources to the “Basics” chapter.

• Added a note about deform.load() JavaScript requiredness to the “Basics” chapter.

• Add new top-level sections named Widget Templates and Widget JavaScript to the “Widgets”chapter.

1.35.1 0.5 (2010-08-25)

1.36 Features

• Added features which make it possible to inquire about which resources (JavaScript and CSS resources) arerequired by all the widgets that make up a form rendering. Also make it possible for a newly created widget tospecify its requirements. See “Widget Requirements and Resources” in the widgets chapter of the documenta-tion.

• Add the get_widget_requirements method to deform.Field objects.

• Add the get_widget_resources method to deform.Field objects.

• Allow deform.Field (and deform.Form) objects to accept a “resource registry” as a constructor argu-ment.

• Add the deform.Field.set_widgets method, which allows a (potentially nested) set of widgets to beapplied to children fields of the field upon which it is called.

• Add the deform.widget.TextInputCSV widget. This widget is exactly like thedeform.widget.TextAreaCSV widget except it accepts a single line of input only.

• The default widget for colander.Tuple schema types is now deform.widget.TextInputCSV.

• The deform.widget.FileUploadWidget now returns an instance of deform.widget.filedictinstead of a plain dictionary to make it possible (using isinstance) to tell the difference between file upload dataand a plain data dictionary for highly generalized persistence code.

1.36.1 0.4 (2010-08-22)

1.37 Bug Fixes

• When the hidden widget is used to deserialize a field, return colander.null rather than the empty stringso that it may be used to represent non-text fields such as colander.Integer. This is isomorphic to thechange done previously to deform.TextInputWidget to support nontextual empty fields.

• Fix typo about overriding templates using set_zpt_renderer in templating chapter.

• Fix link to imperative schema within in Colander docs within “Basics”.

• Remove duplicate deform.widget.DateInputWidget class definition.

1.35. Documentation 65

Page 70: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

1.38 Features

• Add a deform.widget.RichTextWidget widget, which adds the TinyMCE WYSIWIG javascript editorto a text area.

• Add a deform.widget.AutocompleteInputWidget widget, which adds a text input that can be sup-plied a URL or iterable of choices to ease the search and selection of a finite set of choices.

• The deform.widget.Widget class now accepts an extra keyword argument in its constructor:css_class.

• All widgets now inherit a css_class attribute from the base deform.widget.Widget class. If css_class‘contains a value, the “primary” element in the rendered widget will get a CSS class attribute equal to the value(“primary” is defined by the widget template’s implementor).

• The deform.Field class now as an __iter__ method which iterates over the children fields of the fieldupon which it is called (for item in field == for item in field.children).

1.38.1 0.3 (2010-06-09)

1.39 Bug Fixes

• Change default form action to the empty string (rather than .). Thanks to Kiran.

1.40 Features

• Add deform.widget.DateInputWidget widget, which is a date picker widget. This has now becomethe default widget for the colander.Date schema type, preferred to the date parts widget.

• Add text input mask capability to deform.widget.TextInputWidget.

• Add text input mask capability to deform.widget.CheckedInputWidget.

1.41 Backwards Incompatibilities

• Custom widgets must now check for colander.null rather than None as the null sentinel value.

• Dependency on a new (0.7) version of Colander, which has been changed to make using proper defaults possible;if you’ve used the default argument to a colander.SchemaNode, or if you’ve defined a custom Colandertype, you’ll want to read the updated Colander documentation (particularly the changelist). Short story: use themissing argument instead.

• If you’ve created a custom widget, you will need to tweak it slightly to handle the value colander.nullas input to both serialize and deserialize. See the Deform docs at http://docs.repoze.org/deform formore information.

1.41.1 0.2 (2010-05-13)

• Every form has a formid now, defaulting to deform. The formid is used to compute the id of the form tag aswell as the button ids in the form. Previously, if a formid was not passed to the Form constructor, no id wouldbe given to the rendered form and the form’s buttons would not be prefixed with any formid.

66 Chapter 1. Topics

Page 71: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

• The deform.Form class now accepts two extra keyword arguments in its constructor: use_ajax andajax_options.

If use_ajax is True, the page is not reloaded when a submit button is pressed. Instead, the form is posted,and the result replaces the DOM node on the page.

ajax_options is a string which allows you to pass extra options to the underlying AJAX form machinerywhen use_ajax is True.

• Added a couple Ajax examples to the demo app.

• Add a rudimentary Ajax chapter to the docs.

1.41.2 0.1 (2010-05-09)

• Initial release.

1.41. Backwards Incompatibilities 67

Page 72: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

68 Chapter 1. Topics

Page 73: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

CHAPTER 2

Demonstration Site

Visit deform2demo.repoze.org to view an application which demonstrates most of Deform’s features. The source codefor this application is also available in the deform package on GitHub.

69

Page 74: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

70 Chapter 2. Demonstration Site

Page 75: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

CHAPTER 3

Support and Development

To report bugs, use the bug tracker.

If you’ve got questions that aren’t answered by this documentation, contact the Pylons-discuss mailing list or join the

#pylons IRC channel irc://irc.freenode.net/#pylons.

Browse and check out tagged and trunk versions of deform via the deform package on GitHub. To check out thetrunk, use this command:

git clone git://github.com/Pylons/deform.git

To find out how to become a contributor to deform, please see the Pylons Project contributor documentation.

71

Page 76: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

72 Chapter 3. Support and Development

Page 77: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

CHAPTER 4

Index and Glossary

• genindex

• modindex

• search

73

Page 78: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

74 Chapter 4. Index and Glossary

Page 79: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

CHAPTER 5

Thanks

Without these people, this software would not exist:

• The Formish guys (http://ish.io)

• Tres Seaver

• Fear Factory (http://fearfactory.com)

• Midlake (http://midlake.net)

75

Page 80: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

76 Chapter 5. Thanks

Page 81: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

Python Module Index

ddeform, 32deform.interfaces, 52deform.widget, 42

77

Page 82: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

78 Python Module Index

Page 83: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

Index

Symbols__call__() (deform.widget.ResourceRegistry method), 51__contains__() (deform.Field method), 34__contains__() (deform.interfaces.FileUploadTempStore

method), 52__getitem__() (deform.Field method), 34__getitem__() (deform.interfaces.FileUploadTempStore

method), 52__iter__() (deform.Field method), 34__setitem__() (deform.interfaces.FileUploadTempStore

method), 52

Aappstruct, 53AutocompleteInputWidget (class in deform.widget), 44

BButton (class in deform), 40

CChameleon, 53CheckboxChoiceWidget (class in deform.widget), 47CheckboxWidget (class in deform.widget), 46CheckedInputWidget (class in deform.widget), 46CheckedPasswordWidget (class in deform.widget), 46clone() (deform.Field method), 34Colander, 53cstruct, 53

DDateInputWidget (class in deform.widget), 50DatePartsWidget (class in deform.widget), 50DateTimeInputWidget (class in deform.widget), 50default renderer, 53default_options (deform.widget.RichTextWidget at-

tribute), 45default_renderer (in module deform), 42default_resource_registry (in module deform.widget), 52deform (module), 32deform.interfaces (module), 52

deform.widget (module), 42deserialize() (deform.Field method), 34deserialize() (deform.widget.Widget method), 43

Eend_mapping() (deform.Field method), 34end_rename() (deform.Field method), 34end_sequence() (deform.Field method), 34errormsg (deform.Field attribute), 34

Ffield, 53Field (class in deform), 32FileData (class in deform), 40FileUploadTempStore (class in deform.interfaces), 52FileUploadWidget (class in deform.widget), 50Form (class in deform), 39form controls, 53FormWidget (class in deform.widget), 51

Gget() (deform.interfaces.FileUploadTempStore method),

52get_root() (deform.Field method), 34get_widget_requirements() (deform.Field method), 34get_widget_resources() (deform.Field method), 35Gettext, 53

Hhandle_error() (deform.widget.Select2Widget method),

48handle_error() (deform.widget.Widget method), 43HiddenWidget (class in deform.widget), 45

JjQuery, 53JQuery UI, 53jquery.autocomplete, 53jquery.maskedinput, 53jquery.ui.autocomplete, 53

79

Page 84: deform Documentation - Read the Docs Documentation, Release 2.0a2 The preparer of a schema node is called after deserialization but before validation; it prepares a deserialized value

deform Documentation, Release 2.0a2

JSON, 53

MMappingWidget (class in deform.widget), 49MoneyInputWidget (class in deform.widget), 44

OOptGroup (class in deform.widget), 47options (deform.widget.RichTextWidget attribute), 46

PPeppercorn, 53preview_url() (deform.interfaces.FileUploadTempStore

method), 52pstruct, 53

RRadioChoiceWidget (class in deform.widget), 48render() (deform.Field method), 35render() (deform.ValidationFailure method), 41render_template() (deform.Field method), 35renderer, 53Resource registry, 53ResourceRegistry (class in deform.widget), 51RichTextWidget (class in deform.widget), 45

Sschema, 53schema node, 53Select2Widget (class in deform.widget), 48SelectWidget (class in deform.widget), 47Sequence, 54SequenceWidget (class in deform.widget), 49serialize() (deform.Field method), 35serialize() (deform.FileData method), 40serialize() (deform.widget.Widget method), 43set_appstruct() (deform.Field method), 35set_css_resources() (deform.widget.ResourceRegistry

method), 51set_default_renderer() (deform.Field class method), 36set_default_resource_registry() (deform.Field class

method), 36set_js_resources() (deform.widget.ResourceRegistry

method), 52set_pstruct() (deform.Field method), 36set_widgets() (deform.Field method), 36set_zpt_renderer() (deform.Field class method), 37start_mapping() (deform.Field method), 37start_rename() (deform.Field method), 37start_sequence() (deform.Field method), 37

TTemplateError (class in deform), 41

TextAreaCSVWidget (class in deform.widget), 51TextAreaWidget (class in deform.widget), 45TextInputCSVWidget (class in deform.widget), 51TextInputWidget (class in deform.widget), 43TinyMCE Editor, 54translate() (deform.Field method), 34, 37

Vvalidate() (deform.Field method), 37validate_pstruct() (deform.Field method), 38ValidationFailure (class in deform), 41validator, 54

WWebOb, 54widget, 54Widget (class in deform.widget), 42Widget requirement, 54

Xxhr, 54

ZZPTRendererFactory (class in deform), 41

80 Index