[Checkins] SVN: z3ext.layout/trunk/ api refactoring
Nikolay Kim
fafhrd at datacom.kz
Sun Dec 21 18:05:17 EST 2008
Log message for revision 94231:
api refactoring
Changed:
U z3ext.layout/trunk/CHANGES.txt
U z3ext.layout/trunk/setup.py
U z3ext.layout/trunk/src/z3ext/layout/configure.zcml
U z3ext.layout/trunk/src/z3ext/layout/interfaces.py
U z3ext.layout/trunk/src/z3ext/layout/meta.zcml
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/tales.py
U z3ext.layout/trunk/src/z3ext/layout/zcml.py
-=-
Modified: z3ext.layout/trunk/CHANGES.txt
===================================================================
--- z3ext.layout/trunk/CHANGES.txt 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/CHANGES.txt 2008-12-21 23:05:17 UTC (rev 94231)
@@ -2,12 +2,21 @@
CHANGES
=======
-1.7.4 (2008-12-??)
+2.0.0 (2008-12-22)
------------------
-- Added IPageletManagerType, same as IPageletType but use extra parameters for adopter
+- Added 'type' attribute to 'z3ext:pagelet'
+- Added 'z3ext:pageletType' directive for registering new pagelet types
+- multiple params is allowed for 'for' attribute
+
+- Removed pagelet 'manager' attribute
+
+- 'pagelet' tales expression and 'pagelet' view checks additional context IPageletContext
+ if exists use it as adapter parameter
+
+
1.7.3 (2008-12-18)
------------------
Modified: z3ext.layout/trunk/setup.py
===================================================================
--- z3ext.layout/trunk/setup.py 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/setup.py 2008-12-21 23:05:17 UTC (rev 94231)
@@ -21,7 +21,7 @@
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-version='1.7.4dev'
+version='2.0.0'
setup(name='z3ext.layout',
Modified: z3ext.layout/trunk/src/z3ext/layout/configure.zcml
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/configure.zcml 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/src/z3ext/layout/configure.zcml 2008-12-21 23:05:17 UTC (rev 94231)
@@ -7,6 +7,10 @@
<includeDependencies package="z3ext.layout" />
+ <z3ext:pageletType
+ name="pagelet"
+ interface="z3ext.layout.interfaces.IPageletType" />
+
<!-- adapter provides IPagelet for (context, request) -->
<adapter factory=".pagelet.queryPagelet" />
Modified: z3ext.layout/trunk/src/z3ext/layout/interfaces.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/interfaces.py 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/src/z3ext/layout/interfaces.py 2008-12-21 23:05:17 UTC (rev 94231)
@@ -26,7 +26,7 @@
class IPagelet(IBrowserPage):
""" pagelet """
- managers = interface.Attribute('Additional managers')
+ contexts = interface.Attribute('Additional contexts')
isRedirected = interface.Attribute('is redirected')
@@ -46,13 +46,10 @@
""" pagelet interface type """
-class IPageletManager(interface.Interface):
- """ pagelet manager """
+class IPageletContext(interface.Interface):
+ """ pagelet contexts """
-class IPageletManagerType(IPageletType):
- """ pagelet interface type with view as manager """
-
class ILayout(IBrowserPage):
""" layout """
Modified: z3ext.layout/trunk/src/z3ext/layout/meta.zcml
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/meta.zcml 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/src/z3ext/layout/meta.zcml 2008-12-21 23:05:17 UTC (rev 94231)
@@ -12,6 +12,11 @@
name="pagelet"
schema=".zcml.IPageletDirective"
handler=".zcml.pageletDirective" />
+
+ <meta:directive
+ name="pageletType"
+ schema=".zcml.IPageletTypeDirective"
+ handler=".zcml.pageletTypeDirective" />
</meta:directives>
</configure>
Modified: z3ext.layout/trunk/src/z3ext/layout/pagelet.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/pagelet.py 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/src/z3ext/layout/pagelet.py 2008-12-21 23:05:17 UTC (rev 94231)
@@ -17,16 +17,14 @@
"""
import logging, sys
from zope import interface, component
-from zope.component import queryUtility
-from zope.component import queryMultiAdapter
+from zope.component import queryUtility, queryAdapter, queryMultiAdapter
from zope.publisher.browser import BrowserPage
from zope.publisher.interfaces import NotFound
from zope.publisher.interfaces.browser import IBrowserPublisher
from zope.tales.expressions import SimpleModuleImporter
from zope.app.publisher.browser import queryDefaultViewName
-from z3ext.layout.interfaces import IPagelet, ILayout, IPageletType
-from z3ext.layout.interfaces import IPageletManager, IPageletManagerType
+from interfaces import ILayout, IPagelet, IPageletType, IPageletContext
@interface.implementer(IPagelet)
@@ -59,10 +57,16 @@
template = None
layoutname = u''
- def __init__(self, context, request, *args):
- self.managers = args
+ def __init__(self, context, *args):
+ request = args[-1]
super(BrowserPagelet, self).__init__(context, request)
+ args = args[:-1]
+ self.contexts = args
+
+ for idx in range(len(args)):
+ setattr(self, 'context%s'%idx, args[idx])
+
def update(self):
pass
@@ -70,7 +74,7 @@
if self.template is not None:
return self.template()
else:
- template = queryMultiAdapter((self, self.request), IPagelet, name='')
+ template = queryMultiAdapter((self, self.request), IPagelet)
if template is not None:
template.update()
return template.render()
@@ -114,9 +118,9 @@
raise NotFound(self.context, name, request)
- def __call__(self):
+ def __call__(self, name=''):
try:
- return self['']
+ return self[name]
except KeyError:
pass
@@ -124,9 +128,7 @@
def __getitem__(self, name):
if name:
- iface = queryUtility(IPageletManagerType, name)
- if iface is None:
- iface = queryUtility(IPageletType, name)
+ iface = queryUtility(IPageletType, name)
if iface is None:
try:
@@ -142,12 +144,15 @@
if iface.providedBy(context):
return context.render()
- if IPageletManagerType.providedBy(iface):
- manager = IPageletManager(context, None)
- context = [context, self.request]
- if type(manager) in (list, tuple):
- context.extend(manager)
- view = queryMultiAdapter(context, iface)
+ contexts = queryAdapter(context, IPageletContext, name)
+ if contexts is not None:
+ required = [context]
+ if type(contexts) in (list, tuple):
+ required.extend(contexts)
+ else:
+ required.append(contexts)
+ required.append(self.request)
+ view = queryMultiAdapter(required, iface)
else:
view = queryMultiAdapter((context, self.request), iface)
Modified: z3ext.layout/trunk/src/z3ext/layout/pagelet.txt
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/pagelet.txt 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/src/z3ext/layout/pagelet.txt 2008-12-21 23:05:17 UTC (rev 94231)
@@ -8,7 +8,7 @@
>>> import os, tempfile, sys
>>> from zope import interface, component, schema
>>> from zope.configuration import xmlconfig
- >>> from z3ext.layout.interfaces import IPagelet
+ >>> from z3ext.layout.interfaces import IPagelet, IPageletType, IPageletContext
>>> import z3ext.layout
>>> context = xmlconfig.file('meta.zcml', z3ext.layout)
@@ -24,6 +24,7 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="index.html"
... class="z3ext.layout.TESTS.MyPagelet"
... permission="zope.Public"
@@ -99,9 +100,9 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="new.html"
... class="z3ext.layout.TESTS.NewPagelet"
- ... permission="zope.Public"
... provides="z3ext.layout.TESTS.INewPagelet" />
... </configure>
... """, context)
@@ -133,9 +134,9 @@
>>> xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="new.html"
... class="z3ext.layout.TESTS.NewPagelet"
- ... permission="zope.Public"
... provides="z3ext.layout.TESTS.INewPagelet2" />
... </configure>
... """, context)
@@ -156,15 +157,15 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="new.html"
... class="z3ext.layout.TESTS.NewPagelet"
- ... permission="zope.Public"
... provides="z3ext.layout.TESTS.INewPagelet2" />
... </configure>
... """, context)
>>> pagelet = component.getMultiAdapter(
- ... (object(), TestRequest()), INewPagelet2, name='new.html')
+ ... (object(), TestRequest()), IPagelet, name='new.html')
>>> print pagelet.number
9
@@ -173,16 +174,16 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... 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')
+ ... (object(), TestRequest()), IPagelet, name='new1.html')
>>> print pagelet.number, ':', type(pagelet.number)
10 : <type 'int'>
@@ -191,9 +192,9 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="new1.html"
... class="z3ext.layout.TESTS.NewPagelet"
- ... permission="zope.Public"
... provides="z3ext.layout.TESTS.INewPagelet2"
... number="xxxxx" />
... </configure>
@@ -213,9 +214,9 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="new.html"
... class="z3ext.layout.TESTS.NewPagelet"
- ... permission="zope.Public"
... date="2007-10-10"
... provides="z3ext.layout.TESTS.INewPagelet3" />
... </configure>
@@ -224,15 +225,33 @@
...
ZopeXMLConfigurationError:...ConfigurationError: ("Can't convert value", 'date')
+If pagelet is typed, type schema also checked
+ >>> from zope.component.interface import provideInterface
+ >>> provideInterface('newPagelet3', INewPagelet3, IPageletType)
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+ ... <z3ext:pagelet
+ ... for="*"
+ ... name="new.html"
+ ... class="z3ext.layout.TESTS.NewPagelet"
+ ... date="2007-10-10"
+ ... type="newPagelet3" />
+ ... </configure>
+ ... """, context)
+ Traceback (most recent call last):
+ ...
+ ZopeXMLConfigurationError:...ConfigurationError: ("Can't convert value", 'date')
+
+
We can create pagelet without specific class
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
- ... name="noclass.html"
- ... permission="zope.Public" />
+ ... for="*"
+ ... name="noclass.html" />
... </configure>
... """, context)
@@ -247,15 +266,15 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="unknown.html"
- ... template="unknown.pt"
- ... permission="zope.Public" />
+ ... template="unknown.pt" />
... </configure>
... """, context)
Traceback (most recent call last):
...
- ZopeXMLConfigurationError: File "<string>", line 3.2-6.33
- ConfigurationError: ('No such file', ...unknown.pt')
+ ZopeXMLConfigurationError: File "<string>", line 3.2-6.30
+ ConfigurationError: ('No such file', '...unknown.pt')
>>> temp_dir = tempfile.mkdtemp()
>>> template = os.path.join(temp_dir, 'pagelet.pt')
@@ -264,6 +283,7 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... name="template.html"
... template="%s"
... permission="zope.Public" />
@@ -290,20 +310,18 @@
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
... name="index.html"
- ... for="*"
- ... manager="z3ext.layout.TESTS.IContext2"
- ... permission="zope.Public" />
+ ... for="* z3ext.layout.TESTS.IContext2" />
... </configure>
... """, context)
>>> context2 = Context2()
>>> c2Pagelet = component.queryMultiAdapter(
- ... (object(), TestRequest(), context2), name='index.html')
+ ... (object(), context2, TestRequest()), name='index.html')
>>> c2Pagelet
<z3ext.layout.zcml.PageletClass from None ...>
- >>> c2Pagelet.managers
+ >>> c2Pagelet.contexts
(<z3ext.layout.TESTS.Context2 ...>,)
@@ -370,34 +388,63 @@
u'index.html'
-Pagelet without name
+Typed pagelets
- >>> class IMyPagelet1(interface.Interface):
+ >>> class IMyPagelet2(interface.Interface):
... pass
- >>> class IMyPagelet2(interface.Interface):
+ >>> class IMyPagelet3(interface.Interface):
... pass
+ >>> from z3ext.layout.tests import ITestPagelet
+
+We need register types
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+ ... <z3ext:pageletType name="pagelet"
+ ... interface="z3ext.layout.interfaces.IPagelet" />
+ ... <z3ext:pageletType name="myPagelet1"
+ ... interface="z3ext.layout.tests.ITestPagelet" />
+ ... <z3ext:pageletType name="myPagelet2"
+ ... interface="z3ext.layout.TESTS.IMyPagelet2" />
+ ... <z3ext:pageletType name="myPagelet3"
+ ... interface="z3ext.layout.TESTS.IMyPagelet3" />
+ ... </configure>""", context)
+
>>> template2 = os.path.join(temp_dir, 'pagelet2.pt')
>>> open(template2, 'w').write('''<div>My pagelet2</div>''')
- >>> from z3ext.layout.tests import ITestPagelet
+ >>> template3 = os.path.join(temp_dir, 'pagelet3.pt')
+ >>> open(template3, 'w').write('''<div>My pagelet3</div>''')
+ >>> template4 = os.path.join(temp_dir, 'pagelet4.pt')
+ >>> open(template4, 'w').write('''<div>My pagelet - default</div>''')
+
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... template="%s"
- ... provides="z3ext.layout.tests.ITestPagelet"
+ ... type="myPagelet1"
... permission="zope.Public" />
... <z3ext:pagelet
+ ... for="*"
... template="%s"
- ... provides="z3ext.layout.TESTS.IMyPagelet2"
+ ... type="myPagelet2"
... permission="zope.Public" />
... <z3ext:pagelet
+ ... for="*"
... template="%s"
+ ... type="myPagelet3"
... permission="zope.Public" />
+ ... <z3ext:pagelet
+ ... for="*"
+ ... template="%s"
+ ... type="pagelet"
+ ... permission="zope.Public" />
... </configure>
- ... """%(template, template2, template2), context)
+ ... """%(template, template2, template3, template4), context)
>>> pagelet = component.queryMultiAdapter(
... (object(), TestRequest()), ITestPagelet)
@@ -415,7 +462,7 @@
<div>My pagelet2</div>
-Access nameless pagelet from view
+Access typed pagelet from view
>>> pagelet = component.getMultiAdapter((object(), request), name='pagelet')
@@ -431,10 +478,10 @@
by default IPagelet
>>> print pagelet()
- <div>My pagelet2</div>
+ <div>My pagelet - default</div>
>>> print pagelet.publishTraverse(request, '')
- <div>My pagelet2</div>
+ <div>My pagelet - default</div>
>>> print pagelet.publishTraverse(
... request, 'z3ext.layout.tests.ITestPagelet')
@@ -450,6 +497,65 @@
>>> print pagelet.publishTraverse(request, 'testPageletType')
<div>My pagelet</div>
+We can provide additional context for pagelet
+
+ >>> def getContexts(content):
+ ... return Content()
+
+ >>> component.provideAdapter(
+ ... getContexts, (IContent,), IPageletContext, name='myPagelet4')
+
+ >>> class IMyPagelet4(interface.Interface):
+ ... pass
+
+ >>> provideInterface('myPagelet4', IMyPagelet4, IPageletType)
+
+ >>> template4 = os.path.join(temp_dir, 'pagelet4.pt')
+ >>> open(template4, 'w').write('''<div>My pagelet4</div>''')
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+ ... <z3ext:pagelet
+ ... for="* z3ext.layout.TESTS.IContent"
+ ... template="%s"
+ ... type="myPagelet4"
+ ... permission="zope.Public" />
+ ... </configure>"""%template4, context)
+
+ >>> pagelet = component.getMultiAdapter((Content(), request), name='pagelet')
+ >>> print pagelet.publishTraverse(request, 'myPagelet4')
+ <div>My pagelet4</div>
+
+Or multiple contexts
+
+ >>> def getContexts2(content):
+ ... return (Content(), Content())
+
+ >>> component.provideAdapter(
+ ... getContexts2, (IContent,), IPageletContext, name='myPagelet5')
+
+ >>> class IMyPagelet5(interface.Interface):
+ ... pass
+
+ >>> provideInterface('myPagelet5', IMyPagelet5, IPageletType)
+
+ >>> template5 = os.path.join(temp_dir, 'pagelet5.pt')
+ >>> open(template5, 'w').write('''<div>My pagelet5</div>''')
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+ ... <z3ext:pagelet
+ ... for="* z3ext.layout.TESTS.IContent z3ext.layout.TESTS.IContent"
+ ... template="%s"
+ ... type="myPagelet5"
+ ... permission="zope.Public" />
+ ... </configure>"""%template5, context)
+
+ >>> pagelet = component.getMultiAdapter((Content(), request), name='pagelet')
+ >>> print pagelet.publishTraverse(request, 'myPagelet5')
+ <div>My pagelet5</div>
+
+
We can register nameless pagelet only if provided interface is not
inherited from IBrowserPublisher, because we can override
IBrowserPublisher for content.
@@ -460,6 +566,7 @@
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
... <z3ext:pagelet
+ ... for="*"
... template="%s"
... provides="z3ext.layout.TESTS.IWrongPageletInterface"
... permission="zope.Public" />
@@ -483,8 +590,7 @@
... """%template, context)
-If we register named pagelet and provided interface provides IPageletType,
-also nameless adapter registered
+We can register typed pagelet with name
>>> context = xmlconfig.string("""
... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
@@ -492,19 +598,45 @@
... name="test.html"
... for="z3ext.layout.TESTS.IContent"
... template="%s"
- ... provides="z3ext.layout.TESTS.ITestPagelet"
+ ... type="myPagelet1"
... permission="zope.Public" />
... </configure>
... """%template, context)
>>> content = Content()
- >>> pagelet1 = component.getMultiAdapter((content, request), name='test.html')
- >>> pagelet2 = component.getMultiAdapter((content, request), ITestPagelet)
+ >>> pagelet = component.getMultiAdapter(
+ ... (content, request), ITestPagelet, name='test.html')
- >>> pagelet1.__class__ is pagelet2.__class__
- True
+Pagelets with errors
+ >>> class PageletWithError(object):
+ ... def render(self):
+ ... raise Exception('Error')
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+ ... <z3ext:pagelet
+ ... for="z3ext.layout.TESTS.IContent"
+ ... class="z3ext.layout.TESTS.PageletWithError"
+ ... type="myPagelet2" />
+ ... </configure>
+ ... """, context)
+
+ >>> pagelet = component.getMultiAdapter((content, request), name='pagelet')
+ >>> pagelet.publishTraverse(request, 'myPagelet2')
+ Traceback (most recent call last):
+ ...
+ NotFound: ...
+
+ >>> pagelet('myPagelet2')
+ u''
+
+ >>> pagelet['myPagelet2']
+ Traceback (most recent call last):
+ ...
+ KeyError: 'myPagelet2'
+
+
The TALES `pagelet` expression
==============================
@@ -625,7 +757,7 @@
<body>
<h1>My Web Page</h1>
<div class="left-column">
- <div>My pagelet2</div>
+ <div>My pagelet - default</div>
</div>
<div class="main">
Content here
@@ -662,10 +794,131 @@
<body>
<h1>My Web Page</h1>
<div class="left-column">
- <BLANKLINE>
</div>
<div class="main">
Content here
</div>
</body>
</html>
+
+
+Pagelets with errors
+
+ >>> class PageletWithError(object):
+ ... def render(self):
+ ... raise Exception('Error')
+
+ >>> context = xmlconfig.string("""
+ ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext">
+ ... <z3ext:pagelet
+ ... for="z3ext.layout.TESTS.IContent"
+ ... class="z3ext.layout.TESTS.PageletWithError"
+ ... type="myPagelet2" />
+ ... </configure>
+ ... """, context)
+
+ >>> open(templateFileName, 'w').write('''
+ ... <html>
+ ... <body>
+ ... <h1>My Web Page</h1>
+ ... <div class="left-column">
+ ... <tal:block replace="structure pagelet:myPagelet2" />
+ ... </div>
+ ... <div class="main">
+ ... Content here
+ ... </div>
+ ... </body>
+ ... </html>
+ ... ''')
+
+ >>> FrontPage = SimpleViewClass(templateFileName, name='error.html')
+ >>> component.provideAdapter(
+ ... FrontPage,
+ ... (IContent, interface.Interface), interface.Interface,
+ ... name='error.html')
+
+ >>> view = component.getMultiAdapter((Content(), request), name='error.html')
+ >>> print view()
+ <html>
+ <body>
+ <h1>My Web Page</h1>
+ <div class="left-column">
+ </div>
+ <div class="main">
+ Content here
+ </div>
+ </body>
+ </html>
+
+Pagelet with extra context
+
+ >>> open(templateFileName, 'w').write('''
+ ... <html>
+ ... <body>
+ ... <h1>My Web Page</h1>
+ ... <div class="left-column">
+ ... <tal:block replace="structure pagelet:myPagelet4" />
+ ... </div>
+ ... <div class="main">
+ ... Content here
+ ... </div>
+ ... </body>
+ ... </html>
+ ... ''')
+
+ >>> FrontPage = SimpleViewClass(templateFileName, name='extra4.html')
+ >>> component.provideAdapter(
+ ... FrontPage,
+ ... (IContent, interface.Interface), interface.Interface,
+ ... name='extra4.html')
+
+ >>> view = component.getMultiAdapter((Content(), request), name='extra4.html')
+ >>> print view()
+ <html>
+ <body>
+ <h1>My Web Page</h1>
+ <div class="left-column">
+ <div>My pagelet4</div>
+ </div>
+ <div class="main">
+ Content here
+ </div>
+ </body>
+ </html>
+
+
+Pagelet with extra context
+
+ >>> open(templateFileName, 'w').write('''
+ ... <html>
+ ... <body>
+ ... <h1>My Web Page</h1>
+ ... <div class="left-column">
+ ... <tal:block replace="structure pagelet:myPagelet5" />
+ ... </div>
+ ... <div class="main">
+ ... Content here
+ ... </div>
+ ... </body>
+ ... </html>
+ ... ''')
+
+ >>> FrontPage = SimpleViewClass(templateFileName, name='extra5.html')
+ >>> component.provideAdapter(
+ ... FrontPage,
+ ... (IContent, interface.Interface), interface.Interface,
+ ... name='extra5.html')
+
+ >>> view = component.getMultiAdapter((Content(), request), name='extra5.html')
+ >>> print view()
+ <html>
+ <body>
+ <h1>My Web Page</h1>
+ <div class="left-column">
+ <div>My pagelet5</div>
+ </div>
+ <div class="main">
+ Content here
+ </div>
+ </body>
+ </html>
Modified: z3ext.layout/trunk/src/z3ext/layout/tales.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/tales.py 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/src/z3ext/layout/tales.py 2008-12-21 23:05:17 UTC (rev 94231)
@@ -16,12 +16,10 @@
$Id: tales.py 2720 2008-08-25 11:15:10Z fafhrd91 $
"""
import logging, sys
-from zope.component import queryUtility
-from zope.component import queryMultiAdapter
from zope.tales.expressions import StringExpr
+from zope.component import queryUtility, queryAdapter, queryMultiAdapter
-from interfaces import IPagelet, IPageletType
-from interfaces import IPageletManager, IPageletManagerType
+from interfaces import IPagelet, IPageletType, IPageletContext
class TALESPageletExpression(StringExpr):
@@ -35,9 +33,7 @@
# lookup pagelet
if name:
- iface = queryUtility(IPageletManagerType, name)
- if iface is None:
- iface = queryUtility(IPageletType, name)
+ iface = queryUtility(IPageletType, name)
if iface is None:
try:
@@ -53,12 +49,15 @@
if iface.providedBy(context):
return context.render()
- if IPageletManagerType.providedBy(iface):
- manager = IPageletManager(context, None)
- context = [context, request]
- if type(manager) in (list, tuple):
- context.extend(manager)
- view = queryMultiAdapter(context, iface)
+ contexts = queryAdapter(context, IPageletContext, name)
+ if contexts is not None:
+ required = [context]
+ if type(contexts) in (list, tuple):
+ required.extend(contexts)
+ else:
+ required.append(contexts)
+ required.append(request)
+ view = queryMultiAdapter(required, iface)
else:
view = queryMultiAdapter((context, request), iface)
Modified: z3ext.layout/trunk/src/z3ext/layout/zcml.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/zcml.py 2008-12-21 20:08:09 UTC (rev 94230)
+++ z3ext.layout/trunk/src/z3ext/layout/zcml.py 2008-12-21 23:05:17 UTC (rev 94231)
@@ -18,6 +18,7 @@
import os.path
from zope import schema, interface, event
from zope.schema.interfaces import IFromUnicode
+from zope.component import getUtility, queryUtility
from zope.component.interface import provideInterface
from zope.component.zcml import handler, adapter, utility
from zope.security.checker import defineChecker, Checker, CheckerPublic
@@ -27,6 +28,7 @@
from zope.publisher.interfaces.browser import IDefaultBrowserLayer
from zope.app.component.metadirectives import IBasicViewInformation
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.security.zcml import Permission
from interfaces import IPagelet, IPageletType
from interfaces import ILayout, ILayoutCreatedEvent
@@ -35,6 +37,20 @@
from layout import Layout, LayoutTemplateFile
+class IPageletTypeDirective(interface.Interface):
+ """A directive to register a new pagelet type."""
+
+ name = schema.TextLine(
+ title = u'Name',
+ description = u'Pagelet type name',
+ required = True)
+
+ interface = GlobalInterface(
+ title = u'Interface',
+ description = u'Interface that is used as pagelet type.',
+ required = True)
+
+
class IPageletDirective(IBasicViewInformation):
"""A directive to register a new pagelet.
@@ -42,29 +58,27 @@
that are set as attributes on the pagelet after creation.
"""
- for_ = GlobalObject(
+ for_ = Tokens(
title = u"Context",
description = u"The content interface or class this pagelet is for.",
- required = False)
+ value_type = GlobalObject(missing_value=object()),
+ required = True)
name = schema.TextLine(
title = u"The name of the pagelet.",
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, ...)""",
+ type = Tokens(
+ title = u"Pagelet type.",
required = False,
- value_type = GlobalObject())
+ value_type = schema.TextLine())
provides = Tokens(
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.""",
+ description = u"""A pagelet can provide an interface. This would be used for views that support other views.""",
required = False,
- value_type = GlobalInterface(),
- default = [IPagelet,])
+ value_type = GlobalInterface())
class_ = GlobalObject(
title=u"Class",
@@ -84,6 +98,13 @@
default=u'',
required=False)
+ layer = GlobalObject(
+ title = u'Layer',
+ description = u'The layer for which the template should be available',
+ required = False,
+ default = IDefaultBrowserLayer)
+
+
# Arbitrary keys and values are allowed to be passed to the pagelet.
IPageletDirective.setTaggedValue('keyword_arguments', True)
@@ -165,10 +186,14 @@
ILayoutDirective.setTaggedValue('keyword_arguments', True)
+def pageletTypeDirective(_context, name, interface):
+ provideInterface(name, interface, IPageletType)
+
+
def layoutDirective(
_context, uid='', template='', for_=None, view=None, name = u'',
layer = IDefaultBrowserLayer, provides = ILayout,
- contentType='text/html', class_ = None, layout = '',
+ contentType='text/html', class_ = None, layout = '',
title='', description='', **kwargs):
if not layout:
@@ -280,13 +305,18 @@
uid, name, view, context, layer, layoutclass, keywords))
+Type = type
+
# pagelet directive
-def pageletDirective(
- _context, permission, for_=interface.Interface, name=u'', manager=(),
- class_=None, layer=IDefaultBrowserLayer, provides=[IPagelet,],
- allowed_interface=[], allowed_attributes=[],
- template=u'', layout=u'', **kwargs):
+def pageletDirective(_context, for_, name=u'', type=(),
+ class_=None, layer=IDefaultBrowserLayer, provides=[],
+ allowed_interface=[], allowed_attributes=[],
+ template=u'', layout=u'', permission='zope.Public', **kwargs):
+ provides = list(provides)
+ if IPagelet not in provides:
+ provides.append(IPagelet)
+
# Security map dictionary
required = {}
@@ -316,8 +346,14 @@
else:
bases = (BrowserPagelet,)
- new_class = type('PageletClass from %s'%class_, bases, cdict)
+ new_class = Type('PageletClass from %s'%class_, bases, cdict)
+ # extend provides with type
+ for tp in type:
+ iface = queryUtility(IPageletType, tp)
+ if iface is not None:
+ provides.append(iface)
+
# convert kwargs
for iface in provides:
for fname, field in schema.getFields(iface).items():
@@ -328,6 +364,7 @@
setattr(new_class, fname, field.fromUnicode(kwargs[fname]))
else:
if field.required and not hasattr(new_class, fname):
+ print provides, new_class, fname
raise ConfigurationError("Required field is missing", fname)
if not hasattr(new_class, fname):
@@ -357,9 +394,6 @@
# prepare allowed interfaces and attributes
allowed_interface.extend(provides)
- if IPagelet not in provides:
- allowed_interface.append(IPagelet)
-
allowed_attributes.extend(kwargs.keys())
allowed_attributes.extend(('__call__', 'browserDefault',
'update', 'render', 'publishTraverse'))
@@ -382,28 +416,39 @@
defineChecker(new_class, Checker(required))
# register pagelet
- _context.action(
- discriminator = ('z3ext.layout:registerPagelets', new_class),
- callable = registerPagelets,
- args = (for_, layer, new_class, manager, provides, name, _context.info))
+ for_.append(layer)
+ if type:
+ _context.action(
+ discriminator = ('z3ext.layout:registerPagelets', new_class),
+ callable = registerTypedPagelets,
+ args = (for_, new_class, type, name, _context.info))
+ else:
+ _context.action(
+ discriminator = ('z3ext.layout:registerPagelets', tuple(for_), layer, name),
+ callable = registerPagelets,
+ args = (for_, new_class, provides, name, _context.info))
-def registerPagelets(for_, layer, newClass, managers, provides, name, info):
- if managers:
- required = [for_, layer] + managers
- else:
- required = (for_, layer)
+def registerPagelets(required, newClass, provides, name, info):
+ handler('registerAdapter', newClass, required, IPagelet, name, info)
for iface in provides:
+ if iface is IPagelet:
+ continue
+
if IPageletType.providedBy(iface):
handler('registerAdapter', newClass, required, iface, '', info)
- else:
- handler('registerAdapter', newClass, required, iface, name, info)
+def registerTypedPagelets(required, newClass, type, name, info):
+ for tp in type:
+ iface = getUtility(IPageletType, tp)
+ handler('registerAdapter', newClass, required, iface, name, info)
+
+
def _handle_allowed_interface(
_context, allowed_interface, permission, required):
- # Allow access for all names defined by named interfaces
+ # Allow access for all names defined by named interfaces
if allowed_interface:
for i in allowed_interface:
_context.action(
@@ -423,8 +468,9 @@
required[name] = permission
def _handle_for(_context, for_):
- if for_ is not None:
- _context.action(
- discriminator = None,
- callable = provideInterface,
- args = ('', for_))
+ for iface in for_:
+ if iface is not None:
+ _context.action(
+ discriminator = None,
+ callable = provideInterface,
+ args = ('', iface))
More information about the Checkins
mailing list