[Checkins] SVN: z3c.jbot/trunk/z3c/jbot/ Layer specialization is
now observed such that template overrides are looked up in
order of specialization.
Malthe Borch
mborch at gmail.com
Tue Jul 15 12:40:41 EDT 2008
Log message for revision 88383:
Layer specialization is now observed such that template overrides are looked up in order of specialization.
Changed:
U z3c.jbot/trunk/z3c/jbot/Five.txt
U z3c.jbot/trunk/z3c/jbot/README.txt
U z3c.jbot/trunk/z3c/jbot/__init__.py
U z3c.jbot/trunk/z3c/jbot/manager.py
U z3c.jbot/trunk/z3c/jbot/metaconfigure.py
U z3c.jbot/trunk/z3c/jbot/utility.py
-=-
Modified: z3c.jbot/trunk/z3c/jbot/Five.txt
===================================================================
--- z3c.jbot/trunk/z3c/jbot/Five.txt 2008-07-15 14:17:55 UTC (rev 88382)
+++ z3c.jbot/trunk/z3c/jbot/Five.txt 2008-07-15 16:40:39 UTC (rev 88383)
@@ -49,7 +49,8 @@
>>> from zope.publisher.interfaces.browser import IHTTPRequest
>>> factory = z3c.jbot.manager.TemplateManagerFactory()
>>> component.provideAdapter(
- ... factory, (IHTTPRequest,), z3c.jbot.interfaces.ITemplateManager)
+ ... factory, (IHTTPRequest,),
+ ... z3c.jbot.interfaces.ITemplateManager, name='http')
>>> manager = factory.manager
>>> manager.registerDirectory(directory)
@@ -74,10 +75,11 @@
>>> import z3c.jbot.utility
>>> z3c.jbot.utility.getRequest()
<zope.publisher.browser.TestRequest ...>
-
- >>> z3c.jbot.utility.getManager() is manager
- True
+ >>> managers = tuple(z3c.jbot.utility.getManagers())
+ >>> len(managers)
+ 2
+
Verify that template attributes are set per request layer.
>>> view.template._v_last_read is not False
Modified: z3c.jbot/trunk/z3c/jbot/README.txt
===================================================================
--- z3c.jbot/trunk/z3c/jbot/README.txt 2008-07-15 14:17:55 UTC (rev 88382)
+++ z3c.jbot/trunk/z3c/jbot/README.txt 2008-07-15 16:40:39 UTC (rev 88383)
@@ -37,7 +37,8 @@
>>> import z3c.jbot.interfaces
>>> factory = z3c.jbot.manager.TemplateManagerFactory()
>>> component.provideAdapter(
- ... factory, (interface.Interface,), z3c.jbot.interfaces.ITemplateManager)
+ ... factory, (interface.Interface,),
+ ... z3c.jbot.interfaces.ITemplateManager)
Register overrides directory.
@@ -79,7 +80,8 @@
>>> from zope.publisher.interfaces.browser import IHTTPRequest
>>> factory = z3c.jbot.manager.TemplateManagerFactory()
>>> component.provideAdapter(
- ... factory, (IHTTPRequest,), z3c.jbot.interfaces.ITemplateManager)
+ ... factory, (IHTTPRequest,),
+ ... z3c.jbot.interfaces.ITemplateManager, name='http')
Register overrides directory.
@@ -122,21 +124,22 @@
Let's verify that we only cook once per template source.
>>> import z3c.jbot.utility
- >>> z3c.jbot.utility.getManager().registerTemplate(template)
+ >>> output = template()
>>> template._v_last_read and template._v_cooked
1
>>> interface.alsoProvides(request, IHTTPRequest)
- >>> z3c.jbot.utility.getManager().registerTemplate(template)
+ >>> output = template()
>>> template._v_last_read and template._v_cooked
1
>>> template()
u'This template will override the example template.\n'
- >>> z3c.jbot.utility.getManager().unregisterDirectory("%s/templates" % directory)
+ >>> for manager in z3c.jbot.utility.getManagers():
+ ... manager.unregisterDirectory("%s/templates" % directory)
+
>>> interface.noLongerProvides(request, IHTTPRequest)
- >>> z3c.jbot.utility.getManager().unregisterDirectory("%s/templates" % directory)
Configuring template override directories in ZCML
-------------------------------------------------
@@ -161,8 +164,21 @@
>>> template()
u'This template will override the example template.\n'
- >>> z3c.jbot.utility.getManager().unregisterDirectory("%s/templates" % directory)
+Providing the HTTP-request layer does not change this.
+ >>> interface.alsoProvides(request, IHTTPRequest)
+
+ >>> template()
+ u'This template will override the example template.\n'
+
+Unregister overrides.
+
+ >>> manager = tuple(z3c.jbot.utility.getManagers())[0]
+ >>> manager.unregisterDirectory("%s/templates" % directory)
+
+ >>> template()
+ u'This is an example page template.\n'
+
Let's register overrides for the HTTP-request layer.
>>> xmlconfig.xmlconfig(StringIO("""
@@ -173,11 +189,8 @@
... </configure>
... """ % directory))
- >>> template()
- u'This is an example page template.\n'
+If we now provide the HTTP-request layer, the override becomes active.
-If we now provide the HTTP-request layer, the override becomes active.
-
- >>> interface.alsoProvides(request, IHTTPRequest)
>>> template()
u'This template will override the example template.\n'
+
Modified: z3c.jbot/trunk/z3c/jbot/__init__.py
===================================================================
--- z3c.jbot/trunk/z3c/jbot/__init__.py 2008-07-15 14:17:55 UTC (rev 88382)
+++ z3c.jbot/trunk/z3c/jbot/__init__.py 2008-07-15 16:40:39 UTC (rev 88383)
@@ -1,13 +1,17 @@
from zope.pagetemplate.pagetemplatefile import PageTemplateFile
-import manager
import utility
+import logging
+logger = logging.getLogger('jbot')
+
PT_CLASSES = [PageTemplateFile]
-if utility.ZOPE_2:
+try:
import Products.PageTemplates.PageTemplateFile
PT_CLASSES.append(Products.PageTemplates.PageTemplateFile.PageTemplateFile)
+except:
+ pass
class LayerProperty(property):
"""Layer-specific property class.
@@ -54,18 +58,23 @@
# registration hook to template manager
def jbot(func):
def patch(self, *args, **kwargs):
- manager = utility.getManager()
- if manager is not None:
- manager.registerTemplate(self)
-
+ for manager in utility.getManagers():
+ # register template; this call returns ``True`` if
+ # template was invalidated
+ if manager.registerTemplate(self):
+ break
+
return func(self, *args, **kwargs)
return patch
+logger.info("Patching page template classes...")
+
+# patch ``_cook_check``-method to insert jbot-logic
for pt_class in PT_CLASSES:
- # patch ``_cook_check``-method to insert jbot-logic
pt_class._cook_check = jbot(pt_class._cook_check)
- # munge per-layer attribute descriptors on class
+# munge per-layer attribute descriptors on class
+for pt_class in PT_CLASSES:
for name in ('_v_macros', '_v_program', '_v_cooked', '_v_errors',
'_v_last_read', '_v_warning', '_text_',
'filename', 'content_type', 'is_html'):
Modified: z3c.jbot/trunk/z3c/jbot/manager.py
===================================================================
--- z3c.jbot/trunk/z3c/jbot/manager.py 2008-07-15 14:17:55 UTC (rev 88382)
+++ z3c.jbot/trunk/z3c/jbot/manager.py 2008-07-15 16:40:39 UTC (rev 88383)
@@ -1,8 +1,9 @@
from zope import interface
+import os
import sys
-import os.path
+import utility
import interfaces
IGNORE = object()
@@ -70,8 +71,9 @@
del self.paths[filename]
for template in templates:
- template._v_last_read = False
-
+ self.registerTemplate(template)
+ del self.templates[template]
+
def registerTemplate(self, template):
# only register templates that have a filename attribute
if not hasattr(template, 'filename'):
@@ -116,3 +118,5 @@
# force cook
template._v_last_read = False
+
+ return True
Modified: z3c.jbot/trunk/z3c/jbot/metaconfigure.py
===================================================================
--- z3c.jbot/trunk/z3c/jbot/metaconfigure.py 2008-07-15 14:17:55 UTC (rev 88382)
+++ z3c.jbot/trunk/z3c/jbot/metaconfigure.py 2008-07-15 16:40:39 UTC (rev 88383)
@@ -8,14 +8,26 @@
gsm = component.getGlobalSiteManager()
# check if a template manager already exists
- factory = gsm.adapters.lookup((layer,), interfaces.ITemplateManager)
+ factories = set(factory for name, factory in gsm.adapters.lookupAll(
+ (layer,), interfaces.ITemplateManager))
- if factory is None:
+ # if factory is available on the interface bases of the layer we
+ # discard it and register a new manager specialized to the layer
+ if layer is interface.Interface:
+ base_factories = set()
+ else:
+ base_factories = set(factory for name, factory in gsm.adapters.lookupAll(
+ (interface.implementedBy(layer.__bases__),), interfaces.ITemplateManager))
+
+ try:
+ factory = factories.difference(base_factories).pop()
+ except KeyError:
factory = manager.TemplateManagerFactory()
- component.provideAdapter(factory, (layer,), interfaces.ITemplateManager)
+ component.provideAdapter(
+ factory, (layer,), interfaces.ITemplateManager, name=directory)
- factory.manager.registerDirectory(directory)
-
+ factory(layer).registerDirectory(directory)
+
def templateOverridesDirective(_context, directory, layer=interface.Interface):
_context.action(
discriminator = ('override', directory, layer),
Modified: z3c.jbot/trunk/z3c/jbot/utility.py
===================================================================
--- z3c.jbot/trunk/z3c/jbot/utility.py 2008-07-15 14:17:55 UTC (rev 88382)
+++ z3c.jbot/trunk/z3c/jbot/utility.py 2008-07-15 16:40:39 UTC (rev 88383)
@@ -10,26 +10,27 @@
import interfaces
try:
- import Products.PageTemplates
+ import Acquisition
ZOPE_2 = True
-except ImportError:
+except:
ZOPE_2 = False
def getRequest():
- try:
- i = zope.security.management.getInteraction()
- for p in i.participations:
- if IRequest.providedBy(p):
- return p
- except zope.security.interfaces.NoInteraction:
- pass
-
if ZOPE_2:
# get request by acquisition
site = getSite()
if site is not None:
return site.REQUEST
-
+
+ try:
+ i = zope.security.management.getInteraction()
+ except zope.security.interfaces.NoInteraction:
+ return
+
+ for p in i.participations:
+ if IRequest.providedBy(p):
+ return p
+
def getLayer():
request = getRequest()
@@ -38,10 +39,9 @@
return interface.Interface
-def getManager():
+def getManagers():
layer = getLayer()
gsm = component.getGlobalSiteManager()
- factory = gsm.adapters.lookup((layer,), interfaces.ITemplateManager)
- if factory is not None:
- return factory.manager
+ for name, factory in gsm.adapters.lookupAll((layer,), interfaces.ITemplateManager):
+ yield factory(layer)
More information about the Checkins
mailing list