Skip to content

Commit 6594061

Browse files
committed
add autoform documentation for classic UI
1 parent bff9287 commit 6594061

File tree

1 file changed

+318
-0
lines changed

1 file changed

+318
-0
lines changed

docs/classic-ui/forms.md

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,324 @@ schema = IMyForm
120120
If your form is not bound to an object (such as a Dexterity object), set `ignoreContext = True`.
121121

122122

123+
(classic-ui-forms-autoform-label)=
124+
## Controlling form presentation
125+
126+
Directives can be specified in the schema to control aspects of form presentation.
127+
128+
### Changing a field's display mode
129+
130+
A field's widget can be displayed in several "modes":
131+
132+
* input - allows the user to enter data into the field
133+
* display - a read-only indication of the field's value
134+
* hidden - a record of the field's value that is included only in the HTML source
135+
136+
The mode can be controlled using the `mode` directive.
137+
138+
```python
139+
from plone.supermodel import model
140+
from plone.autoform import directives as form
141+
142+
class IMySchema(model.Schema):
143+
144+
form.mode(secret='hidden')
145+
form.mode(IEditForm, secret='input')
146+
secret = schema.TextLine(
147+
title=u"Secret",
148+
default=u"Secret stuff (except on edit forms)"
149+
)
150+
```
151+
152+
In this case the mode for the `secret` field is set to 'hidden' for most forms,
153+
but 'input' for forms that provide the IEditForm interface.
154+
155+
The corresponding supermodel XML directive is `form:mode`:
156+
157+
```xml
158+
<field type="zope.schema.TextLine"
159+
name="secret"
160+
form:mode="z3c.form.interfaces.IForm:hidden z3c.form.interfaces.IEditForm:input">
161+
<title>Secret</title>
162+
<description>Secret stuff (except on edit forms)</description>
163+
</field>
164+
```
165+
166+
The mode can be specified briefly if it should be the same for all forms:
167+
168+
```xml
169+
<field type="zope.schema.TextLine"
170+
name="secret"
171+
form:mode="hidden">
172+
<title>Secret</title>
173+
<description>Secret stuff</description>
174+
</field>
175+
```
176+
177+
In other words, `form:mode` may be either a single mode, or a space-separated
178+
list of form_interface:mode pairs.
179+
180+
181+
### Omitting fields
182+
183+
A field can be omitted entirely from all forms, or from some forms,
184+
using the `omitted` and `no_omit` directives. In this example,
185+
the `dummy` field is omitted from all forms, and the `edit_only`
186+
field is omitted from all forms except those that provide the
187+
IEditForm interface:
188+
189+
```python
190+
from z3c.form.interfaces import IEditForm
191+
from plone.supermodel import model
192+
from plone.autoform import directives as form
193+
194+
class IMySchema(model.Schema):
195+
196+
form.omitted('dummy')
197+
dummy = schema.Text(
198+
title=u"Dummy"
199+
)
200+
201+
form.omitted('edit_only')
202+
form.no_omit(IEditForm, 'edit_only')
203+
edit_only = schema.TextLine(
204+
title = u'Only included on edit forms',
205+
)
206+
```
207+
208+
In supermodel XML, this can be specified as:
209+
210+
```xml
211+
<field type="zope.schema.TextLine"
212+
name="dummy"
213+
form:omitted="true">
214+
<title>Dummy</title>
215+
</field>
216+
217+
<field type="zope.schema.TextLine"
218+
name="edit-only"
219+
form:omitted="z3c.form.interfaces.IForm:true z3c.form.interfaces.IEditForm:false">
220+
<title>Only included on edit form</title>
221+
</field>
222+
```
223+
224+
`form:omitted` may be either a single boolean value, or a space-separated
225+
list of form_interface:boolean pairs.
226+
227+
228+
### Re-ordering fields
229+
230+
A field's position in the form can be influenced using the `order_before`
231+
and `order_after` directives. In this example, the `not_last` field
232+
is placed before the `summary` field even though it is defined afterward:
233+
234+
```python
235+
from plone.supermodel import model
236+
from plone.autoform import directives as form
237+
238+
class IMySchema(model.Schema):
239+
240+
summary = schema.Text(
241+
title=u"Summary",
242+
description=u"Summary of the body",
243+
readonly=True
244+
)
245+
246+
form.order_before(not_last='summary')
247+
not_last = schema.TextLine(
248+
title=u"Not last",
249+
)
250+
```
251+
252+
The value passed to the directive may be either '*' (indicating before or after
253+
all fields) or the name of another field. Use `'.fieldname'` to refer to
254+
field in the current schema or a base schema. Prefix with the schema name (e.g.
255+
`'IDublinCore.title'`) to refer to a field in another schema. Use an
256+
unprefixed name to refer to a field in the current or the default schema for
257+
the form.
258+
259+
In supermodel XML, the directives are called `form:before` and `form:after`.
260+
For example:
261+
262+
```xml
263+
<field type="zope.schema.TextLine"
264+
name="not_last"
265+
form:before="*">
266+
<title>Not last</title>
267+
</field>
268+
```
269+
270+
271+
### Organizing fields into fieldsets
272+
273+
Fields can be grouped into fieldsets, which will be rendered within an HTML
274+
`<fieldset>` tag. In this example the `footer` and `dummy` fields
275+
are placed within the `extra` fieldset:
276+
277+
```python
278+
from plone.supermodel import model
279+
from plone.autoform import directives as form
280+
281+
class IMySchema(model.Schema):
282+
283+
model.fieldset('extra',
284+
label=u"Extra info",
285+
fields=['footer', 'dummy']
286+
)
287+
288+
footer = schema.Text(
289+
title=u"Footer text",
290+
)
291+
292+
dummy = schema.Text(
293+
title=u"Dummy"
294+
)
295+
```
296+
297+
In supermodel XML fieldsets are specified by grouping fields within a
298+
`<fieldset>` tag:
299+
300+
```xml
301+
<fieldset name="extra" label="Extra info">
302+
<field name="footer" type="zope.schema.TextLine">
303+
<title>Footer text</title>
304+
</field>
305+
<field name="dummy" type="zope.schema.TextLine">
306+
<title>Dummy</title>
307+
</field>
308+
</fieldset>
309+
```
310+
311+
312+
### Changing a field's widget
313+
314+
Usually, z3c.form picks a widget based on the type of your field.
315+
You can change the widget using the `widget` directive if you want
316+
users to enter or view data in a different format. For example,
317+
here we change the widget for the `human` field to use yes/no
318+
radio buttons instead of a checkbox:
319+
320+
```python
321+
from plone.supermodel import model
322+
from plone.autoform import directives as form
323+
from z3c.form.browser.radio import RadioFieldWidget
324+
325+
class IMySchema(model.Schema):
326+
form.widget('human', RadioFieldWidget)
327+
human = schema.Bool(
328+
title = u'Are you human?',
329+
)
330+
```
331+
332+
You can also pass widget parameters to control attributes of the
333+
widget. For example, here we keep the default widget, but
334+
set a CSS class:
335+
336+
```python
337+
from plone.supermodel import model
338+
from plone.autoform import directives as form
339+
from z3c.form.browser.radio import RadioWidget
340+
341+
class IMySchema(model.Schema):
342+
form.widget('human', klass='annoying')
343+
human = schema.Bool(
344+
title = u'Are you human?',
345+
)
346+
```
347+
348+
In supermodel XML the widget is specified using a `<form:widget>` tag, which
349+
can have its own elements specifying parameters::
350+
351+
```xml
352+
<field name="human" type="zope.schema.TextLine">
353+
<title>Are you human?</title>
354+
<form:widget type="z3c.form.browser.radio.RadioWidget">
355+
<klass>annoying</klass>
356+
</form:widget>
357+
</field>
358+
```
359+
360+
Note: In order to be included in the XML representation of a schema,
361+
widget parameters must be handled by a WidgetExportImportHandler utility.
362+
There is a default one which handles the attributes defined in
363+
`z3c.form.browser.interfaces.IHTMLFormElement`.
364+
365+
### Protect a field with a permission
366+
367+
By default, fields are included in the form regardless of the user's
368+
permissions. Fields can be protected using the `read_permission`
369+
and `write_permission` directives. The read permission is checked when
370+
the field is in display mode, and the write permission is checked when
371+
the field is in input mode. The permission should be given with its
372+
Zope 3-style name (i.e. cmf.ManagePortal rather than 'Manage portal').
373+
374+
In this example, the `secret` field is protected by the
375+
`cmf.ManagePortal` permission as both a read and write permission.
376+
This means that in both display and input modes, the field will
377+
only be included in the form for users who have that permission:
378+
379+
```python
380+
from plone.supermodel import model
381+
from plone.autoform import directives as form
382+
383+
class IMySchema(model.Schema):
384+
form.read_permission(secret='cmf.ManagePortal')
385+
form.write_permission(secret='cmf.ManagePortal')
386+
secret = schema.TextLine(
387+
title = u'Secret',
388+
)
389+
```
390+
391+
In supermodel XML the directives are `security:read-permission` and
392+
`security:write-permission`:
393+
394+
```xml
395+
<field type="zope.schema.TextLine"
396+
name="secret"
397+
security:read-permission="cmf.ManagePortal"
398+
security:write-permission="cmf.ManagePortal">
399+
<title>Secret</title>
400+
</field>
401+
```
402+
403+
## Display Forms
404+
405+
406+
Sometimes rather than rendering a form for data entry, you want to display
407+
stored values based on the same schema. This can be done using a "display form."
408+
The display form renders each field's widget in "display mode," which means
409+
that it shows the field value in read-only form rather than as a form input.
410+
411+
To use the display form, create a view that extends `WidgetsView` like this:
412+
413+
```python
414+
from plone.autoform.view import WidgetsView
415+
416+
class MyView(WidgetsView):
417+
schema = IMySchema
418+
additionalSchemata = (ISchemaOne, ISchemaTwo,)
419+
420+
# ...
421+
```
422+
423+
To render the form, do not override `__call__()`. Instead, either implement
424+
the `render()` method, set an `index` attribute to a page template or
425+
other callable, or use the `template` attribute of the `<browser:page />`
426+
ZCML directive when registering the view.
427+
428+
In the template, you can use the following variables:
429+
430+
* `view/w` is a dictionary of all widgets, including those from non-default
431+
fieldsets (by contrast, the `widgets` variable contains only those
432+
widgets in the default fieldset). The keys are the field names, and the
433+
values are widget instances. To render a widget (in display mode), you can
434+
do `tal:replace="structure view/w/myfield/render" />`.
435+
* `view/fieldsets` is a dictionary of all fieldsets (not including the
436+
default fieldset, i.e. those widgets not placed into a fieldset). They keys
437+
are the fieldset names, and the values are the fieldset form instances,
438+
which in turn have variables like `widgets` given a list of all widgets.
439+
440+
123441
(classic-ui-forms-dexterity-add-edit-forms-label)=
124442

125443
## Dexterity add and edit forms

0 commit comments

Comments
 (0)