[Checkins] SVN: z3c.pagelet/trunk/src/z3c/pagelet/zcml. Added provides attribute for pagelets directive.

Roger Ineichen roger at projekt01.ch
Tue May 22 22:58:50 EDT 2007


Log message for revision 75901:
  Added provides attribute for pagelets directive.
  This allows us to use enhanced IPagelet interfaces
  which makes it possible to specify e.g. IAddPagelets 
  and collect them by getAdapters.
  
  Added unit tests

Changed:
  U   z3c.pagelet/trunk/src/z3c/pagelet/zcml.py
  U   z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt

-=-
Modified: z3c.pagelet/trunk/src/z3c/pagelet/zcml.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/zcml.py	2007-05-22 20:47:05 UTC (rev 75900)
+++ z3c.pagelet/trunk/src/z3c/pagelet/zcml.py	2007-05-23 02:58:48 UTC (rev 75901)
@@ -57,11 +57,21 @@
         )
 
     for_ = zope.configuration.fields.GlobalObject(
-        title=u"The interface or class this pagelet is for.",
+        title=u"Context",
+        description=u"The content interface or class this pagelet is for.",
         required=False
         )
 
+    provides = zope.configuration.fields.GlobalInterface(
+        title=u"The interface this pagelets provides.",
+        description=u"""
+        A pagelet can provide an interface.  This would be used for
+        views that support other views.""",
+        required=False,
+        default=interfaces.IPagelet,
+        )
 
+
 # Arbitrary keys and values are allowed to be passed to the pagelet.
 IPageletDirective.setTaggedValue('keyword_arguments', True)
 
@@ -69,8 +79,8 @@
 # pagelet directive
 def pageletDirective(
     _context, class_, name, permission, for_=zope.interface.Interface, 
-    layer=IDefaultBrowserLayer, allowed_interface=None, 
-    allowed_attributes=None, **kwargs):
+    layer=IDefaultBrowserLayer, provides=interfaces.IPagelet, 
+    allowed_interface=None, allowed_attributes=None, **kwargs):
 
     # Security map dictionary
     required = {}
@@ -82,6 +92,13 @@
     if not class_:
         raise ConfigurationError("Must specify a class.")
 
+    if not zope.interface.interfaces.IInterface.providedBy(provides):
+        raise ConfigurationError("Provides interface provide IInterface.")
+
+    ifaces = list(zope.interface.Declaration(provides).flattened())
+    if interfaces.IPagelet not in ifaces:
+        raise ConfigurationError("Provides interface must inherit IPagelet.")
+
     # Build a new class that we can use different permission settings if we
     # use the class more then once.
     cdict = {}
@@ -103,6 +120,10 @@
     # Register the interfaces.
     viewmeta._handle_for(_context, for_)
 
+    # provide the custom provides interface if not allready provided
+    if not provides.implementedBy(new_class):
+        zope.interface.classImplements(new_class, provides)
+
     # Create the security checker for the new class
     zope.security.checker.defineChecker(new_class, 
         zope.security.checker.Checker(required))
@@ -112,5 +133,4 @@
         discriminator = ('pagelet', for_, layer, name),
         callable = zope.component.zcml.handler,
         args = ('registerAdapter',
-                new_class, (for_, layer), interfaces.IPagelet,
-                 name, _context.info),)
+                new_class, (for_, layer), provides, name, _context.info),)

Modified: z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt	2007-05-22 20:47:05 UTC (rev 75900)
+++ z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt	2007-05-23 02:58:48 UTC (rev 75901)
@@ -87,7 +87,6 @@
 Get the pagelet for the new content object
 
   >>> import zope.component
-  >>> from zope.publisher.browser import TestRequest
   >>> pagelet = zope.component.queryMultiAdapter((Content(), TestRequest()), 
   ...     name='custom.html')
 
@@ -99,6 +98,65 @@
   >>> pagelet.label
   u'my Label'
 
+We also can provide another interface then the IPagelet within the directive.
+Such a interface must be inherited from IPagelet.
+
+  >>> class NewPagelet(BrowserPagelet):
+  ...     """New pagelet"""
+  >>> sys.modules['custom'] = type(
+  ...     'Module', (), 
+  ...     {'NewPagelet': NewPagelet})()
+
+Now register the pagelet within a interface which isn't inherited from IPagelet.
+
+  >>> context = xmlconfig.string("""
+  ... <configure
+  ...     xmlns:z3c="http://namespaces.zope.org/z3c">
+  ...   <z3c:pagelet
+  ...       name="new.html"
+  ...       class="custom.NewPagelet"
+  ...       permission="zope.Public"
+  ...       provides="zope.interface.Interface"
+  ...       />
+  ... </configure>
+  ... """, context)
+  Traceback (most recent call last):
+  ...
+  ZopeXMLConfigurationError: File "<string>", line 4.2-9.8
+  ConfigurationError: Provides interface must inherit IPagelet.
+
+If we use a correct interface, we can register the pagelet:
+
+  >>> from z3c.pagelet import interfaces
+  >>> class INewPagelet(interfaces.IPagelet):
+  ...     """New pagelet interface."""
+  >>> sys.modules['custom'] = type(
+  ...     'Module', (), 
+  ...     {'INewPagelet': INewPagelet, 'NewPagelet': NewPagelet})()
+
+  >>> context = xmlconfig.string("""
+  ... <configure
+  ...     xmlns:z3c="http://namespaces.zope.org/z3c">
+  ...   <z3c:pagelet
+  ...       name="new.html"
+  ...       class="custom.NewPagelet"
+  ...       permission="zope.Public"
+  ...       provides="custom.INewPagelet"
+  ...       />
+  ... </configure>
+  ... """, context)
+
+And if we get the pagelet, we can see that the object provides the new 
+pagelet interface:
+
+  >>> pagelet = zope.component.queryMultiAdapter((object(), TestRequest()), 
+  ...     name='new.html')
+  >>> pagelet
+  <z3c.pagelet.zcml.NewPagelet object at ...>
+
+  >>> INewPagelet.providedBy(pagelet)
+  True
+
 Now we need to clean up the custom module.
 
   >>> del sys.modules['custom']



More information about the Checkins mailing list