doc/book/en/devweb/edition/examples.rst
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Wed, 05 May 2010 18:15:25 +0200
branchstable
changeset 5476 23758c00d3ab
parent 5463 37a2455639b9
child 6152 6824f8b61098
permissions -rw-r--r--
[doc/book] a very simple example of entity form extension
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     1
Examples
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     2
--------
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
     3
5476
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
     4
(Automatic) Entity form
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
     5
~~~~~~~~~~~~~~~~~~~~~~~
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
     6
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
     7
Looking at some cubes available on the `cubicweb forge`_ we find some
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
     8
with form manipulation. The following example comes from the the
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
     9
`conference`_ cube. It extends the change state form for the case
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    10
where a ``Talk`` entity is getting into ``submitted`` state. The goal
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    11
is to select reviewers for the submitted talk.
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    12
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    13
.. _`cubicweb forge`: http://www.cubicweb.org/view?rql=Any+P+ORDERBY+N+WHERE+P+name+LIKE+%22cubicweb-%25%22%2C+P+is+Project%2C+P+name+N
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    14
.. _`conference`: http://www.cubicweb.org/project/cubicweb-conference
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    15
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    16
.. sourcecode:: python
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    17
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    18
 from cubicweb.web import formfields as ff, formwidgets as fwdgs
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    19
 class SendToReviewerStatusChangeView(ChangeStateFormView):
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    20
     __select__ = (ChangeStateFormView.__select__ &
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    21
                   implements('Talk') &
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    22
                   rql_condition('X in_state S, S name "submitted"'))
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    23
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    24
     def get_form(self, entity, transition, **kwargs):
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    25
         form = super(SendToReviewerStatusChangeView, self).get_form(entity, transition, **kwargs)
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    26
         relation = ff.RelationField(name='reviews', role='object',
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    27
                                     eidparam=True,
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    28
                                     label=_('select reviewers'),
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    29
                                     widget=fwdgs.Select(multiple=True))
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    30
         form.append_field(relation)
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    31
         return form
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    32
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    33
Simple extension of a form can be done from within the `FormView`
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    34
wrapping the form. FormView instances have a handy ``get_form`` method
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    35
that returns the form to be rendered. Here we add a ``RelationField``
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    36
to the base state change form.
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    37
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    38
One notable point is the ``eidparam`` argument: it tells both the
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    39
field and the ``edit controller`` that the field is linked to a
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    40
specific entity.
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    41
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    42
It is hence entirely possible to add ad-hoc fields that will be
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    43
processed by some specialized instance of the edit controller.
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    44
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    45
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    46
Ad-hoc fields form
23758c00d3ab [doc/book] a very simple example of entity form extension
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5463
diff changeset
    47
~~~~~~~~~~~~~~~~~~
5463
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    48
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    49
We want to define a form doing something else than editing an entity. The idea is
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    50
to propose a form to send an email to entities in a resultset which implements
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    51
:class:`IEmailable`.  Let's take a simplified version of what you'll find in
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    52
:mod:`cubicweb.web.views.massmailing`.
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    53
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    54
Here is the source code:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    55
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    56
.. sourcecode:: python
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    57
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    58
    def sender_value(form):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    59
	return '%s <%s>' % (form._cw.user.dc_title(), form._cw.user.get_email())
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    60
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    61
    def recipient_choices(form, field):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    62
	return [(e.get_email(), e.eid)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    63
                 for e in form.cw_rset.entities()
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    64
		 if e.get_email()]
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    65
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    66
    def recipient_value(form):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    67
	return [e.eid for e in form.cw_rset.entities()
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    68
                if e.get_email()]
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    69
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    70
    class MassMailingForm(forms.FieldsForm):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    71
	__regid__ = 'massmailing'
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    72
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    73
	needs_js = ('cubicweb.widgets.js',)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    74
	domid = 'sendmail'
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    75
	action = 'sendmail'
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    76
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    77
	sender = ff.StringField(widget=TextInput({'disabled': 'disabled'}),
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    78
				label=_('From:'),
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    79
				value=sender_value)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    80
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    81
	recipient = ff.StringField(widget=CheckBox(),
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    82
	                           label=_('Recipients:'),
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    83
				   choices=recipient_choices,
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    84
				   value=recipients_value)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    85
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    86
	subject = ff.StringField(label=_('Subject:'), max_length=256)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    87
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    88
	mailbody = ff.StringField(widget=AjaxWidget(wdgtype='TemplateTextField',
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    89
						    inputid='mailbody'))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    90
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    91
	form_buttons = [ImgButton('sendbutton', "javascript: $('#sendmail').submit()",
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    92
				  _('send email'), 'SEND_EMAIL_ICON'),
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    93
			ImgButton('cancelbutton', "javascript: history.back()",
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    94
				  stdmsgs.BUTTON_CANCEL, 'CANCEL_EMAIL_ICON')]
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    95
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    96
Let's detail what's going on up there. Our form will hold four fields:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    97
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    98
* a sender field, which is disabled and will simply contains the user's name and
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
    99
  email
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   100
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   101
* a recipients field, which will be displayed as a list of users in the context
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   102
  result set with checkboxes so user can still choose who will receive his mailing
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   103
  by checking or not the checkboxes. By default all of them will be checked since
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   104
  field's value return a list containing same eids as those returned by the
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   105
  vocabulary function.
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   106
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   107
* a subject field, limited to 256 characters (hence we know a
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   108
  :class:`~cubicweb.web.formwidgets.TextInput` will be used, as explained in
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   109
  :class:`~cubicweb.web.formfields.StringField`)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   110
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   111
* a mailbody field. This field use an ajax widget, defined in `cubicweb.widgets.js`,
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   112
  and whose definition won't be shown here. Notice though that we tell this form
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   113
  need this javascript file by using `needs_js`
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   114
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   115
Last but not least, we add two buttons control: one to post the form using
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   116
javascript (`$('#sendmail')` being the jQuery call to get the element with DOM id
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   117
set to 'sendmail', which is our form DOM id as specified by its `domid`
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   118
attribute), another to cancel the form which will go back to the previous page
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   119
using another javascript call. Also we specify an image to use as button icon as a
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   120
resource identifier (see :ref:`external_resources`) given as last argument to
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   121
:class:`cubicweb.web.formwidgets.ImgButton`.
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   122
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   123
To see this form, we still have to wrap it in a view. This is pretty simple:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   124
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   125
.. sourcecode:: python
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   126
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   127
    class MassMailingFormView(form.FormViewMixIn, EntityView):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   128
	__regid__ = 'massmailing'
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   129
	__select__ = implements(IEmailable) & authenticated_user()
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   130
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   131
	def call(self):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   132
	    form = self._cw.vreg['forms'].select('massmailing', self._cw,
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   133
	                                         rset=self.cw_rset)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   134
	    self.w(form.render())
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   135
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   136
As you see, we simply define a view with proper selector so it only apply to a
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   137
result set containing :class:`IEmailable` entities, and so that only users in the
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   138
managers or users group can use it. Then in the `call()` method for this view we
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   139
simply select the above form and write what its `.render()` method returns.
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   140
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   141
When this form is submitted, a controller with id 'sendmail' will be called (as
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   142
specified using `action`). This controller will be responsible to actually send
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   143
the mail to specified recipients.
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   144
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   145
Here is what it looks like:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   146
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   147
.. sourcecode:: python
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   148
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   149
   class SendMailController(Controller):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   150
       __regid__ = 'sendmail'
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   151
       __select__ = (authenticated_user() &
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   152
                     match_form_params('recipient', 'mailbody', 'subject'))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   153
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   154
       def publish(self, rset=None):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   155
           body = self._cw.form['mailbody']
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   156
           subject = self._cw.form['subject']
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   157
           eids = self._cw.form['recipient']
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   158
           # eids may be a string if only one recipient was specified
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   159
           if isinstance(eids, basestring):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   160
               rset = self._cw.execute('Any X WHERE X eid %(x)s', {'x': eids})
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   161
           else:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   162
               rset = self._cw.execute('Any X WHERE X eid in (%s)' % (','.join(eids)))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   163
           recipients = list(rset.entities())
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   164
           msg = format_mail({'email' : self._cw.user.get_email(),
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   165
                              'name' : self._cw.user.dc_title()},
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   166
                             recipients, body, subject)
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   167
           if not self._cw.vreg.config.sendmails([(msg, recipients]):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   168
               msg = self._cw._('could not connect to the SMTP server')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   169
           else:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   170
               msg = self._cw._('emails successfully sent')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   171
           raise Redirect(self._cw.build_url(__message=msg))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   172
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   173
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   174
The entry point of a controller is the publish method. In that case we simply get
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   175
back post values in request's `form` attribute, get user instances according
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   176
to eids found in the 'recipient' form value, and send email after calling
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   177
:func:`format_mail` to get a proper email message. If we can't send email or
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   178
if we successfully sent email, we redirect to the index page with proper message
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   179
to inform the user.
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   180
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   181
Also notice that our controller has a selector that deny access to it
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   182
to anonymous users (we don't want our instance to be used as a spam
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   183
relay), but also checks if the expected parameters are specified in
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   184
forms. That avoids later defensive programming (though it's not enough
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   185
to handle all possible error cases).
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   186
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   187
To conclude our example, suppose we wish a different form layout and that existent
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   188
renderers are not satisfying (we would check that first of course :). We would then
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   189
have to define our own renderer:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   190
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   191
.. sourcecode:: python
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   192
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   193
    class MassMailingFormRenderer(formrenderers.FormRenderer):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   194
        __regid__ = 'massmailing'
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   195
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   196
        def _render_fields(self, fields, w, form):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   197
            w(u'<table class="headersform">')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   198
            for field in fields:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   199
                if field.name == 'mailbody':
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   200
                    w(u'</table>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   201
                    w(u'<div id="toolbar">')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   202
                    w(u'<ul>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   203
                    for button in form.form_buttons:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   204
                        w(u'<li>%s</li>' % button.render(form))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   205
                    w(u'</ul>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   206
                    w(u'</div>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   207
                    w(u'<div>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   208
                    w(field.render(form, self))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   209
                    w(u'</div>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   210
                else:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   211
                    w(u'<tr>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   212
                    w(u'<td class="hlabel">%s</td>' %
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   213
                      self.render_label(form, field))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   214
                    w(u'<td class="hvalue">')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   215
                    w(field.render(form, self))
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   216
                    w(u'</td></tr>')
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   217
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   218
        def render_buttons(self, w, form):
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   219
            pass
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   220
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   221
We simply override the `_render_fields` and `render_buttons` method of the base form renderer
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   222
to arrange fields as we desire it: here we'll have first a two columns table with label and
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   223
value of the sender, recipients and subject field (form order respected), then form controls,
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   224
then a div containing the textarea for the email's content.
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   225
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   226
To bind this renderer to our form, we should add to our form definition above:
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   227
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   228
.. sourcecode:: python
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   229
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   230
    form_renderer_id = 'massmailing'
37a2455639b9 [doc/book] move examples to a separate chapter, fix autoform module docstring
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
diff changeset
   231