[Checkins] SVN: z3c.viewtemplate/ This package allows to separate
the registration of the view code and the
Jürgen Kartnaller
juergen at kartnaller.at
Thu Sep 14 16:39:47 EDT 2006
Log message for revision 70182:
This package allows to separate the registration of the view code and the
view templates.
Changed:
A z3c.viewtemplate/
A z3c.viewtemplate/trunk/
A z3c.viewtemplate/trunk/src/
A z3c.viewtemplate/trunk/src/z3c/
A z3c.viewtemplate/trunk/src/z3c/__init__.py
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/README.txt
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/SETUP.cfg
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/__init__.py
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/baseview.py
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/meta.zcml
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/tests.py
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/z3c.viewtemplate-meta.zcml
A z3c.viewtemplate/trunk/src/z3c/viewtemplate/zcml.py
-=-
Added: z3c.viewtemplate/trunk/src/z3c/__init__.py
===================================================================
Property changes on: z3c.viewtemplate/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/README.txt
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/README.txt 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/README.txt 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1,116 @@
+============
+ViewTemplate
+============
+
+This package allows us to separate the registration of the view code and the
+view templates.
+
+Why is this a good thing?
+
+While developing customizable applications that require us to develop multiple
+customer UIs for one particular application, we noticed there is a fine but
+clear distinction between skins and layers. Layers contain the logic to
+prepare data for presentation output, namely the view classes. Skins, on the
+other hand contain the resources to generate the UI, for example templates,
+images and CSS files.
+
+The problem of the existing infrastructure is that code, template and layer are all
+hardlinked in one zcml configuration directive of the view component -- page,
+content provider, viewlet. This package separates this triplet -- code, template,
+layer -- into two pairs, code/layer and template/skin. No additional
+components are introduced, since skins and layers are physically the same
+components.
+
+Before we can setup a view component using this new method, we have to first
+create a template ...
+
+ >>> import os, tempfile
+ >>> temp_dir = tempfile.mkdtemp()
+ >>> template = os.path.join(temp_dir, 'demoTemplate.pt')
+ >>> open(template, 'w').write('''<div>demo</div>''')
+
+and the view code:
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest()
+
+ >>> from zope import interface
+ >>> from z3c.viewtemplate.baseview import BaseView
+ >>> class IMyView(interface.Interface):
+ ... pass
+ >>> class MyView(BaseView):
+ ... interface.implements(IMyView)
+
+ >>> view = MyView(root, request)
+
+Since the template is not yet registered, rendering the view will fail:
+
+ >>> print view()
+ Traceback (most recent call last):
+ ...
+ ComponentLookupError: ......
+
+Let's now register the template (commonly done using ZCML):
+
+ >>> from zope import component
+ >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+ >>> from z3c.viewtemplate.zcml import TemplateFactory
+ >>> from zope.pagetemplate.interfaces import IPageTemplate
+
+The template factory allows us to create a ViewPageTeplateFile instance.
+
+ >>> factory = TemplateFactory(template, 'text/html')
+
+We register the factory on a view interface and a layer.
+
+ >>> component.provideAdapter(factory,
+ ... (interface.Interface, IDefaultBrowserLayer),
+ ... IPageTemplate)
+ >>> template = component.getMultiAdapter(
+ ... (view, request), IPageTemplate)
+ >>> template
+ <zope.app.pagetemplate.viewpagetemplatefile.ViewPageTemplateFile ...>
+
+Now that we have a registered template for the default layer we can call our
+view again.
+
+ >>> print view()
+ <div>demo</div>
+
+Now we register a new template on the specific interface of our view.
+
+ >>> myTemplate = os.path.join(temp_dir, 'demoTemplate.pt')
+ >>> open(myTemplate, 'w').write('''<div>IMyView</div>''')
+ >>> factory = TemplateFactory(myTemplate, 'text/html')
+ >>> component.provideAdapter(factory,
+ ... (IMyView, IDefaultBrowserLayer),
+ ... IPageTemplate)
+ >>> print view()
+ <div>IMyView</div>
+
+It is possible to provide the template directly.
+
+We create a new template.
+
+ >>> viewTemplate = os.path.join(temp_dir, 'viewTemplate.pt')
+ >>> open(viewTemplate, 'w').write('''<div>view</div>''')
+
+ >>> from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+ >>> class MyViewWithTemplate(BaseView):
+ ... interface.implements(IMyView)
+ ... template = ViewPageTemplateFile(viewTemplate)
+ >>> templatedView = MyViewWithTemplate(root, request)
+
+If we render this view we get the original template and not the registered
+one.
+
+ >>> print templatedView()
+ <div>view</div>
+
+
+Why didn't we use named templates from the ``zope.formlib`` package?
+
+While named templates allow us to separate the view code from the template
+registration, they are not registerable for a particular layer making it
+impossible to implement multiple skins using named templates.
+
Property changes on: z3c.viewtemplate/trunk/src/z3c/viewtemplate/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/SETUP.cfg
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/SETUP.cfg 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/SETUP.cfg 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+ z3c.viewtemplate-*.zcml
+</data-files>
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/__init__.py
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/__init__.py 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/__init__.py 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1 @@
+# package
Property changes on: z3c.viewtemplate/trunk/src/z3c/viewtemplate/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/baseview.py
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/baseview.py 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/baseview.py 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1,48 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope import interface
+from zope import component
+
+from zope.contentprovider.interfaces import IContentProvider
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.publisher.browser import BrowserView
+
+
+class TemplatedContentProvider(object):
+ interface.implements(IContentProvider)
+
+ template = None
+
+ def update(self):
+ pass
+
+ def render(self):
+ if self.template is None:
+ template = component.getMultiAdapter(
+ (self, self.request), IPageTemplate)
+ return template(self)
+ return self.template()
+
+
+class BaseView(TemplatedContentProvider, BrowserView):
+
+ def __call__(self):
+ self.update()
+ return self.render()
+
Property changes on: z3c.viewtemplate/trunk/src/z3c/viewtemplate/baseview.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/meta.zcml
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/meta.zcml 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/meta.zcml 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1,16 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:meta="http://namespaces.zope.org/meta">
+
+ <meta:directives namespace="http://namespaces.zope.org/browser">
+
+ <meta:directive
+ name="template"
+ schema=".zcml.ITemplateDirective"
+ handler=".zcml.templateDirective"
+ />
+
+ </meta:directives>
+
+</configure>
+
Property changes on: z3c.viewtemplate/trunk/src/z3c/viewtemplate/meta.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/tests.py
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/tests.py 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/tests.py 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+
+from zope.testing import doctest
+from zope.testing.doctestunit import DocFileSuite
+from zope.app.testing import setup
+
+
+def setUp(test):
+ root = setup.placefulSetUp(site=True)
+ test.globs['root'] = root
+
+
+def tearDown(test):
+ setup.placefulTearDown()
+
+
+def test_suite():
+ return unittest.TestSuite((
+ DocFileSuite('README.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: z3c.viewtemplate/trunk/src/z3c/viewtemplate/tests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/z3c.viewtemplate-meta.zcml
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/z3c.viewtemplate-meta.zcml 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/z3c.viewtemplate-meta.zcml 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1,6 @@
+<configure
+ xmlns:zcml="http://namespaces.zope.org/zcml">
+
+ <include package="z3c.viewtemplate" file="meta.zcml" />
+
+</configure>
Property changes on: z3c.viewtemplate/trunk/src/z3c/viewtemplate/z3c.viewtemplate-meta.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.viewtemplate/trunk/src/z3c/viewtemplate/zcml.py
===================================================================
--- z3c.viewtemplate/trunk/src/z3c/viewtemplate/zcml.py 2006-09-14 19:39:03 UTC (rev 70181)
+++ z3c.viewtemplate/trunk/src/z3c/viewtemplate/zcml.py 2006-09-14 20:39:46 UTC (rev 70182)
@@ -0,0 +1,99 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import os
+
+from zope import interface
+from zope import component
+from zope import schema
+
+from zope.component import zcml
+
+from zope.configuration.exceptions import ConfigurationError
+import zope.configuration.fields
+
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.configuration.fields import GlobalObject
+
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+
+from zope.i18nmessageid import MessageFactory
+_ = MessageFactory('zope')
+
+
+class ITemplateDirective(interface.Interface):
+ """Parameters for the template directive."""
+
+ template = zope.configuration.fields.Path(
+ title=_("Content-generating template."),
+ description=_("Refers to a file containing a page template (should "
+ "end in extension ``.pt`` or ``.html``)."),
+ required=False,
+ )
+
+ for_ = GlobalObject(
+ title = _(u'View'),
+ description = _(u'The view for which the template should be used'),
+ required = False,
+ default=interface.Interface,
+ )
+
+ layer = GlobalObject(
+ title = _(u'Layer'),
+ description = _(u'The layer for which the template should be used'),
+ required = False,
+ default=IDefaultBrowserLayer,
+ )
+
+ contentType = GlobalObject(
+ title = _(u'Content Type'),
+ description = _(u'The content type that will be set as part of '
+ 'HTTP headers'),
+ required = False,
+ default='text/html',
+ )
+
+
+class TemplateFactory(object):
+
+ def __init__(self, filename, contentType):
+ self.filename = filename
+ self.contentType = contentType
+
+ def __call__(self, view, request):
+ return ViewPageTemplateFile(self.filename,
+ content_type=self.contentType)
+
+
+def templateDirective(_context,
+ template,
+ for_=interface.Interface,
+ layer=IDefaultBrowserLayer,
+ contentType='text/html',
+ ):
+ # Make sure that the template exists
+ template = os.path.abspath(str(_context.path(template)))
+ if not os.path.isfile(template):
+ raise ConfigurationError("No such file", template)
+
+ factory = TemplateFactory(template, contentType)
+
+ # register the template
+ zcml.adapter(_context, (factory,), IPageTemplate, (for_, layer))
+
Property changes on: z3c.viewtemplate/trunk/src/z3c/viewtemplate/zcml.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
More information about the Checkins
mailing list