--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_portal/page.py Wed Jun 17 09:58:33 2015 +0200
@@ -0,0 +1,151 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+from pyramid.view import view_config
+from zope.traversing.interfaces import ITraversable
+from pyams_portal.template import PortalWfTemplate, PortalTemplate
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.registry import query_utility
+from pyams_workflow.interfaces import IWorkflowInfo, IWorkflowVersions
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_portal.interfaces import IPortalPage, IPortalContext, IPortalTemplateRenderer, \
+ IPortalTemplateConfiguration, IPortalWfTemplate
+from zope.annotation.interfaces import IAnnotations
+
+# import packages
+from persistent import Persistent
+from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyramid.threadlocal import get_current_registry
+from zope.container.contained import Contained
+from zope.interface import implementer
+from zope.lifecycleevent import ObjectCreatedEvent, ObjectAddedEvent
+from zope.location.location import locate
+from zope.schema.fieldproperty import FieldProperty
+
+
+@implementer(IPortalPage)
+class PortalPage(Persistent, Contained):
+ """Portal page"""
+
+ _inherit_parent = FieldProperty(IPortalPage['inherit_parent'])
+ _use_local_template = FieldProperty(IPortalPage['use_local_template'])
+ _shared_template = FieldProperty(IPortalPage['shared_template'])
+ _local_template = FieldProperty(IPortalPage['local_template'])
+
+ @property
+ def can_inherit(self):
+ return IPortalContext.providedBy(self.__parent__.__parent__)
+
+ @property
+ def inherit_parent(self):
+ return self._inherit_parent if self.can_inherit else False
+
+ @inherit_parent.setter
+ def inherit_parent(self, value):
+ self._inherit_parent = value
+
+ @property
+ def use_local_template(self):
+ if self.inherit_parent:
+ return IPortalPage(self.__parent__.__parent__).use_local_template
+ else:
+ return self._use_local_template
+
+ @use_local_template.setter
+ def use_local_template(self, value):
+ self._use_local_template = value
+ if value and (self._local_template is None):
+ registry = get_current_registry()
+ wf_template = self._local_template = PortalWfTemplate()
+ registry.notify(ObjectCreatedEvent(wf_template))
+ locate(wf_template, self, '++template++')
+ template = PortalTemplate()
+ registry.notify(ObjectCreatedEvent(template))
+ IWorkflowVersions(wf_template).add_version(template, None)
+ IWorkflowInfo(template).fire_transition('init')
+
+ @property
+ def shared_template(self):
+ if self.inherit_parent:
+ return IPortalPage(self.__parent__.__parent__).shared_template
+ else:
+ return self._shared_template
+
+ @shared_template.setter
+ def shared_template(self, value):
+ if not self.inherit_parent:
+ if isinstance(value, IPortalWfTemplate):
+ value = value.__name__
+ self._shared_template = value
+
+ @property
+ def local_template(self):
+ if self.inherit_parent:
+ return IPortalPage(self.__parent__.__parent__).local_template
+ else:
+ return self._local_template
+
+ @local_template.setter
+ def local_template(self, value):
+ if not self.inherit_parent:
+ self._local_template = value
+
+ @property
+ def template(self):
+ if self.use_local_template:
+ return self.local_template
+ else:
+ template = self.shared_template
+ if isinstance(template, str):
+ template = query_utility(IPortalWfTemplate, name=template)
+ return template
+
+
+PORTAL_PAGE_KEY = 'pyams_portal.page'
+
+
+@adapter_config(name='template', context=IPortalContext, provides=ITraversable)
+class PortalPageTemplateTraverser(ContextAdapter):
+ """++template++ portal context traverser"""
+
+ def traverse(self, name, furtherpath=None):
+ page = IPortalPage(self.context)
+ if page.use_local_template:
+ return page.template
+
+
+@adapter_config(context=IPortalContext, provides=IPortalPage)
+def PortalPageFactory(context):
+ """Portal page factory"""
+ annotations = IAnnotations(context)
+ page = annotations.get(PORTAL_PAGE_KEY)
+ if page is None:
+ page = annotations[PORTAL_PAGE_KEY] = PortalPage()
+ get_current_registry().notify(ObjectCreatedEvent(page))
+ locate(page, context)
+ return page
+
+
+@view_config(context=IPortalContext, request_type=IPyAMSLayer)
+def PortalPageRenderer(request):
+ page = IPortalPage(request.context)
+ template = page.template
+ registry = request.registry
+ renderer = registry.queryMultiAdapter((request.context, request, template), IPortalTemplateRenderer)
+ if renderer is not None:
+ configuration = registry.queryMultiAdapter((request.context, template), IPortalTemplateConfiguration)
+ return renderer(configuration)