[Checkins] SVN: z3c.layout/trunk/s Added plone.memoize to cache
content providers for the duration of the request.
Malthe Borch
mborch at gmail.com
Sun Aug 3 20:57:46 EDT 2008
Log message for revision 89335:
Added plone.memoize to cache content providers for the duration of the request.
Changed:
U z3c.layout/trunk/setup.py
U z3c.layout/trunk/src/z3c/layout/README.txt
U z3c.layout/trunk/src/z3c/layout/browser/insertion.py
U z3c.layout/trunk/src/z3c/layout/browser/layout.py
-=-
Modified: z3c.layout/trunk/setup.py
===================================================================
--- z3c.layout/trunk/setup.py 2008-08-04 00:57:11 UTC (rev 89334)
+++ z3c.layout/trunk/setup.py 2008-08-04 00:57:46 UTC (rev 89335)
@@ -51,6 +51,7 @@
'zope.app.publisher',
'zope.contentprovider',
'zope.viewlet',
+ 'plone.memoize',
'lxml>=2.0',
],
include_package_data = True,
Modified: z3c.layout/trunk/src/z3c/layout/README.txt
===================================================================
--- z3c.layout/trunk/src/z3c/layout/README.txt 2008-08-04 00:57:11 UTC (rev 89334)
+++ z3c.layout/trunk/src/z3c/layout/README.txt 2008-08-04 00:57:46 UTC (rev 89335)
@@ -112,6 +112,12 @@
>>> context = MockContext()
>>> request = TestRequest()
+We need to have the request be annotatable.
+
+ >>> from zope.annotation.attribute import AttributeAnnotations
+ >>> component.provideAdapter(
+ ... AttributeAnnotations, (TestRequest,))
+
The view expects the context to adapt to ``ILayout``.
>>> from z3c.layout.interfaces import ILayout
@@ -123,9 +129,11 @@
Verify that the layout view is able to get to these providers.
- >>> tuple(view._get_content_providers())
- ((<Region 'title' .//title (replace) 'title'>, <MockContentProvider 'title'>),
- (<Region 'content' .//div (replace) None>, <MockContentProvider 'content'>))
+ >>> view.mapping
+ {'content':
+ (<Region 'content' .//div (replace) None>, <MockContentProvider 'content'>),
+ 'title':
+ (<Region 'title' .//title (replace) 'title'>, <MockContentProvider 'title'>)}
Now for the actual output.
Modified: z3c.layout/trunk/src/z3c/layout/browser/insertion.py
===================================================================
--- z3c.layout/trunk/src/z3c/layout/browser/insertion.py 2008-08-04 00:57:11 UTC (rev 89334)
+++ z3c.layout/trunk/src/z3c/layout/browser/insertion.py 2008-08-04 00:57:46 UTC (rev 89335)
@@ -1,3 +1,15 @@
+def insert(tree, region, provided):
+ # look up insertion method
+ try:
+ insert = _map[region.mode]
+ except KeyError:
+ raise ValueError("Invalid mode: %s" % repr(region.mode))
+
+ # insert provided content into nodes
+ nodes = tree.xpath(region.xpath)
+ for node in nodes:
+ insert(node, provided)
+
def replace(node, provided):
"""Replace node with contents.
@@ -90,3 +102,10 @@
if provided.text:
node.tail = node.tail or "" + provided.text
+
+_map = dict(
+ replace=replace,
+ prepend=prepend,
+ append=append,
+ before=before,
+ after=after)
Modified: z3c.layout/trunk/src/z3c/layout/browser/layout.py
===================================================================
--- z3c.layout/trunk/src/z3c/layout/browser/layout.py 2008-08-04 00:57:11 UTC (rev 89334)
+++ z3c.layout/trunk/src/z3c/layout/browser/layout.py 2008-08-04 00:57:46 UTC (rev 89335)
@@ -9,28 +9,29 @@
from z3c.layout import interfaces
+from plone.memoize.view import memoize
+
import insertion
class LayoutView(BrowserView):
def __init__(self, context, request):
BrowserView.__init__(self, context, request)
- self.layout = interfaces.ILayout(context)
-
- def __call__(self):
- tree = self.layout.parse()
-
- # lookup content provider components
- content_providers = self._get_content_providers()
- # update content providers
- for region, provider in content_providers:
- provider.update()
+ self._layout = interfaces.ILayout(context)
+ self.mapping = self._get_region_provider_mapping()
+ def __call__(self):
+ # parse tree
+ tree = self._layout.parse()
+
# render and insert content providers
- for region, provider in content_providers:
+ for region, provider in self.mapping.values():
self._insert_provider(tree, region, provider)
return lxml.html.tostring(tree, pretty_print=True).rstrip('\n')
+
+ def get_context(self, region):
+ return region
def _insert_provider(self, tree, region, provider):
# render and wrap provided content
@@ -38,38 +39,36 @@
provided = lxml.html.fromstring(
u"<div>%s</div>" % html)
- # look up insertion method
- try:
- insert = getattr(insertion, region.mode)
- except AttributeError:
- raise ValueError("Invalid mode: %s" % repr(region.mode))
+ insertion.insert(tree, region, provided)
- # insert provided content into nodes
- nodes = tree.xpath(region.xpath)
- for node in nodes:
- insert(node, provided)
+ def _get_provider(self, region):
+ """Lookup content provider for region."""
- def _get_content_providers(self):
- """Lookup content providers for regions."""
-
- results = []
-
- for region in self.layout.regions:
- name = region.provider
+ name = region.provider
+ context = self.get_context(region)
- if name is not None:
- provider = component.queryMultiAdapter(
- (region, self.request, self), IContentProvider, name=name)
- else:
- provider = component.queryMultiAdapter(
- (region, self.request, self), IContentProvider)
+ if name is not None:
+ provider = component.queryMultiAdapter(
+ (context, self.request, self), IContentProvider, name=name)
+ else:
+ provider = component.queryMultiAdapter(
+ (context, self.request, self), IContentProvider)
- if provider is None:
- raise ValueError(
- "Unable to determine content "
- "provider for region '%s'." % region.name)
+ return provider
+
+ @memoize
+ def _get_region_provider_mapping(self):
+ mapping = {}
- provider.__name__ = region.name
- results.append((region, provider))
+ for region in self._layout.regions:
+ provider = self._get_provider(region)
- return results
+ if provider is not None:
+ provider.__name__ = region.name
+ mapping[region.name] = (region, provider)
+
+ # update content providers
+ for region, provider in mapping.values():
+ provider.update()
+
+ return mapping
More information about the Checkins
mailing list