[Checkins] SVN: z3c.macroviewlet/ Added z3c.macroviewlet implementation

Roger Ineichen roger at projekt01.ch
Wed Jan 17 20:03:09 EST 2007


Log message for revision 72086:
  Added z3c.macroviewlet implementation

Changed:
  A   z3c.macroviewlet/branches/
  A   z3c.macroviewlet/tags/
  A   z3c.macroviewlet/trunk/
  A   z3c.macroviewlet/trunk/src/
  A   z3c.macroviewlet/trunk/src/z3c/
  A   z3c.macroviewlet/trunk/src/z3c/__init__.py
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/README.txt
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/SETUP.cfg
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/__init__.py
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/configure.zcml
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/meta.zcml
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/tests.py
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-configure.zcml
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-meta.zcml
  A   z3c.macroviewlet/trunk/src/z3c/macroviewlet/zcml.py

-=-
Added: z3c.macroviewlet/trunk/src/z3c/__init__.py
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/__init__.py	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/__init__.py	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2006 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$
+"""


Property changes on: z3c.macroviewlet/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/README.txt
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/README.txt	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/README.txt	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,207 @@
+==============
+Macro Provider
+==============
+
+This package provides a ZCML directive which allows you to register a macro 
+deined in a template as a viewlet. Such a macro based viewlet acts 100% the 
+same as a other viewlets. It could be very handy if you like to write a layout 
+template in one page template and define selective parts as viewlets without 
+to add any additional HTML. Let me show how this will look like:
+
+The layout/master template can look like this:
+
+  <!DOCTYPE ...>
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
+        i18n:domain="z3c">
+  <head>
+  <tal:block replace="structure provider:ITitle">
+    <metal:block define-macro="title">
+      <title>The title</title>
+    </metal:block>
+  </tal:block>
+  </head>
+  <body tal:define="applicationURL request/getApplicationURL">
+  <div id="content">
+    <tal:block content="structure provider:pagelet">content</tal:block>
+  </div>
+  </div>
+  </body>
+  </html>
+
+The tempalte aboce defines a ITitle provider which contains the definition 
+for a macro in itself. Yo have to define a viewlet manager within the 
+zope.viewlet ZCMl directive which provides ITitle as a viewlet manager.
+After that you can register the template above as a layout template wthin
+the z3c:layout ZCML directive like:
+
+  <z3c:layout
+      for="*"
+      layer="z3c.skin.pagelet.IPageletBrowserSkin"
+      template="template.pt"
+      />
+
+After that you can register the macro viewlet for the ITitle viewlet manager
+like this:
+
+  <z3c:macroProvider
+      for="*"
+      template="template.pt"
+      macro="title"
+      manager="z3c.skin.pagelet.ITitle"
+      layer="z3c.skin.pagelet.IPageletBrowserSkin"
+      />
+
+As you can see the ZCML configuration directive above uses ``title`` as the
+macro attribute and uses ITitle as the viewlet manager. This will use the 
+following part of the template.pt 
+
+  <title>Pagelet skin</title>
+
+and registers it as a viewlet. This viewlet get rendered in the ITitle 
+provider. Ay you can see you can use a complete layout tempalte and use it
+as it is. And here it comes, you can offer a included viewlet manager 
+rendering the viewlet which can get overriden for other context or views etc.
+You also can register more the one viewlet for the ITitle viewlet manager.
+Wich of corse makes no sense in our special title tag example.
+
+Let's show this in some tests. We start with creating a content object that 
+is used as a view context later:
+
+  >>> import zope.interface
+  >>> import zope.component
+  >>> from zope.publisher.interfaces.browser import IBrowserView
+  >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+  >>> class Content(object):
+  ...     zope.interface.implements(zope.interface.Interface)
+
+  >>> content = Content()
+
+We also create a temp dir for sample templates which we define later for 
+testing:
+
+  >>> import os, tempfile
+  >>> temp_dir = tempfile.mkdtemp()
+
+And we register security checker for the MacroViewlet class:
+
+  >>> from zope.configuration.xmlconfig import XMLConfig
+  >>> import zope.app.component
+  >>> import z3c.macroviewlet
+  >>> XMLConfig('meta.zcml', zope.app.component)()
+  >>> XMLConfig('configure.zcml', z3c.macroviewlet)()
+
+
+Layout template
+---------------
+
+We define a template including a macro definition and using a provider:
+
+  >>> path = os.path.join(temp_dir, 'template.pt')
+  >>> open(path, 'w').write('''
+  ... <html>
+  ... <body>
+  ... <head>
+  ... <tal:block replace="structure provider:ITitle">
+  ...   <metal:block define-macro="title">
+  ...     <title>The title</title>
+  ...   </metal:block>
+  ... </tal:block>
+  ... </head>
+  ... <body tal:define="applicationURL request/getApplicationURL">
+  ...   content
+  ... </body>
+  ... </html>
+  ... ''')
+
+Let's register a view class using the view template:
+
+  >>> import zope.interface
+  >>> from zope.app.pagetemplate import viewpagetemplatefile
+  >>> from zope.publisher.interfaces.browser import IBrowserView
+  >>> class View(object):
+  ...     zope.interface.implements(IBrowserView)
+  ...     def __init__(self, context, request):
+  ...        self.context = context
+  ...        self.request = request
+  ...     def __call__(self):
+  ...         return viewpagetemplatefile.ViewPageTemplateFile(path)(self)
+
+Let's prepare the view.
+
+  >>> from zope.publisher.browser import TestRequest
+  >>> request = TestRequest()
+  >>> view = View(content, request)
+
+Let's define the viewlet manager ``ITitle``:
+
+  >>> from zope.viewlet.interfaces import IViewletManager
+  >>> from zope.viewlet.manager import ViewletManager
+  >>> class ITitle(IViewletManager):
+  ...     """Viewlet manager located in the title tag."""
+
+  >>> title = ViewletManager('title', ITitle)
+
+Let's register the viewlet manager:
+
+  >>> from zope.viewlet.interfaces import IViewletManager
+  >>> manager = zope.component.provideAdapter(
+  ...     title,
+  ...     (zope.interface.Interface, TestRequest, IBrowserView),
+  ...     IViewletManager, 
+  ...     name='ITitle')
+
+
+MacroViewlet
+------------
+
+Before we register the macro viewlet, we check the rendered page without any
+registered macro viewlet:
+
+  >>> print view()
+  <html>
+  <body>
+  <head>
+  </head>
+  <body>
+    content
+  </body>
+  </body></html>
+
+As you can see there is no title rendered. Now we can define the macro 
+viewlet...
+
+  >>> from zope.app.pagetemplate import viewpagetemplatefile
+  >>> from z3c.macroviewlet import zcml
+  >>> macroViewlet = zcml.MacroViewletFactory(path, 'title', 'text/html')
+
+and register them as adapter:
+
+  >>> from zope.viewlet.interfaces import IViewlet
+  >>> zope.component.provideAdapter(
+  ...     macroViewlet,
+  ...     (zope.interface.Interface, IDefaultBrowserLayer, IBrowserView, 
+  ...      ITitle),
+  ...     IViewlet,
+  ...     name='title')
+
+Now we are ready to test it again:
+
+  >>> print view()
+  <html>
+  <body>
+  <head>
+      <title>The title</title>
+  </head>
+  <body>
+    content
+  </body>
+  </body></html>
+
+As you can see, the title get rendered as a viewlet into the ITitle provider.
+
+Cleanup
+-------
+
+  >>> import shutil
+  >>> shutil.rmtree(temp_dir)
+


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/SETUP.cfg
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/SETUP.cfg	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/SETUP.cfg	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  z3c.macroviewlet-*.zcml
+</data-files>


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/__init__.py
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/__init__.py	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/__init__.py	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2006 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$
+"""


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/configure.zcml
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/configure.zcml	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/configure.zcml	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,11 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope">
+
+  <class class=".zcml.MacroViewlet">
+    <require
+        permission="zope.Public"
+        interface="zope.viewlet.interfaces.IViewlet"
+        />
+  </class>
+
+</configure>


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/meta.zcml
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/meta.zcml	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/meta.zcml	2007-01-18 01:03:08 UTC (rev 72086)
@@ -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/z3c">
+
+    <meta:directive
+        name="macroViewlet"
+        schema=".zcml.IMacroViewletDirective"
+        handler=".zcml.macroViewletDirective"
+        />
+
+  </meta:directives>
+
+</configure>
+


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/meta.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/tests.py
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/tests.py	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/tests.py	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation 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.
+#
+##############################################################################
+"""Viewlet tests
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+import os.path
+import unittest
+import zope.security
+from zope.testing import doctest
+from zope.testing.doctestunit import DocFileSuite
+from zope.app.testing import setup
+from z3c.testing import setUpContentMetaDirectives
+
+class TestParticipation(object):
+    principal = 'foobar'
+    interaction = None
+
+
+def setUp(test):
+    root = setup.placefulSetUp(site=True)
+    test.globs['root'] = root
+    setUpContentMetaDirectives()
+
+    # register provider TALES
+    from zope.app.pagetemplate import metaconfigure
+    from zope.contentprovider import tales
+    metaconfigure.registerType('provider', tales.TALESProviderExpression)
+
+    zope.security.management.getInteraction().add(TestParticipation())
+
+
+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.macroviewlet/trunk/src/z3c/macroviewlet/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-configure.zcml
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-configure.zcml	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-configure.zcml	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,6 @@
+<configure
+    xmlns:zcml="http://namespaces.zope.org/zcml">
+
+  <include package="z3c.macroviewlet" />
+
+</configure>


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-configure.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-meta.zcml
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-meta.zcml	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-meta.zcml	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,6 @@
+<configure
+    xmlns:zcml="http://namespaces.zope.org/zcml">
+
+  <include package="z3c.macroviewlet" file="meta.zcml" />
+
+</configure>


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/z3c.macroviewlet-meta.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.macroviewlet/trunk/src/z3c/macroviewlet/zcml.py
===================================================================
--- z3c.macroviewlet/trunk/src/z3c/macroviewlet/zcml.py	2007-01-18 01:02:49 UTC (rev 72085)
+++ z3c.macroviewlet/trunk/src/z3c/macroviewlet/zcml.py	2007-01-18 01:03:08 UTC (rev 72086)
@@ -0,0 +1,144 @@
+##############################################################################
+#
+# 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 StringIO import StringIO
+
+import zope.interface
+import zope.schema
+import zope.configuration.fields
+from zope.configuration.exceptions import ConfigurationError
+from zope.component import zcml
+from zope.publisher.interfaces.browser import IBrowserView
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.tal.talinterpreter import TALInterpreter
+from zope.viewlet.interfaces import IViewlet
+from zope.viewlet.interfaces import IViewletManager
+from zope.viewlet import viewlet
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+
+
+class IMacroViewletDirective(zope.interface.Interface):
+    """Parameters for the template directive."""
+
+    template = zope.configuration.fields.Path(
+        title=u'Template defining a named macro.',
+        description=u"""Refers to a file containing a page template 
+            (should end in extension ``.pt`` or ``.html``).
+            """,
+        required=True,
+        )
+
+    macro = zope.schema.TextLine(
+        title=u'Macro',
+        description=u"""
+            The name of the macro to be used. This allows us to reference 
+            the named  macro defined with metal:define-macro if we use a 
+            different IMacroDirective name.
+            """,
+        required=True,
+        default=u'',
+        )
+
+    for_ = zope.configuration.fields.GlobalObject(
+        title=u'Context',
+        description=u'The context for which the macro should be used',
+        required=False,
+        default=zope.interface.Interface,
+        )
+
+    view = zope.configuration.fields.GlobalObject(
+        title=u'View',
+        description=u'The view for which the macro should be used',
+        required=False,
+        default=IBrowserView)
+
+    manager = zope.configuration.fields.GlobalObject(
+        title=u"Manager",
+        description=u"The interface of the manager this provider is for.",
+        required=False,
+        default=IViewletManager)
+
+    layer = zope.configuration.fields.GlobalObject(
+        title=u'Layer',
+        description=u'The layer for which the macro should be used',
+        required=False,
+        default=IDefaultBrowserLayer,
+        )
+
+    contentType = zope.schema.BytesLine(
+        title=u'Content Type',
+        description=u'The content type identifies the type of data.',
+        default='text/html',
+        required=False,
+        )
+
+
+class MacroViewlet(viewlet.ViewletBase):
+    """Provides a single macro from a template for rendering."""
+
+    def __init__(self, template, macroName, view, request, contentType):
+        self.template = template
+        self.macroName = macroName
+        self.view = view
+        self.request = request
+        self.contentType = contentType
+
+    def render(self):
+        program = self.template.macros[self.macroName]
+        output = StringIO(u'')
+        namespace = self.template.pt_getContext(self.view, self.request)
+        context = self.template.pt_getEngineContext(namespace)
+        TALInterpreter(program, None,
+                       context, output, tal=True, showtal=False,
+                       strictinsert=0, sourceAnnotations=False)()
+        if not self.request.response.getHeader("Content-Type"):
+            self.request.response.setHeader("Content-Type",
+                                            self.contentType)
+        return output.getvalue()
+
+
+class MacroViewletFactory(object):
+
+    def __init__(self, filename, macro, contentType):
+        self.filename = filename
+        self.macro = macro
+        self.contentType = contentType
+
+    def __call__(self, context, request, view, manager):
+        self.template= ViewPageTemplateFile(self.filename,
+                                                content_type=self.contentType)
+        return MacroViewlet(self.template, self.macro, view,
+                     request, self.contentType)
+
+
+def macroViewletDirective(_context, template, macro, 
+    for_=zope.interface.Interface, view=IBrowserView, 
+    layer=IDefaultBrowserLayer, manager=IViewletManager, 
+    contentType='text/html'):
+
+    # Make sure that the template exists
+    path = os.path.abspath(str(_context.path(template)))
+    if not os.path.isfile(path):
+        raise ConfigurationError("No such file", template)
+
+    factory = MacroViewletFactory(path, macro, contentType)
+
+    # register the macro provider
+    zcml.adapter(_context, (factory,), IViewlet, 
+        (for_, layer, view, manager), name=macro)


Property changes on: z3c.macroviewlet/trunk/src/z3c/macroviewlet/zcml.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the Checkins mailing list