# HG changeset patch # User Thierry Florac # Date 1532031329 -7200 # Node ID 1fcd5c845d1d051440c8dfbd7556954526d0bb04 # Parent 17c1149151aad37ac80008db5825d9d6e6b2c27d Invalidate cache on settings update diff -r 17c1149151aa -r 1fcd5c845d1d src/pyams_content/features/footer/__init__.py --- a/src/pyams_content/features/footer/__init__.py Thu Jul 19 17:19:50 2018 +0200 +++ b/src/pyams_content/features/footer/__init__.py Thu Jul 19 22:15:29 2018 +0200 @@ -18,16 +18,20 @@ # import interfaces from pyams_content.features.footer.interfaces import FOOTER_RENDERERS, IFooterRenderer, IFooterSettings, IFooterTarget, \ FOOTER_SETTINGS_KEY, IFooterRendererSettings, FOOTER_RENDERER_SETTINGS_KEY +from zope.lifecycleevent.interfaces import IObjectModifiedEvent from zope.traversing.interfaces import ITraversable # import packages from persistent import Persistent +from pyams_cache.beaker import get_cache from pyams_content.features.renderer import RenderedContentMixin +from pyams_portal.portlet import PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter from pyams_utils.inherit import BaseInheritInfo, InheritedFieldProperty from pyams_utils.request import check_request from pyams_utils.traversing import get_parent from pyams_utils.vocabulary import vocabulary_config +from pyramid.events import subscriber from zope.interface import implementer, noLongerProvides, alsoProvides from zope.location import Location, locate from zope.schema.fieldproperty import FieldProperty @@ -77,6 +81,14 @@ return get_annotation_adapter(context, FOOTER_SETTINGS_KEY, FooterSettings, name='++footer++') +@subscriber(IObjectModifiedEvent, context_selector=IFooterSettings) +def handle_modified_footer_settings(event): + """Clear cache if modified footer settings""" + renderer = event.object.get_renderer() + portlets_cache = get_cache(PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME) + portlets_cache.remove(renderer.cache_key) + + @adapter_config(name='footer', context=IFooterTarget, provides=ITraversable) class FooterTargetNamespace(ContextAdapter): """Footer target '++footer++' namespace traverser""" diff -r 17c1149151aa -r 1fcd5c845d1d src/pyams_content/features/footer/interfaces/__init__.py --- a/src/pyams_content/features/footer/interfaces/__init__.py Thu Jul 19 17:19:50 2018 +0200 +++ b/src/pyams_content/features/footer/interfaces/__init__.py Thu Jul 19 22:15:29 2018 +0200 @@ -54,6 +54,7 @@ name = Attribute("Renderer name") settings_key = Attribute("Renderer settings key") + cache_key = Attribute("Renderer cache key") class IFooterRendererSettings(IRendererSettings): diff -r 17c1149151aa -r 1fcd5c845d1d src/pyams_content/features/footer/skin/__init__.py --- a/src/pyams_content/features/footer/skin/__init__.py Thu Jul 19 17:19:50 2018 +0200 +++ b/src/pyams_content/features/footer/skin/__init__.py Thu Jul 19 22:15:29 2018 +0200 @@ -32,13 +32,18 @@ from pyams_utils.adapter import adapter_config from pyams_utils.traversing import get_parent from pyramid.decorator import reify +from zope.interface import implementer from pyams_content import _ +@implementer(IFooterRenderer) class BaseFooterRenderer(BaseContentRenderer): """Base footer renderer""" + name = None + settings_key = None + @reify def settings_target(self): context = self.request.annotations.get(DISPLAY_CONTEXT) @@ -56,24 +61,28 @@ settings = IFooterSettings(settings.parent) return settings.settings + @reify + def cache_key(self): + return PORTLETS_CACHE_KEY.format(portlet=self.name, + context=ICacheKeyValue(self.settings_target), + lang=self.request.locale_name) + def render(self): preview_mode = self.request.annotations.get(PREVIEW_MODE, False) if preview_mode: return super(BaseFooterRenderer, self).render() else: portlets_cache = get_cache(PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME) - cache_key = PORTLETS_CACHE_KEY.format(portlet=self.name, - context=ICacheKeyValue(self.settings_target), - lang=self.request.locale_name) + cache_key = self.cache_key if self.context is not self.request.context: # display shared content cache_key = '{0}::shared'.format(cache_key) try: result = portlets_cache.get_value(cache_key) - logger.debug("Retrieving header content from cache key {0}".format(cache_key)) + logger.debug("Retrieving footer content from cache key {0}".format(cache_key)) except KeyError: result = super(BaseFooterRenderer, self).render() portlets_cache.set_value(cache_key, result) - logger.debug("Storing header content for cache key {0}".format(cache_key)) + logger.debug("Storing footer content to cache key {0}".format(cache_key)) return result diff -r 17c1149151aa -r 1fcd5c845d1d src/pyams_content/features/header/__init__.py --- a/src/pyams_content/features/header/__init__.py Thu Jul 19 17:19:50 2018 +0200 +++ b/src/pyams_content/features/header/__init__.py Thu Jul 19 22:15:29 2018 +0200 @@ -18,16 +18,20 @@ # import interfaces from pyams_content.features.header.interfaces import HEADER_RENDERERS, IHeaderRenderer, IHeaderSettings, IHeaderTarget, \ HEADER_SETTINGS_KEY, IHeaderRendererSettings, HEADER_RENDERER_SETTINGS_KEY +from zope.lifecycleevent.interfaces import IObjectModifiedEvent from zope.traversing.interfaces import ITraversable # import packages from persistent import Persistent +from pyams_cache.beaker import get_cache from pyams_content.features.renderer import RenderedContentMixin +from pyams_portal.portlet import PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter from pyams_utils.inherit import BaseInheritInfo, InheritedFieldProperty from pyams_utils.request import check_request from pyams_utils.traversing import get_parent from pyams_utils.vocabulary import vocabulary_config +from pyramid.events import subscriber from zope.interface import implementer, noLongerProvides, alsoProvides from zope.location import Location, locate from zope.schema.fieldproperty import FieldProperty @@ -77,6 +81,14 @@ return get_annotation_adapter(context, HEADER_SETTINGS_KEY, HeaderSettings, name='++header++') +@subscriber(IObjectModifiedEvent, context_selector=IHeaderSettings) +def handle_modified_header_settings(event): + """Clear cache if modified header settings""" + renderer = event.object.get_renderer() + portlets_cache = get_cache(PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME) + portlets_cache.remove(renderer.cache_key) + + @adapter_config(name='header', context=IHeaderTarget, provides=ITraversable) class HeaderTargetNamespace(ContextAdapter): """Header target '++header++' namespace traverser""" diff -r 17c1149151aa -r 1fcd5c845d1d src/pyams_content/features/header/interfaces/__init__.py --- a/src/pyams_content/features/header/interfaces/__init__.py Thu Jul 19 17:19:50 2018 +0200 +++ b/src/pyams_content/features/header/interfaces/__init__.py Thu Jul 19 22:15:29 2018 +0200 @@ -54,6 +54,8 @@ name = Attribute("Renderer name") settings_key = Attribute("Renderer settings key") + cache_key = Attribute("Renderer cache key") + class IHeaderRendererSettings(IRendererSettings): diff -r 17c1149151aa -r 1fcd5c845d1d src/pyams_content/features/header/skin/__init__.py --- a/src/pyams_content/features/header/skin/__init__.py Thu Jul 19 17:19:50 2018 +0200 +++ b/src/pyams_content/features/header/skin/__init__.py Thu Jul 19 22:15:29 2018 +0200 @@ -33,13 +33,18 @@ from pyams_utils.adapter import adapter_config from pyams_utils.traversing import get_parent from pyramid.decorator import reify +from zope.interface import implementer from pyams_content import _ +@implementer(IHeaderRenderer) class BaseHeaderRenderer(BaseContentRenderer): """Base header renderer""" + name = None + settings_key = None + @reify def settings_target(self): context = self.request.annotations.get(DISPLAY_CONTEXT) @@ -57,6 +62,12 @@ settings = IHeaderSettings(settings.parent) return settings.settings + @reify + def cache_key(self): + return PORTLETS_CACHE_KEY.format(portlet=self.name, + context=ICacheKeyValue(self.settings_target), + lang=self.request.locale_name) + @property def main_header_class(self): request = self.request @@ -68,9 +79,7 @@ return super(BaseHeaderRenderer, self).render() else: portlets_cache = get_cache(PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME) - cache_key = PORTLETS_CACHE_KEY.format(portlet=self.name, - context=ICacheKeyValue(self.settings_target), - lang=self.request.locale_name) + cache_key = self.cache_key if self.context is not self.request.context: # display shared content cache_key = '{0}::shared'.format(cache_key) try: @@ -79,7 +88,7 @@ except KeyError: result = super(BaseHeaderRenderer, self).render() portlets_cache.set_value(cache_key, result) - logger.debug("Storing header content for cache key {0}".format(cache_key)) + logger.debug("Storing header content to cache key {0}".format(cache_key)) return result