[Checkins] SVN: z3ext.layout/trunk/ - Added `manager` attribute to z3ext:pagelet directive

Nikolay Kim fafhrd at datacom.kz
Wed Dec 3 07:49:03 EST 2008


Log message for revision 93574:
  - Added `manager` attribute to z3ext:pagelet directive
    this allow use getMultiAdapter((content, request, manager1, manager2, ...), IPagelet)
  
  - Use 'provides' schema for converting kwargs in z3ext:pagelet directive
  
  
  

Changed:
  U   z3ext.layout/trunk/CHANGES.txt
  U   z3ext.layout/trunk/src/z3ext/layout/interfaces.py
  U   z3ext.layout/trunk/src/z3ext/layout/pagelet.py
  U   z3ext.layout/trunk/src/z3ext/layout/pagelet.txt
  U   z3ext.layout/trunk/src/z3ext/layout/zcml.py

-=-
Modified: z3ext.layout/trunk/CHANGES.txt
===================================================================
--- z3ext.layout/trunk/CHANGES.txt	2008-12-03 12:46:26 UTC (rev 93573)
+++ z3ext.layout/trunk/CHANGES.txt	2008-12-03 12:49:03 UTC (rev 93574)
@@ -2,6 +2,15 @@
 CHANGES
 =======
 
+1.7.0 (Unreleased)
+------------------
+
+- Added `manager` attribute to z3ext:pagelet directive
+  this allow use getMultiAdapter((content, request, manager1, manager2, ...), IPagelet)
+
+- Use 'provides' schema for converting kwargs in z3ext:pagelet directive
+
+
 1.6.0 (2008-11-27)
 ------------------
 

Modified: z3ext.layout/trunk/src/z3ext/layout/interfaces.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/interfaces.py	2008-12-03 12:46:26 UTC (rev 93573)
+++ z3ext.layout/trunk/src/z3ext/layout/interfaces.py	2008-12-03 12:49:03 UTC (rev 93574)
@@ -26,6 +26,8 @@
 class IPagelet(IBrowserPage):
     """ pagelet """
 
+    managers = interface.Attribute('Additional managers')
+
     isRedirected = interface.Attribute('is redirected')
 
     def redirect(url=''):

Modified: z3ext.layout/trunk/src/z3ext/layout/pagelet.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/pagelet.py	2008-12-03 12:46:26 UTC (rev 93573)
+++ z3ext.layout/trunk/src/z3ext/layout/pagelet.py	2008-12-03 12:49:03 UTC (rev 93574)
@@ -61,6 +61,10 @@
     index = None
     template = None
 
+    def __init__(self, context, request, *args):
+        self.managers = args
+        super(BrowserPagelet, self).__init__(context, request)
+
     def update(self):
         pass
 

Modified: z3ext.layout/trunk/src/z3ext/layout/pagelet.txt
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/pagelet.txt	2008-12-03 12:46:26 UTC (rev 93573)
+++ z3ext.layout/trunk/src/z3ext/layout/pagelet.txt	2008-12-03 12:49:03 UTC (rev 93574)
@@ -6,7 +6,7 @@
 the directive.
 
   >>> import os, tempfile, sys
-  >>> from zope import interface, component
+  >>> from zope import interface, component, schema
   >>> from zope.configuration import xmlconfig
   >>> from z3ext.layout.interfaces import IPagelet
 
@@ -34,8 +34,8 @@
 Let's get the pagelet
 
   >>> from zope.publisher.browser import TestRequest
-  >>> pagelet = component.queryMultiAdapter((object(), TestRequest()), 
-  ...     name='index.html')
+  >>> pagelet = component.queryMultiAdapter(
+  ...     (object(), TestRequest()), name='index.html')
 
 and check them:
 
@@ -117,6 +117,67 @@
   >>> INewPagelet.providedBy(pagelet)
   True
 
+If any of provides interfaces define schema field, newlly create class
+will have this attribute. Let' redefine INewPagelet interface
+
+  >>> class INewPagelet2(interface.Interface):
+  ...     """New pagelet interface."""
+  ...     
+  ...     number = schema.Int(
+  ...         title = u'Number',
+  ...         required = True)
+
+Because NewPagelet class doesn't have 'number' attribute and we don't
+supply it in directive we get exception.
+
+  >>> xmlconfig.string("""
+  ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+  ...   <z3ext:pagelet
+  ...       name="new.html"
+  ...       class="z3ext.layout.TESTS.NewPagelet"
+  ...       permission="zope.Public"
+  ...       provides="z3ext.layout.TESTS.INewPagelet2" />
+  ... </configure>
+  ... """, context)
+  Traceback (most recent call last):
+  ...
+  ZopeXMLConfigurationError: ...Required field is missing...number...
+
+Let's provide 'number' in directive
+
+  >>> context = xmlconfig.string("""
+  ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+  ...   <z3ext:pagelet
+  ...       name="new1.html"
+  ...       class="z3ext.layout.TESTS.NewPagelet"
+  ...       permission="zope.Public"
+  ...       provides="z3ext.layout.TESTS.INewPagelet2"
+  ...       number="10" />
+  ... </configure>
+  ... """, context)
+
+  >>> pagelet = component.getMultiAdapter(
+  ...     (object(), TestRequest()), INewPagelet2, name='new1.html')
+  >>> print pagelet.number, ':', type(pagelet.number)
+  10 : <type 'int'>
+
+Value should be in right format
+
+  >>> context = xmlconfig.string("""
+  ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+  ...   <z3ext:pagelet
+  ...       name="new1.html"
+  ...       class="z3ext.layout.TESTS.NewPagelet"
+  ...       permission="zope.Public"
+  ...       provides="z3ext.layout.TESTS.INewPagelet2"
+  ...       number="xxxxx" />
+  ... </configure>
+  ... """, context)
+  Traceback (most recent call last):
+  ...
+  ZopeXMLConfigurationError: ...invalid literal for int()...
+
+
 We can create pagelet without specific class
 
   >>> context = xmlconfig.string("""
@@ -127,8 +188,8 @@
   ... </configure>
   ... """, context) 
 
-  >>> pagelet = component.queryMultiAdapter((object(), TestRequest()), 
-  ...     name='noclass.html')
+  >>> pagelet = component.queryMultiAdapter(
+  ...     (object(), TestRequest()), name='noclass.html')
   >>> pagelet
   <z3ext.layout.zcml.PageletClass from None ...>
 
@@ -169,6 +230,35 @@
   >>> pagelet.template
   <BoundPageTemplateFile of <z3ext.layout.zcml.PageletClass from None ...>>
 
+We can create pagelet with additional context
+
+  >>> class IContext2(interface.Interface):
+  ...     """ additional context """
+
+  >>> class Context2(object):
+  ...     interface.implements(IContext2)
+
+  >>> context = xmlconfig.string("""
+  ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+  ...   <z3ext:pagelet
+  ...       name="index.html"
+  ...       for="*"
+  ...       manager="z3ext.layout.TESTS.IContext2"
+  ...       permission="zope.Public" />
+  ... </configure>
+  ... """, context) 
+
+  >>> context2 = Context2()
+
+  >>> c2Pagelet = component.queryMultiAdapter(
+  ...     (object(), TestRequest(), context2), name='index.html')
+  >>> c2Pagelet
+  <z3ext.layout.zcml.PageletClass from None ...>
+
+  >>> c2Pagelet.managers
+  (<z3ext.layout.TESTS.Context2 ...>,)
+
+
 Pagelet rendering
 
   >>> print pagelet.render()

Modified: z3ext.layout/trunk/src/z3ext/layout/zcml.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/zcml.py	2008-12-03 12:46:26 UTC (rev 93573)
+++ z3ext.layout/trunk/src/z3ext/layout/zcml.py	2008-12-03 12:49:03 UTC (rev 93574)
@@ -17,6 +17,7 @@
 """
 import os.path
 from zope import schema, interface, event
+from zope.schema.interfaces import IFromUnicode
 from zope.component.interface import provideInterface
 from zope.component.zcml import handler, adapter, utility
 from zope.security.checker import defineChecker, Checker, CheckerPublic
@@ -51,6 +52,12 @@
         description = u"The name shows up in URLs/paths. For example 'foo'.",
         required = False)
 
+    manager = Tokens(
+        title = u"Additional managers.",
+        description = u"""A pagelet can adapt (for, layer). With managers pagelet can adats as (for, layer, manager1, manager2, manager3, ...)""",
+        required = False,
+        value_type = GlobalObject())
+
     provides = Tokens(
         title = u"The interface this pagelets provides.",
         description = u"""A pagelet can provide an interface.  This would be used for
@@ -275,8 +282,8 @@
 
 # pagelet directive
 def pageletDirective(
-    _context, permission, name=u'', class_=None, for_=interface.Interface,
-    layer=IDefaultBrowserLayer, provides=[IPagelet,],
+    _context, permission, for_=interface.Interface, name=u'', manager=(), 
+    class_=None, layer=IDefaultBrowserLayer, provides=[IPagelet,],
     allowed_interface=[], allowed_attributes=[],
     template=u'', layout=u'', **kwargs):
 
@@ -311,6 +318,21 @@
 
     new_class = type('PageletClass from %s'%class_, bases, cdict)
 
+    # convert kwargs
+    for iface in provides:
+        for fname, field in schema.getFields(iface).items():
+            if fname in kwargs:
+                if not IFromUnicode.providedBy(field):
+                    raise ConfigurationError("Can't convert value", fname)
+
+                setattr(new_class, fname, field.fromUnicode(kwargs[fname]))
+            else:
+                if field.required and not hasattr(new_class, fname):
+                    raise ConfigurationError("Required field is missing", fname)
+
+                if not hasattr(new_class, fname):
+                    setattr(new_class, fname, field.default)
+
     # check name
     if not name:
         for iface in provides:
@@ -363,15 +385,20 @@
     _context.action(
         discriminator = ('z3ext.layout:registerPagelets', new_class),
         callable = registerPagelets,
-        args = (for_, layer, new_class, provides, name, _context.info))
+        args = (for_, layer, new_class, manager, provides, name, _context.info))
 
 
-def registerPagelets(for_, layer, newClass, provides, name, info):
+def registerPagelets(for_, layer, newClass, managers, provides, name, info):
+    if managers:
+        required = [for_, layer] + managers
+    else:
+        required = (for_, layer)
+
     for iface in provides:
         if IPageletType.providedBy(iface):
-            handler('registerAdapter', newClass, (for_, layer), iface, '', info)
+            handler('registerAdapter', newClass, required, iface, '', info)
         else:
-            handler('registerAdapter', newClass, (for_, layer), iface, name, info)
+            handler('registerAdapter', newClass, required, iface, name, info)
 
 
 def _handle_allowed_interface(



More information about the Checkins mailing list