[Checkins] SVN: plone.z3cform/trunk/plone/z3cform/ Most existing
users of this package will need to import from
Daniel Nouri
daniel.nouri at gmail.com
Tue Jul 22 16:20:19 EDT 2008
Log message for revision 88735:
Most existing users of this package will need to import from
``plone.app.z3cform.layout`` instead anyway, so let's break some
imports.
Changed:
D plone.z3cform/trunk/plone/z3cform/base.py
D plone.z3cform/trunk/plone/z3cform/base.txt
A plone.z3cform/trunk/plone/z3cform/layout.py
A plone.z3cform/trunk/plone/z3cform/layout.txt
U plone.z3cform/trunk/plone/z3cform/tests.py
-=-
Deleted: plone.z3cform/trunk/plone/z3cform/base.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/base.py 2008-07-22 20:17:50 UTC (rev 88734)
+++ plone.z3cform/trunk/plone/z3cform/base.py 2008-07-22 20:20:19 UTC (rev 88735)
@@ -1,60 +0,0 @@
-import z3c.form.interfaces
-from Products.Five import BrowserView
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-
-from plone.z3cform import z2
-
-class FormWrapper(BrowserView):
- """Use this as a base class for your Five view and override the
- 'form' attribute with your z3c.form form class. Your form will
- then be rendered in the contents area of a layout template, the
- 'index' attribute.
-
- Use the 'wrap' function in this module if you don't like defining
- classes.
- """
- index = ViewPageTemplateFile('layout.pt')
- form = None # override this with a form class.
- request_layer = z3c.form.interfaces.IFormLayer
-
- def __call__(self):
- """This method renders the outer skeleton template, which in
- turn calls the 'contents' method below.
-
- We use an indirection to 'self.index' here to allow users to
- override the skeleton template through the 'browser' zcml
- directive.
- """
- return self.index()
-
- def contents(self):
- """This is the method that'll call your form. You don't
- usually override this.
- """
- # A call to 'switch_on' is required before we can render
- # z3c.forms within Zope 2.
- z2.switch_on(self, request_layer=self.request_layer)
- return self.render_form()
-
- def render_form(self):
- """This method returns the rendered z3c.form form.
-
- 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(self.context.aq_inner, self.request)()
-
- 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 wrap_form(form, __wrapper_class=FormWrapper, **kwargs):
- class MyFormWrapper(__wrapper_class):
- pass
- MyFormWrapper.form = form
- for name, value in kwargs.items():
- setattr(MyFormWrapper, name, value)
- return MyFormWrapper
Deleted: plone.z3cform/trunk/plone/z3cform/base.txt
===================================================================
--- plone.z3cform/trunk/plone/z3cform/base.txt 2008-07-22 20:17:50 UTC (rev 88734)
+++ plone.z3cform/trunk/plone/z3cform/base.txt 2008-07-22 20:20:19 UTC (rev 88735)
@@ -1,133 +0,0 @@
-Base
-====
-
-Testing the FormWrapper class::
-
- >>> from zope.interface import alsoProvides
- >>> from zope.publisher.browser import TestRequest
- >>> from zope.annotation.interfaces import IAttributeAnnotatable
- >>> from z3c.form.interfaces import IFormLayer
-
- >>> def make_request(form={}):
- ... request = TestRequest()
- ... request.form.update(form)
- ... alsoProvides(request, IFormLayer)
- ... alsoProvides(request, IAttributeAnnotatable)
- ... return request
-
-Then we create a simple z3c form::
-
- >>> from zope import interface, schema
- >>> from z3c.form import form, field, button
- >>> from plone.z3cform.base import FormWrapper
-
- >>> class MySchema(interface.Interface):
- ... age = schema.Int(title=u"Age")
-
- >>> from z3c.form.interfaces import IFieldsForm
- >>> from zope.interface import implements
- >>> class MyWrappedForm(form.Form):
- ... implements(IFieldsForm)
- ... fields = field.Fields(MySchema)
- ... ignoreContext = True # don't use context to get widget data
- ...
- ... @button.buttonAndHandler(u'Apply')
- ... def handleApply(self, action):
- ... data, errors = self.extractData()
- ... print data['age'] # ... or do stuff
-
- >>> class MyFormWrapper(FormWrapper):
- ... form = MyWrappedForm
- ... label = u"Please enter your age"
-
- >>> from zope.component import provideAdapter
- >>> from zope.publisher.interfaces.browser import IBrowserRequest
- >>> from zope.interface import Interface
-
- >>> provideAdapter(adapts=(Interface, IBrowserRequest),
- ... provides=Interface,
- ... factory=MyFormWrapper,
- ... name=u"test-form")
-
-Let's verify that worked:
-
- >>> from zope.component import getMultiAdapter
- >>> context = object()
- >>> request = make_request()
- >>> getMultiAdapter((context, request), name=u"test-form")
- ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- <MyFormWrapper object ...>
-
-We can also use a function called ``wrap_form`` to wrap our form in a
-layout. We define a custom layout template first:
-
- >>> import os
- >>> import tempfile
- >>> from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
- >>> fd, path = tempfile.mkstemp()
- >>> f = os.fdopen(fd, 'w')
- >>> f.write("""
- ... <html>Hello, this is your layout speaking:
- ... <div tal:content="structure view/contents"></div>
- ... </html>""")
- >>> f.close()
- >>> 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.
-
- >>> from plone.z3cform.base import wrap_form
- >>> view_class = wrap_form(MyWrappedForm, index=layout)
- >>> 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:
-
- >>> 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:...Age...</html>
- >>> os.unlink(path)
-
-Send bad data to the form:
-
- >>> request = make_request(form={'form.widgets.age': '12.1'})
- >>> from zope.interface import Interface, implements
- >>> formWrapper = getMultiAdapter((context, request), name=u"test-form")
- >>> form = formWrapper.form(context, request)
- >>> form.update()
- >>> data, errors = form.extractData()
- >>> data
- {}
- >>> errors
- (<ValueErrorViewSnippet for ValueError>,)
-
-And then send correct data to the form:
-
- >>> request = make_request(form={'form.widgets.age': '12'})
- >>> from zope.interface import Interface, implements
- >>> from Acquisition import Implicit
- >>> formWrapper = getMultiAdapter((context, request), name=u"test-form")
- >>> form = formWrapper.form(context, request)
- >>> form.update()
- >>> data, errors = form.extractData()
- >>> data
- {'age': 12}
- >>> errors
- ()
-
-
-
Copied: plone.z3cform/trunk/plone/z3cform/layout.py (from rev 88730, plone.z3cform/trunk/plone/z3cform/base.py)
===================================================================
--- plone.z3cform/trunk/plone/z3cform/layout.py (rev 0)
+++ plone.z3cform/trunk/plone/z3cform/layout.py 2008-07-22 20:20:19 UTC (rev 88735)
@@ -0,0 +1,60 @@
+import z3c.form.interfaces
+from Products.Five import BrowserView
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
+from plone.z3cform import z2
+
+class FormWrapper(BrowserView):
+ """Use this as a base class for your Five view and override the
+ 'form' attribute with your z3c.form form class. Your form will
+ then be rendered in the contents area of a layout template, the
+ 'index' attribute.
+
+ Use the 'wrap' function in this module if you don't like defining
+ classes.
+ """
+ index = ViewPageTemplateFile('layout.pt')
+ form = None # override this with a form class.
+ request_layer = z3c.form.interfaces.IFormLayer
+
+ def __call__(self):
+ """This method renders the outer skeleton template, which in
+ turn calls the 'contents' method below.
+
+ We use an indirection to 'self.index' here to allow users to
+ override the skeleton template through the 'browser' zcml
+ directive.
+ """
+ return self.index()
+
+ def contents(self):
+ """This is the method that'll call your form. You don't
+ usually override this.
+ """
+ # A call to 'switch_on' is required before we can render
+ # z3c.forms within Zope 2.
+ z2.switch_on(self, request_layer=self.request_layer)
+ return self.render_form()
+
+ def render_form(self):
+ """This method returns the rendered z3c.form form.
+
+ 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(self.context.aq_inner, self.request)()
+
+ 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 wrap_form(form, __wrapper_class=FormWrapper, **kwargs):
+ class MyFormWrapper(__wrapper_class):
+ pass
+ MyFormWrapper.form = form
+ for name, value in kwargs.items():
+ setattr(MyFormWrapper, name, value)
+ return MyFormWrapper
Copied: plone.z3cform/trunk/plone/z3cform/layout.txt (from rev 88606, plone.z3cform/trunk/plone/z3cform/base.txt)
===================================================================
--- plone.z3cform/trunk/plone/z3cform/layout.txt (rev 0)
+++ plone.z3cform/trunk/plone/z3cform/layout.txt 2008-07-22 20:20:19 UTC (rev 88735)
@@ -0,0 +1,142 @@
+Layout
+======
+
+plone.z3cform tries to avoid mixing Acqusition into your forms. Also,
+it tries to separate form templates from layout templates (aka main
+template), so that your forms are usable in different contexts,
+e.g. in viewlets.
+
+Use the ``wrap_form`` function defined in the ``layout`` module to
+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
+ >>> from z3c.form.interfaces import IFormLayer
+
+ >>> def make_request(form={}):
+ ... request = TestRequest()
+ ... request.form.update(form)
+ ... alsoProvides(request, IFormLayer)
+ ... alsoProvides(request, IAttributeAnnotatable)
+ ... return request
+
+Then we create a simple z3c form::
+
+ >>> from zope import interface, schema
+ >>> from z3c.form import form, field, button
+ >>> from plone.z3cform.layout import FormWrapper
+
+ >>> class MySchema(interface.Interface):
+ ... age = schema.Int(title=u"Age")
+
+ >>> from z3c.form.interfaces import IFieldsForm
+ >>> from zope.interface import implements
+ >>> class MyWrappedForm(form.Form):
+ ... implements(IFieldsForm)
+ ... fields = field.Fields(MySchema)
+ ... ignoreContext = True # don't use context to get widget data
+ ...
+ ... @button.buttonAndHandler(u'Apply')
+ ... def handleApply(self, action):
+ ... data, errors = self.extractData()
+ ... print data['age'] # ... or do stuff
+
+ >>> class MyFormWrapper(FormWrapper):
+ ... form = MyWrappedForm
+ ... label = u"Please enter your age"
+
+ >>> from zope.component import provideAdapter
+ >>> from zope.publisher.interfaces.browser import IBrowserRequest
+ >>> from zope.interface import Interface
+
+ >>> provideAdapter(adapts=(Interface, IBrowserRequest),
+ ... provides=Interface,
+ ... factory=MyFormWrapper,
+ ... name=u"test-form")
+
+Let's verify that worked:
+
+ >>> from zope.component import getMultiAdapter
+ >>> context = object()
+ >>> request = make_request()
+ >>> getMultiAdapter((context, request), name=u"test-form")
+ ... # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ <MyFormWrapper object ...>
+
+We can also use a function called ``wrap_form`` to wrap our form in a
+layout. We define a custom layout template first:
+
+ >>> import os
+ >>> import tempfile
+ >>> from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+ >>> fd, path = tempfile.mkstemp()
+ >>> f = os.fdopen(fd, 'w')
+ >>> f.write("""
+ ... <html>Hello, this is your layout speaking:
+ ... <div tal:content="structure view/contents"></div>
+ ... </html>""")
+ >>> f.close()
+ >>> 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.
+
+ >>> from plone.z3cform.layout import wrap_form
+ >>> view_class = wrap_form(MyWrappedForm, index=layout)
+ >>> 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:
+
+ >>> 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:...Age...</html>
+ >>> os.unlink(path)
+
+Send bad data to the form:
+
+ >>> request = make_request(form={'form.widgets.age': '12.1'})
+ >>> from zope.interface import Interface, implements
+ >>> formWrapper = getMultiAdapter((context, request), name=u"test-form")
+ >>> form = formWrapper.form(context, request)
+ >>> form.update()
+ >>> data, errors = form.extractData()
+ >>> data
+ {}
+ >>> errors
+ (<ValueErrorViewSnippet for ValueError>,)
+
+And then send correct data to the form:
+
+ >>> request = make_request(form={'form.widgets.age': '12'})
+ >>> from zope.interface import Interface, implements
+ >>> from Acquisition import Implicit
+ >>> formWrapper = getMultiAdapter((context, request), name=u"test-form")
+ >>> form = formWrapper.form(context, request)
+ >>> form.update()
+ >>> data, errors = form.extractData()
+ >>> data
+ {'age': 12}
+ >>> errors
+ ()
+
+
+
Modified: plone.z3cform/trunk/plone/z3cform/tests.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/tests.py 2008-07-22 20:17:50 UTC (rev 88734)
+++ plone.z3cform/trunk/plone/z3cform/tests.py 2008-07-22 20:20:19 UTC (rev 88735)
@@ -55,14 +55,14 @@
testing_zcml_path, 'plone.z3cform', 'testing_zcml_layer')
def test_suite():
- base_txt = doctest.DocFileSuite('base.txt')
- base_txt.layer = testing_zcml_layer
+ layout_txt = doctest.DocFileSuite('layout.txt')
+ layout_txt.layer = testing_zcml_layer
fieldsets_txt = doctest.DocFileSuite('fieldsets/README.txt')
fieldsets_txt.layer = testing_zcml_layer
return unittest.TestSuite([
- base_txt, fieldsets_txt,
+ layout_txt, fieldsets_txt,
doctest.DocFileSuite(
'crud/README.txt',
More information about the Checkins
mailing list