[Checkins] SVN: plone.z3cform/trunk/README.txt Start fleshing out documentation

Martin Aspeli optilude at gmx.net
Tue Feb 16 12:29:49 EST 2010


Log message for revision 109078:
  Start fleshing out documentation

Changed:
  U   plone.z3cform/trunk/README.txt

-=-
Modified: plone.z3cform/trunk/README.txt
===================================================================
--- plone.z3cform/trunk/README.txt	2010-02-16 15:46:48 UTC (rev 109077)
+++ plone.z3cform/trunk/README.txt	2010-02-16 17:29:43 UTC (rev 109078)
@@ -2,21 +2,189 @@
 plone.z3cform
 =============
 
-plone.z3cform is a library that allows use of `z3c.form`_ with Zope 2
-and the CMF_. For Plone integration, there is also `plone.app.z3cform`_.
+plone.z3cform is a library that enables the use of `z3c.form`_ in Zope 2.
+It depends only on Zope 2 and `z3c.form`.
 
-Layout form wrapper
--------------------
+For Plone integration, there is also `plone.app.z3cform`_.
 
+In addition to pure interoperability support, a few patterns which are useful
+in Zope 2 applications are implemented here.
 
+Installation
+------------
+
+To use this package, simply install it as a dependency of the package where
+you are using forms, via the ``install_requires`` line in ``setup.py``. Then
+loads its configuration via ZCML::
+
+    <include package="plone.directives.form" />
+
 Standalone forms
 ----------------
 
+If you are using Zope 2.12 or later, z3c.form forms will *almost* work
+out of the box. However, two obstacles remain:
 
+* The standard file upload data converter does not work with Zope 2, so
+  fields (e.g. for ``Bytes``) using the file widget will not work correctly.
+* z3c.form expects request values to be decoded to unicode strings by the
+  publisher, which does not happen in Zope 2.
+
+To address the first problem, this package provides an override for the
+standard data converter adapter (registered on the ``schema.Bytes`` class
+directly, so as to override the default, which is registered for the less
+general ``IBytes`` interface). To address the second, it applies a monkey
+patch to the ``update()`` methods of ``BaseForm`` and ``GroupForm`` from
+``z3c.form`` which performs the necessary decoding in a way that is consistent
+with the Zope 3-style publisher.
+
+With this in place, you can create a form using standard `z3c.form`_
+conventions, e.g.::
+
+    from zope.interface import Interface
+    from zope import schema
+    from z3c.form import form, button
+    
+    class IMyFormSchema(Interface):
+        field1 = schema.TextLine(title=u"A field")
+        field2 = schema.Int(title=u"Another field")
+    
+    class MyForm(form.Form):
+        fields = field.Fields(IMyformSchema)
+        
+        @button.buttonAndHandler(u'Submit')
+        def handleApply(self, action):
+            data, errors = self.extractData()
+            # do something
+
+You can register this view in ZCML using the standard ``<browser:page />``
+directive::
+
+    <browser:page
+        for="*"
+        name="my-form"
+        class=".forms.MyForm"
+        permission="zope2.View"
+        />
+
+A default template will be used to render the form. If you want to associate
+a custom template, you should do so by setting the ``template`` class variable
+instead of using the ``template`` attribute of the ZCML directive::
+
+    from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+    
+    class MyForm(form.Form):
+        fields = field.Fields(IMyformSchema)
+        template = ViewPageTemplateFile('mytemplate.pt')
+        
+        @button.buttonAndHandler(u'Submit')
+        def handleApply(self, action):
+            data, errors = self.extractData()
+            # do something
+
+See below for more details about standard form macros.
+
+Note that to render any of the standard widgets, you will also need to make
+sure the request is marked with ``z2c.form.interfaces.IFormLayer``, as is
+the norm with z3c.form. If you install `plone.app.z3cform`_ in Plone, that
+is already done for you, but in other systems, you will need to do this
+in whichever way Zope browser layers are normally applied.
+
+Layout form wrapper
+-------------------
+
+In versions of Zope prior to 2.12, z3c.form instances cannot be registered
+as views directly, because they do not support Zope 2 security (via the
+acquisition mechanism). Whilst it may be possible to support this via custom
+mix-ins, the preferred approach is to use a wrapper view, which separates the
+rendering of the form form the page layout.
+
+There are a few other reasons why you may want to use the wrapper view, even
+in later versions of Zope:
+
+* To support both an earlier version of Zope and Zope 2.12+
+* To re-use a form in multiple views or viewlets
+* To use the ``IPageTemplate`` adapter lookup semantics from z3c.form to
+  provide a different default or override template for the overall page
+  layout, whilst retaining (or indeed customising independently) the default
+  layout of the form.
+
+When using the wrapper view, you do *not* need to ensure your requests are
+marked with ``IFormLayer``, as it is applied automatically during the
+rendering of the wrapper view.
+
+The easiest way to create a wrapper view is to call the ``wrap_form()``
+function::
+
+    from zope.interface import Interface
+    from zope import schema
+    from z3c.form import form, button
+    
+    from plone.z3cform import layout
+    
+    class IMyFormSchema(Interface):
+        field1 = schema.TextLine(title=u"A field")
+        field2 = schema.Int(title=u"Another field")
+    
+    class MyForm(form.Form):
+        fields = field.Fields(IMyformSchema)
+        
+        @button.buttonAndHandler(u'Submit')
+        def handleApply(self, action):
+            data, errors = self.extractData()
+            # do something
+    
+    MyFormView = layout.wrap_form(MyForm)
+
+You can now register the ``MyformView`` (generated) class as a browser view
+factory::
+
+    <browser:page
+        for="*"
+        name="my-form"
+        class=".forms.MyFormView"
+        permission="zope2.View"
+        />
+
+If you want to have more control, you can define the wrapper class manually.
+You should derive from the default, though, to get the correct semantics. The
+following is equivalent to the ``wrap_form()`` call above::
+
+    class MyFormView(layout.FormWrapper):
+        form = MyForm
+
+You can of course add additional methods to the class, use a custom page
+template, and so on.
+
+The default ``FormWrapper`` class exposes a few methods and properties:
+
+* ``update()`` is called to prepare the request and then wrap the form
+* ``render()`` is called to render the wrapper view. If a template has
+  been set (normally via the ``template`` attribute of the
+  ``<browser:page />`` directive), it will be rendered here. Otherwise,
+  a default page template is found by adapting the view (``self``) and 
+  the request to ``zope.pagetemplate.interfaces.IPageTemplate``, in the
+  same way that ``z3c.form`` does for its views. A default template is
+  supplied with this package.
+* ``form`` is a class variable referring to the form class, as set above.
+* ``form_instance`` is set to the current form instance once the view has
+  been initialised.
+
+When a form is rendered in a wrapper view, the form instance is temporarily
+marked with either ``plone.z3cform.interfaces.IWrappedForm`` (for standard
+forms) or ``plone.z3cform.interfaces.IWrappedSubForm`` (for sub-forms),
+to allow custom adapter registrations. Specifically, this is used to ensure
+that a form rendered "standalone" gets a full-page template applied, whilst
+a form rendered in a wrapper is rendered using a template that renders the
+form elements only.
+
 Default templates and macros
 ----------------------------
 
+Template factories
+------------------
 
+
 The widget traverser
 --------------------
 



More information about the checkins mailing list