Handle cache in portlet renderer
authorThierry Florac <thierry.florac@onf.fr>
Thu, 21 Jun 2018 16:37:36 +0200
changeset 133 7ad82c70e528
parent 132 75822b1c3da3
child 134 1cee610aecce
Handle cache in portlet renderer
src/pyams_portal/portlet.py
--- a/src/pyams_portal/portlet.py	Thu Jun 21 16:36:26 2018 +0200
+++ b/src/pyams_portal/portlet.py	Thu Jun 21 16:37:36 2018 +0200
@@ -9,6 +9,7 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
+from pyams_portal.views import PREVIEW_MODE
 
 __docformat__ = 'restructuredtext'
 
@@ -24,11 +25,13 @@
 from pyams_portal.interfaces import IPortlet, IPortletSettings, IPortletConfiguration, IPortletPreviewer, \
     IPortletRenderer, IPortalPortletsConfiguration, IPortalTemplate, IPortalContext, IPortalPage, \
     IPortalTemplateConfiguration, MANAGE_TEMPLATE_PERMISSION, IPortletRendererSettings, PORTLET_RENDERER_SETTINGS_KEY
+from pyams_utils.interfaces import ICacheKeyValue
 from zope.traversing.interfaces import ITraversable
 
 # import packages
 from persistent import Persistent
 from persistent.mapping import PersistentMapping
+from pyams_cache.beaker import get_cache
 from pyams_utils.adapter import adapter_config, ContextAdapter, get_adapter_weight, get_annotation_adapter
 from pyams_utils.factory import get_object_factory, is_interface
 from pyams_utils.request import check_request
@@ -134,13 +137,12 @@
         self.portlet = request.registry.queryUtility(IPortlet, name=settings.configuration.portlet_name)
         self.settings = settings
 
-    def __call__(self):
+    def render(self):
         if self.portlet is None:
             return ''
         if self.portlet.permission and not self.request.has_permission(self.portlet.permission):
             return ''
-        self.update()
-        return self.render()
+        return super(PortletContentProvider, self).render()
 
 
 @implementer(IPortletPreviewer)
@@ -164,6 +166,11 @@
             return super(PortletPreviewer, self).render()
 
 
+PORTLETS_CACHE_KEY = 'portlet::{portlet}::{context}'
+PORTLETS_CACHE_REGION = 'portlets'
+PORTLETS_CACHE_NAME = 'PyAMS::portlet'
+
+
 @implementer(IPortletRenderer)
 class PortletRenderer(PortletContentProvider):
     """Portlet renderer adapter"""
@@ -189,6 +196,24 @@
     def renderer_settings(self):
         return IPortletRendererSettings(self.settings)
 
+    def render(self):
+        preview_mode = self.request.annotations.get(PREVIEW_MODE, False)
+        if preview_mode:
+            return super(PortletRenderer, self).render()
+        else:
+            portlets_cache = get_cache(PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME)
+            cache_key = PORTLETS_CACHE_KEY.format(portlet=ICacheKeyValue(self.settings),
+                                                  context=ICacheKeyValue(self.context))
+            try:
+                result = portlets_cache.get_value(cache_key)
+                logger.debug("Retrieving portlet content for cache key {0}".format(cache_key))
+            except KeyError:
+                self.update()
+                result = super(PortletRenderer, self).render()
+                portlets_cache.set_value(cache_key, result)
+                logger.debug("Storing portlet content for cache key {0}".format(cache_key))
+            return result
+
 
 @vocabulary_config(name='PyAMS portlet renderers')
 class PortletRenderersVocabulary(SimpleVocabulary):