Dexterity XML¶
A reference for Dexterity's XML name spaces
Introduction¶
The schema (structure) of a Dexterity content type may be detailed in two very different ways:
- In Python as a Zope schema; or,
- In XML
When you are using Dexterity's through-the-web schema
editor, all your work is being saved in the content type's
Factory Type Information (FTI) as XML.
plone.supermodel
dynamically translates that XML into Python objects which
are used to display and edit your content objects.
The XML model of your content object may be exported from Dexterity and incorporated into a Python package. That's typically done with code like:
class IExampleType(form.Schema):
form.model("models/example_type.xml")
or:
from plone.supermodel import xmlSchema
IExampleType = xmlSchema("models/example_type.xml")
XML models in a package may be directly edited. (Dexterity will probably also include a TTW XML-model editor at some point in the future.)
This document is a reference to the tags and attributes you may use in model XML files. This includes several form-control and security-control attributes that are not available through the TTW schema editor.
XML Document Structure¶
Dexterity requires that its model XML be well-formed XML, including name space declarations. The typical structure of a Dexterity XML document is:
<?xml version="1.0" encoding="UTF-8"?>
<model xmlns="http://namespaces.plone.org/supermodel/schema"
xmlns:form="http://namespaces.plone.org/supermodel/form"
xmlns:security="http://namespaces.plone.org/supermodel/security">
<schema>
<field type="zope.schema.TextLine" name="one"
<title>One</title>
... More field attributes
</field>
... More fields
</schema>
</model>
Only the default name space (.../supermodel/schema) is
required for basic schema. The
supermodel/form
and
supermodel/schema
provide additional attributes to control form presentation
and security.
supermodel/schema fields¶
Most of the supermodel/schema field tag and its attributes map directly to what's available via the TTW schema editor:
<field name="dummy" type="zope.schema.TextLine">
<default>abc</default>
<description>Test desc</description>
<max_length>10</max_length>
<min_length>2</min_length>
<missing_value>m</missing_value>
<readonly>True</readonly>
<required>False</required>
<title>Test</title>
</field>
The field
type
needs to be the full dotted name (as if it was being
imported in Python) of the field type.
Fieldsets¶
It's easy to add fieldsets by surrounding embedding
fields tags in a
fieldset
block:
<schema>
...
<fieldset name="test"
label="Test Fieldset"
description="Description of test fieldset">
<field name="three" type="zope.schema.TextLine">
<description/>
<title>Three</title>
</field>
<field name="four" type="zope.schema.TextLine">
<description/>
<title>Four</title>
</field>
</fieldset>
...
</schema>
Vocabularies¶
Vocabularies may be specified via dotted names using the
source
tag:
<field name="dummy" type="zope.schema.Choice">
<default>a</default>
<description>Test desc</description>
<missing_value/>
<readonly>True</readonly>
<required>False</required>
<title>Test</title>
<source>plone.supermodel.tests.dummy_vocabulary_instance</source>
</field>
Where the full Python dotted-name of a Zope vocabulary in a package:
from zope.schema.vocabulary import SimpleVocabulary
dummy_vocabulary_instance = SimpleVocabulary.fromItems([(1, 'a'), (2, 'c')])
Or, a source binder:
<field name="dummy" type="zope.schema.Choice">
...
<source>plone.supermodel.tests.dummy_binder</source>
</field>
With Python like:
from zope.schema.interfaces import IContextSourceBinder
class Binder(object):
implements(IContextSourceBinder)
def __call__(self, context):
return SimpleVocabulary.fromValues(['a', 'd', 'f'])
dummy_binder = Binder()
You may also use the
vocabulary
tag rather than
source
to refer to named vocabularies registered via the ZCA.
Internationalization¶
Translation domains and message ids can be specified for text that is interpreted as unicode. This will result in deserialization as a zope.i18nmessageid message id rather than a basic Unicode string.
Note that we need to add the i18n namespace and a domain specification:
<model xmlns="http://namespaces.plone.org/supermodel/schema"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
i18n:domain="your.application">
<schema>
<field type="zope.schema.TextLine" name="title">
<title i18n:translate="yourapp_test_title">Title</title>
</field>
</schema>
</model>
supermodel/form attributes¶
supermodel/form provides attributes that govern presentation and editing.
after/before¶
To re-order fields, use
form:after
or
form:before
.
The value should be either
'*'
, to put the field first/last in the form, or the name
of a another field. Use
'.fieldname'
to refer to field in the current schema (or a base
schema). Use a fully prefixed name (e.g.
'my.package.ISomeSchema'
) to refer to a field in another schema. Use an
unprefixed name to refer to a field in the default
schema for the form.
Example:
<field type="zope.schema.TextLine"
name="one"
form:after="two">
<title>One</title>
</field>
mode¶
To turn a field into a view mode or hidden field, use
form:mode
. The mode may be set for only some forms by specifying
a form interface in the same manner as for
form:omitted
.
Example:
<field type="zope.schema.TextLine"
name="three"
form:mode="z3c.form.interfaces.IEditForm:input">
<title>Three</title>
</field>
omitted¶
To omit a field from all forms, use
form:omitted="true"
. To omit a field only from some forms, specify a form
interface like
form:omitted="z3c.form.interfaces.IForm:true"
. Multiple interface:value settings may be specified,
separated by spaces.
Examples:
<field type="zope.schema.TextLine"
name="one"
form:omitted="true">
<title>One</title>
</field>
<field type="zope.schema.TextLine" name="three"
form:omitted="z3c.form.interfaces.IForm:true z3c.form.interfaces.IEditForm:false"
>
<title>Three</title>
</field>
The latter example hides the field on everything except the edit form.
widget¶
To set a custom widget for a field, use
form:widget
to give a fully qualified name to the field widget
factory.
Example:
<field type="zope.schema.TextLine"
name="password"
form:widget="z3c.form.browser.password.PasswordFieldWidget">
<title>One</title>
</field>
Dynamic Defaults¶
To set a dynamic default for a field, use a
defaultFactory
tag to give a fully qualified name for a callable. The
defaultFactory callable must provide either
plone.supermodel.interfaces.IDefaultFactory or
zope.schema.interfaces.IContextAwareDefaultFactory.
Example:
<field type="zope.schema.TextLine" name="three">
<title>Three</title>
<defaultFactory>plone.supermodel.tests.dummy_defaultFactory</defaultFactory>
</field>
Sample Python for the validator factory:
@provider(IDefaultFactory)
def dummy_defaultFactory():
return u'something'
For a callable using context:
@provider(IContextAwareDefaultFactory)
def dummy_defaultCAFactory(context):
return context.something
Note
The
defaultFactory
tag was added in plone.supermodel 1.2.3, shipping with
Plone 4.3.2+.
validator¶
To set a custom validator for a field, use
form:validator
to give a fully qualified name to the field validator
factory. The validator factory should be a class derived
from one of the validators in z3c.form.validator.
Example:
<field type="zope.schema.TextLine"
name="three"
form:validator="plone.autoform.tests.test_utils.TestValidator">
<title>Three</title>
</field>
Sample Python for the validator factory:
class TestValidator(z3c.form.validator.SimpleFieldValidator):
def validate(self, value):
super(TestValidator, self).validate(value)
raise Invalid("Test")
supermodel/security attributes¶
read-permission/write-permission¶
To set a read or write permission, use
security:read-permission
or
security:write-permission
. The value should be the name of an
IPermission
utility.
Example:
<field type="zope.schema.TextLine"
name="one"
security:read-permission="zope2.View"
security:write-permission="cmf.ModifyPortalContent">
<title>One</title>
</field>