[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