[Checkins] SVN: plone.z3cform/trunk/ In ``plone.z3cform.layout``,
allow labels to be defined per form
Daniel Nouri
daniel.nouri at gmail.com
Mon Aug 4 11:20:07 EDT 2008
Log message for revision 89347:
In ``plone.z3cform.layout``, allow labels to be defined per form
instance, and not only per form class.
Also, make the previous implementation that would allow this a bit
simpler. And do a little rephrasing in tests.
Changed:
U plone.z3cform/trunk/docs/HISTORY.txt
U plone.z3cform/trunk/plone/z3cform/layout.py
U plone.z3cform/trunk/plone/z3cform/layout.txt
-=-
Modified: plone.z3cform/trunk/docs/HISTORY.txt
===================================================================
--- plone.z3cform/trunk/docs/HISTORY.txt 2008-08-04 15:16:03 UTC (rev 89346)
+++ plone.z3cform/trunk/docs/HISTORY.txt 2008-08-04 15:20:06 UTC (rev 89347)
@@ -4,6 +4,9 @@
0.5.1 - Unreleased
------------------
+* In ``plone.z3cform.layout``, allow labels to be defined per form
+ instance, and not only per form class.
+
0.5.0 - 2008-07-30
------------------
Modified: plone.z3cform/trunk/plone/z3cform/layout.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/layout.py 2008-08-04 15:16:03 UTC (rev 89346)
+++ plone.z3cform/trunk/plone/z3cform/layout.py 2008-08-04 15:20:06 UTC (rev 89347)
@@ -17,6 +17,12 @@
form = None # override this with a form class.
request_layer = z3c.form.interfaces.IFormLayer
+ def __init__(self, context, request):
+ super(FormWrapper, self).__init__(context, request)
+ if self.form is not None:
+ self._form = self.form(self.context.aq_inner, self.request)
+ self._form.__name__ = self.__name__
+
def __call__(self):
"""This method renders the outer skeleton template, which in
turn calls the 'contents' method below.
@@ -42,23 +48,14 @@
Override this method if you need to pass a different context
to your form, or if you need to render a number of forms.
"""
- return self._form()()
+ return self._form()
def label(self):
"""Override this method to use a different way of acquiring a
label or title for your page. Overriding this with a simple
attribute works as well.
"""
- return self._form().label
-
- def _form(self):
- form = getattr(self, '_cached_form', None)
- if form is not None:
- return form
- self._cached_form = self.form(self.context.aq_inner, self.request)
- self._cached_form.__name__ = self.__name__
- return self._cached_form
-
+ return self._form.label
def wrap_form(form, __wrapper_class=FormWrapper, **kwargs):
class MyFormWrapper(__wrapper_class):
Modified: plone.z3cform/trunk/plone/z3cform/layout.txt
===================================================================
--- plone.z3cform/trunk/plone/z3cform/layout.txt 2008-08-04 15:16:03 UTC (rev 89346)
+++ plone.z3cform/trunk/plone/z3cform/layout.txt 2008-08-04 15:20:06 UTC (rev 89347)
@@ -10,8 +10,6 @@
create a view that's suitable for registration with a ``browser:page``
directive.
-Testing the FormWrapper class::
-
>>> from zope.interface import alsoProvides
>>> from zope.publisher.browser import TestRequest
>>> from zope.annotation.interfaces import IAttributeAnnotatable
@@ -24,7 +22,7 @@
... alsoProvides(request, IAttributeAnnotatable)
... return request
-Then we create a simple z3c form::
+Then we create a simple z3c form:
>>> from zope import interface, schema
>>> from z3c.form import form, field, button
@@ -35,7 +33,7 @@
>>> from z3c.form.interfaces import IFieldsForm
>>> from zope.interface import implements
- >>> class MyWrappedForm(form.Form):
+ >>> class MyForm(form.Form):
... implements(IFieldsForm)
... fields = field.Fields(MySchema)
... ignoreContext = True # don't use context to get widget data
@@ -46,7 +44,7 @@
... print data['age'] # ... or do stuff
>>> class MyFormWrapper(FormWrapper):
- ... form = MyWrappedForm
+ ... form = MyForm
... label = u"Please enter your age"
>>> from zope.component import provideAdapter
@@ -58,10 +56,19 @@
... factory=MyFormWrapper,
... name=u"test-form")
+For our context, we define a class that inherits from Acquisition.
+This is to satisfy permission checking later on, and it'll allow the
+layout view to call ``aq_inner`` on the context:
+
+ >>> from Acquisition import Implicit
+ >>> class Bar(Implicit):
+ ... __allow_access_to_unprotected_subobjects__ = 1
+ ... implements(Interface)
+
Let's verify that worked:
>>> from zope.component import getMultiAdapter
- >>> context = object()
+ >>> context = Bar()
>>> request = make_request()
>>> getMultiAdapter((context, request), name=u"test-form")
... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
@@ -84,34 +91,39 @@
>>> layout = ViewPageTemplateFile(path, _prefix='')
Note that the ``_prefix`` argument passed to Five's
-ViewPageTemplateFile is unnecessary when used outside of a test. We
-can now make the actual call to ``wrap_form`` and register the view
-class it returns. Normally, you'd register this view class using
-ZCML, like with any other view.
+ViewPageTemplateFile is unnecessary when outside of a test. We can
+now make the actual call to ``wrap_form`` and register the view class
+it returns. Normally, you'd register this view class using ZCML, like
+with any other view.
>>> from plone.z3cform.layout import wrap_form
- >>> view_class = wrap_form(MyWrappedForm, index=layout, label=u"My label")
+ >>> view_class = wrap_form(MyForm, index=layout, label=u"My label")
>>> provideAdapter(adapts=(Interface, IBrowserRequest),
... provides=Interface,
... factory=view_class,
... name=u"test-form2")
-To satisfy permission checking, we'll wrap the view in a Zope2-ish
-object before we render it. Again, you usually don't have to worry
-about this:
+Let's render this view:
- >>> from Acquisition import Implicit
- >>> class Bar(Implicit):
- ... __allow_access_to_unprotected_subobjects__ = 1
- ... implements(Interface)
- >>> context = Bar()
-
>>> view = getMultiAdapter(
... (context, request), name=u"test-form2").__of__(context)
>>> print view() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
<html>Hello, this is your layout speaking:...My label...Age...</html>
+
+If we don't pass the label to ``wrap_form``, it'll try to look up the
+label from the form instance:
+
+ >>> class MyLabelledForm(MyForm):
+ ... @property
+ ... def label(self):
+ ... return 'Another label'
+
+ >>> view_class = wrap_form(MyLabelledForm, index=layout)
+ >>> view = view_class(context, request).__of__(context)
+ >>> print view() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ <html>Hello, this is your layout speaking:...Another label...Age...</html>
>>> os.unlink(path)
-
+
Send bad data to the form:
>>> request = make_request(form={'form.widgets.age': '12.1'})
More information about the Checkins
mailing list