--- a/src/pyams_portal/portlet.py Wed Jul 12 12:21:40 2017 +0200
+++ b/src/pyams_portal/portlet.py Wed Jul 12 12:23:32 2017 +0200
@@ -20,9 +20,10 @@
import venusian
# import interfaces
+from pyams_form.interfaces.form import IFormContextPermissionChecker
from pyams_portal.interfaces import IPortlet, IPortletSettings, IPortletConfiguration, IPortletPreviewer, \
IPortletRenderer, IPortalPortletsConfiguration, IPortalTemplate, IPortalContext, IPortalPage, \
- IPortalTemplateConfiguration
+ IPortalTemplateConfiguration, MANAGE_TEMPLATE_PERMISSION
from zope.traversing.interfaces import ITraversable
# import packages
@@ -189,7 +190,12 @@
@implementer(IPortletSettings)
class PortletSettings(Persistent, Contained):
- """Portlet settings persistent class"""
+ """Portlet settings persistent class
+
+ This class is supposed to be sub-classed by all custom portlet subclasses to
+ store their configuration settings.
+ Each portlet sub-class must define it's settings class in it's "settings_class" attribute.
+ """
visible = FieldProperty(IPortletSettings['visible'])
_renderer = FieldProperty(IPortletSettings['renderer'])
@@ -228,8 +234,12 @@
class PortletConfiguration(Persistent, Contained):
"""Portlet configuration persistent class
- PortletConfiguration.__parent__ points to context where configuration is applied
- PortletConfiguration.parent points to context from where configuration is inherited
+ This class is a generic persistent class which is used to store all portlet
+ configuration and is *not* supposed to be sub-classed.
+
+ PortletConfiguration.__parent__ points to context where configuration is applied (each context or
+ local template).
+ PortletConfiguration.parent points to context from where configuration is inherited.
"""
portlet_id = FieldProperty(IPortletConfiguration['portlet_id'])
@@ -263,7 +273,8 @@
configuration = IPortalPortletsConfiguration(parent).get_portlet_configuration(self.portlet_id)
if not configuration.inherit_parent:
return parent
- if not IPortalContext.providedBy(parent.__parent__):
+ page = IPortalPage(parent)
+ if not page.inherit_parent:
break
parent = parent.__parent__
page = IPortalPage(parent, None)
@@ -302,6 +313,15 @@
return self.context.settings
+@adapter_config(context=IPortletConfiguration, provides=IFormContextPermissionChecker)
+class PortletConfigurationPermissionChecker(ContextAdapter):
+ """Portlet configuration permission checker"""
+
+ @property
+ def edit_permission(self):
+ return MANAGE_TEMPLATE_PERMISSION
+
+
#
# Template portlets configuration
#
@@ -310,11 +330,29 @@
class PortalPortletsConfiguration(PersistentMapping, Contained):
"""Portal portlets configuration"""
+ @classmethod
+ def clone(cls, source_config, new_parent):
+ """Clone source configuration"""
+ configuration = source_config.__class__()
+ get_current_registry().notify(ObjectCreatedEvent(configuration))
+ locate(configuration, new_parent)
+ for config_id, config_portlet in source_config.items():
+ config = clone(config_portlet)
+ configuration[config_id] = config
+ return configuration
+
+ def __setitem__(self, key, value):
+ super(PortalPortletsConfiguration, self).__setitem__(key, value)
+ locate(value, self.__parent__, '++portlet++{0}'.format(key))
+
def get_portlet_configuration(self, portlet_id):
configuration = self.get(portlet_id)
- if (configuration is None) and not IPortalTemplate.providedBy(self.__parent__):
- template = IPortalPage(self.__parent__).template
- portlets = IPortalPortletsConfiguration(template)
+ if configuration is None:
+ if IPortalTemplate.providedBy(self.__parent__):
+ portlets = IPortalPortletsConfiguration(self.__parent__)
+ else:
+ template = IPortalPage(self.__parent__).template
+ portlets = IPortalPortletsConfiguration(template)
configuration = clone(portlets.get_portlet_configuration(portlet_id))
get_current_registry().notify(ObjectCreatedEvent(configuration))
self.set_portlet_configuration(portlet_id, configuration)
@@ -323,7 +361,6 @@
def set_portlet_configuration(self, portlet_id, config):
config.portlet_id = portlet_id
self[portlet_id] = config
- locate(config, self.__parent__, '++portlet++{0}'.format(portlet_id))
def delete_portlet_configuration(self, portlet_id):
if isinstance(portlet_id, int):