[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