[Checkins] SVN: plone.z3cform/trunk/ * Look up the layout template as an IPageTemplate adapter. This means that
Martin Aspeli
optilude at gmx.net
Mon Aug 18 16:53:39 EDT 2008
Log message for revision 89978:
* Look up the layout template as an IPageTemplate adapter. This means that
it is possible for Plone to provide a "Ploneish" default template for forms
that don't opt into this, without those forms having a direct Plone
dependency.
Changed:
U plone.z3cform/trunk/docs/HISTORY.txt
A plone.z3cform/trunk/plone/z3cform/interfaces.py
U plone.z3cform/trunk/plone/z3cform/layout.py
U plone.z3cform/trunk/plone/z3cform/layout.txt
U plone.z3cform/trunk/plone/z3cform/templates.py
U plone.z3cform/trunk/plone/z3cform/templates.zcml
-=-
Modified: plone.z3cform/trunk/docs/HISTORY.txt
===================================================================
--- plone.z3cform/trunk/docs/HISTORY.txt 2008-08-18 19:12:50 UTC (rev 89977)
+++ plone.z3cform/trunk/docs/HISTORY.txt 2008-08-18 20:53:38 UTC (rev 89978)
@@ -4,6 +4,11 @@
0.5.1 - Unreleased
------------------
+* Look up the layout template as an IPageTemplate adapter. This means that
+ it is possible for Plone to provide a "Ploneish" default template for forms
+ that don't opt into this, without those forms having a direct Plone
+ dependency.
+
* Default to the titleless form template, since the layout template will
provide a title anyway.
Added: plone.z3cform/trunk/plone/z3cform/interfaces.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/interfaces.py (rev 0)
+++ plone.z3cform/trunk/plone/z3cform/interfaces.py 2008-08-18 20:53:38 UTC (rev 89978)
@@ -0,0 +1,21 @@
+from zope.interface import Interface, Attribute
+from zope import schema
+
+from zope.pagetemplate.interfaces import IPageTemplate
+from z3c.form.interfaces import IForm
+
+class IFormWrapper(Interface):
+ """Marker interface for the form wrapper
+ """
+
+ form = Attribute("The form class. Should be set at class level")
+
+ form_instance = schema.Object(title=u"Instance of the form being rendered",
+ description=u"Set by the wrapper code during __init__()",
+ readonly=True,
+ schema=IForm)
+
+ index = schema.Object(title=u"Page template instance",
+ description=u"If not set, a template will be found via an adapter lookup",
+ required=False,
+ schema=IPageTemplate)
\ No newline at end of file
Modified: plone.z3cform/trunk/plone/z3cform/layout.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/layout.py 2008-08-18 19:12:50 UTC (rev 89977)
+++ plone.z3cform/trunk/plone/z3cform/layout.py 2008-08-18 20:53:38 UTC (rev 89978)
@@ -1,7 +1,14 @@
import z3c.form.interfaces
+
+import zope.interface
+import zope.component
+
from Products.Five import BrowserView
+
+from zope.pagetemplate.interfaces import IPageTemplate
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+from plone.z3cform import interfaces
from plone.z3cform import z2
class FormWrapper(BrowserView):
@@ -13,15 +20,19 @@
Use the 'wrap' function in this module if you don't like defining
classes.
"""
- index = ViewPageTemplateFile('layout.pt')
+
+ zope.interface.implements(interfaces.IFormWrapper)
+
form = None # override this with a form class.
+
+ index = None # override with a page template, or rely on an adapter
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__
+ self.form_instance = self.form(self.context.aq_inner, self.request)
+ self.form_instance.__name__ = self.__name__
def __call__(self):
"""This method renders the outer skeleton template, which in
@@ -29,8 +40,12 @@
We use an indirection to 'self.index' here to allow users to
override the skeleton template through the 'browser' zcml
- directive.
+ directive. If no index template is set, we look up a an adapter from
+ (self, request) to IPageTemplate and use that instead.
"""
+ if self.index is None:
+ template = zope.component.getMultiAdapter((self, self.request), IPageTemplate)
+ return template.__of__(self)(self)
return self.index()
def contents(self):
@@ -48,14 +63,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_instance()
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
+ return self.form_instance.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-18 19:12:50 UTC (rev 89977)
+++ plone.z3cform/trunk/plone/z3cform/layout.txt 2008-08-18 20:53:38 UTC (rev 89978)
@@ -122,7 +122,7 @@
>>> 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:
@@ -151,5 +151,26 @@
>>> errors
()
+We also have the option of defining a default layout template for all forms
+that don't specify a particular 'index' template. Here, we use the 'path'
+function from plone.z3cform.templates to locate a template file (the default
+template, in fact) from the plone.z3cform directory. For your own purposes,
+you probably just want to specify a filename relative to your package.
+ >>> new_view_class = wrap_form(MyLabelledForm)
+ >>> view = new_view_class(context, request).__of__(context)
+
+ >>> from plone.z3cform.templates import ZopeTwoFormTemplateFactory
+ >>> layout_factory = ZopeTwoFormTemplateFactory(
+ ... path, form=new_view_class)
+Note that the 'form' parameter here should be the wrapper view class, or an
+interface implemented by it, not the form class itself.
+
+ >>> provideAdapter(layout_factory)
+ >>> print view() # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
+ <html>Hello, this is your layout speaking:...Another label...Age...</html>
+
+Clean up:
+
+ >>> os.unlink(path)
\ No newline at end of file
Modified: plone.z3cform/trunk/plone/z3cform/templates.py
===================================================================
--- plone.z3cform/trunk/plone/z3cform/templates.py 2008-08-18 19:12:50 UTC (rev 89977)
+++ plone.z3cform/trunk/plone/z3cform/templates.py 2008-08-18 20:53:38 UTC (rev 89978)
@@ -11,10 +11,27 @@
import z3c.form.interfaces
from z3c.form.form import FormTemplateFactory
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
import plone.z3cform
+import plone.z3cform.layout
path = lambda p: os.path.join(os.path.dirname(plone.z3cform.__file__), p)
+# Zope 2 land - the wrapper
+
+class ZopeTwoFormTemplateFactory(FormTemplateFactory):
+ """Form template factory for Zope 2 templates"""
+
+ def __init__(self, filename, contentType='text/html', form=None, request=None):
+ super(ZopeTwoFormTemplateFactory, self).__init__(filename, contentType, form, request)
+ self.template = ViewPageTemplateFile(filename, content_type=contentType)
+
+layout_factory = ZopeTwoFormTemplateFactory(
+ path('layout.pt'), form=plone.z3cform.interfaces.IFormWrapper)
+
+# Zope 3 land - the forms
+
form_factory = FormTemplateFactory(
path('form.pt'), form=z3c.form.interfaces.IForm)
subform_factory = FormTemplateFactory(
Modified: plone.z3cform/trunk/plone/z3cform/templates.zcml
===================================================================
--- plone.z3cform/trunk/plone/z3cform/templates.zcml 2008-08-18 19:12:50 UTC (rev 89977)
+++ plone.z3cform/trunk/plone/z3cform/templates.zcml 2008-08-18 20:53:38 UTC (rev 89978)
@@ -14,5 +14,6 @@
<adapter factory=".templates.form_factory" />
<adapter factory=".templates.subform_factory" />
+ <adapter factory=".templates.layout_factory" />
</configure>
More information about the Checkins
mailing list