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:
helmutm 2009-11-23 12:53:39 +00:00
parent 0341411d22
commit 4e1e2370a2
4 changed files with 75 additions and 3 deletions

View file

@ -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]

View file

@ -0,0 +1,6 @@
<!-- $Id$ -->
<tal:renderer define="view nocall:options/view;
macro options/macro">
<metal:content use-macro="macro" />
</tal:renderer>

View file

@ -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):

View file

@ -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