[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