src/pyams_portal/page.py
changeset 0 6f99128c6d48
child 5 670b7956c689
--- /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)