Add forms¶
Forms to create new content objects
An add form, as its name implies, is used to add content to a container. Add forms are usually registered as views on a container. For generic CMF or Plone content, the IFolderish interface is normally a good candidate. The fields in an add form usually represent the fields in the type that is being added.
Note
If you are using Dexterity or Archetypes, these frameworks have their own add form factories, which you probably want to use instead of the more basic version described here.
Add forms derive from z3c.form.form.AddForm, which is extended by plone.directives.form.AddForm and plone.directives.form.SchemaAddForm, adding grok support and standard Plone semantics.
To use an add form, you must implement two methods - create() and add(). The form then takes care of emitting the proper events and directing the user to the newly added content item. You can also set the immediate_view property to the URL of a page to visit after adding the content item.
from five import grok
from plone.supermodel import model
from plone.directives import form
from z3c.form import button, field
from Products.CMFCore.interfaces import IFolderish
class IMyType(model.Schema):
...
class MyAddForm(form.SchemaAddForm):
grok.name('add-my-type')
grok.require('cmf.AddPortalContent')
grok.context(IFolderish)
schema = IMyType
label = _(u"Add my type of content")
description = _(u"A sample form.")
def create(self, data):
type = MyType()
type.id = data['id']
type.title = data['title']
...
return type
def add(self, object):
self.context._setObject(object.id, object)
create() is called after validation, and is passed a dictionary of marshalled form fields. It should construct and return the object being added. That object is then passed to add() (after an object-created event has been fired), which should add it, normally to self.context (the container).
A non-schema version would look like this:
from five import grok
from plone.supermodel import model
from plone.directives import form
from z3c.form import button, field
from Products.CMFCore.interfaces import IFolderish
class IMyType(model.Schema):
...
class MyAddForm(form.AddForm):
grok.name('add-my-type')
grok.require('cmf.AddPortalContent')
grok.context(IFolderish)
fields = field.Fields(IMyType)
label = _(u"Add my type of content")
description = _(u"A sample form.")
def create(self, data):
type = MyType()
type.id = data['id']
type.title = data['title']
...
return type
def add(self, object):
self.context._setObject(object.id, object)