provide caching for layout renderers (i.e. macros used as layout renderers)
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@3634 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
0341411d22
commit
4e1e2370a2
4 changed files with 75 additions and 3 deletions
|
@ -34,13 +34,27 @@ class RendererFactory(object):
|
||||||
return self.template.macros.get(key, default)
|
return self.template.macros.get(key, default)
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return self.template.macros[key]
|
#return self.template.macros[key]
|
||||||
|
return Renderer(key, self)
|
||||||
|
|
||||||
def __getattr__(self, key):
|
def __getattr__(self, key):
|
||||||
""" Convenience method for retrieving callable renderer for layout.
|
""" Convenience method.
|
||||||
"""
|
"""
|
||||||
return lambda key=key: self[key]
|
#return lambda key=key: self[key]
|
||||||
|
return self[key]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return ('<RendererFactory, template=%r, macros=%r>' %
|
return ('<RendererFactory, template=%r, macros=%r>' %
|
||||||
(self.template, self.template.macros.keys()))
|
(self.template, self.template.macros.keys()))
|
||||||
|
|
||||||
|
|
||||||
|
class Renderer(object):
|
||||||
|
|
||||||
|
def __init__(self, name, factory):
|
||||||
|
self.name = name
|
||||||
|
self.factory = factory
|
||||||
|
self.template = factory.template
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
return self.template.macros[self.name]
|
||||||
|
|
||||||
|
|
6
composer/layout/browser/renderer.pt
Normal file
6
composer/layout/browser/renderer.pt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<!-- $Id$ -->
|
||||||
|
|
||||||
|
<tal:renderer define="view nocall:options/view;
|
||||||
|
macro options/macro">
|
||||||
|
<metal:content use-macro="macro" />
|
||||||
|
</tal:renderer>
|
|
@ -31,11 +31,16 @@ from zope.app.security.interfaces import IUnauthenticatedPrincipal
|
||||||
from cybertools.composer.layout.base import Layout
|
from cybertools.composer.layout.base import Layout
|
||||||
from cybertools.composer.layout.interfaces import ILayoutManager
|
from cybertools.composer.layout.interfaces import ILayoutManager
|
||||||
from cybertools.composer.layout.interfaces import ILayout, ILayoutInstance
|
from cybertools.composer.layout.interfaces import ILayout, ILayoutInstance
|
||||||
|
from cybertools.util.cache import cache
|
||||||
|
|
||||||
|
|
||||||
|
rendererTemplate = ViewPageTemplateFile('renderer.pt')
|
||||||
|
|
||||||
|
|
||||||
class BaseView(object):
|
class BaseView(object):
|
||||||
|
|
||||||
template = ViewPageTemplateFile('base.pt')
|
template = ViewPageTemplateFile('base.pt')
|
||||||
|
rendererTemplate = rendererTemplate
|
||||||
|
|
||||||
page = None
|
page = None
|
||||||
parent = None
|
parent = None
|
||||||
|
@ -54,6 +59,25 @@ class BaseView(object):
|
||||||
def authenticated(self):
|
def authenticated(self):
|
||||||
return not IUnauthenticatedPrincipal.providedBy(self.request.principal)
|
return not IUnauthenticatedPrincipal.providedBy(self.request.principal)
|
||||||
|
|
||||||
|
def cachedRenderer(self, name, *args):
|
||||||
|
baseRenderer = self.renderer.template.macros[name]
|
||||||
|
cr = CachableRenderer(self, baseRenderer)
|
||||||
|
return cr.renderMacro(*args)
|
||||||
|
|
||||||
|
|
||||||
|
class CachableRenderer(object):
|
||||||
|
|
||||||
|
def __init__(self, view, renderer):
|
||||||
|
self.view = view
|
||||||
|
self.renderer = renderer
|
||||||
|
|
||||||
|
def getRenderMacroId(self, *args):
|
||||||
|
return 'renderer.' + '.'.join(args)
|
||||||
|
|
||||||
|
@cache(getRenderMacroId, lifetime=3600)
|
||||||
|
def renderMacro(self, *args):
|
||||||
|
return rendererTemplate(self.view, view=self.view, macro=self.renderer)
|
||||||
|
|
||||||
|
|
||||||
class Page(BaseView):
|
class Page(BaseView):
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,15 @@ A simple caching mechanism.
|
||||||
$Id$
|
$Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from zope import component
|
||||||
|
try:
|
||||||
|
from lovely.memcached.interfaces import IMemcachedClient
|
||||||
|
except ImportError:
|
||||||
|
IMemcachedClient = None
|
||||||
|
|
||||||
|
|
||||||
|
# internal implementation
|
||||||
|
|
||||||
from cybertools.util.date import getTimeStamp
|
from cybertools.util.date import getTimeStamp
|
||||||
|
|
||||||
INVALID = object()
|
INVALID = object()
|
||||||
|
@ -66,3 +75,22 @@ def cache(getIdentifier, lifetime=3600):
|
||||||
return value
|
return value
|
||||||
return __cache
|
return __cache
|
||||||
return _cache
|
return _cache
|
||||||
|
|
||||||
|
|
||||||
|
# memcached implementation
|
||||||
|
|
||||||
|
def mcCache(getIdentifier, lifetime=3600):
|
||||||
|
def _cache(fct):
|
||||||
|
def __cache(*args, **kw):
|
||||||
|
id = getIdentifier(*args, **kw)
|
||||||
|
client = component.getUtility(IMemcachedClient)
|
||||||
|
value = client.query(id)
|
||||||
|
if value is None:
|
||||||
|
value = fct(*args, **kw)
|
||||||
|
client.set(value, id, lifetime=lifetime)
|
||||||
|
return value
|
||||||
|
return __cache
|
||||||
|
return _cache
|
||||||
|
|
||||||
|
if IMemcachedClient is not None:
|
||||||
|
cache = mcCache
|
||||||
|
|
Loading…
Add table
Reference in a new issue