--- a/src/pyams_default_theme/component/association/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/association/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -23,8 +23,8 @@
from pyams_content.component.links.interfaces import IBaseLink, IInternalLink
from pyams_content.component.paragraph.interfaces import IParagraphContainer, IParagraphContainerTarget
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_default_theme.component.association.interfaces import IAssociationParagraphRemoteContentRendererSettings
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config, get_annotation_adapter
--- a/src/pyams_default_theme/component/gallery/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/gallery/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,15 +12,15 @@
__docformat__ = 'restructuredtext'
-
from pyams_content.component.gallery.interfaces import IBaseGallery
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.features.renderer.skin import BaseContentRenderer
-from pyams_default_theme import _
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
+from pyams_default_theme import _
+
class BaseGalleryRenderer(BaseContentRenderer):
"""Base gallery renderer"""
--- a/src/pyams_default_theme/component/illustration/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/illustration/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -9,8 +9,6 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
-from pyams_content.shared.common import ISharedContent
-
__docformat__ = 'restructuredtext'
@@ -23,12 +21,13 @@
from pyams_content.component.illustration.interfaces import IIllustration
from pyams_content.component.links import IInternalLink
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_content.interfaces import IBaseContent
from pyams_content.root import ISiteRoot
+from pyams_content.shared.common import ISharedContent
from pyams_content.shared.site.interfaces import IContentLink
from pyams_default_theme.component.illustration.interfaces import IIllustrationRenderer, IIllustrationWithZoomSettings, \
ILLUSTRATION_AFTER_BODY, ILLUSTRATION_BEFORE_BODY
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_default_theme.interfaces import IContentBannerIllustration, IContentHeaderIllustration, \
IContentNavigationIllustration
from pyams_skin.layer import IPyAMSLayer
--- a/src/pyams_default_theme/component/keynumber/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/keynumber/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,15 +12,10 @@
__docformat__ = 'restructuredtext'
-# import standard library
-
-# import interfaces
from pyams_content.component.keynumber.interfaces import IKeyNumberContainer, IKeyNumberParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
--- a/src/pyams_default_theme/component/paragraph/audio.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/audio.py Wed Nov 07 19:02:46 2018 +0100
@@ -13,15 +13,10 @@
__docformat__ = 'restructuredtext'
-# import standard library
-
-# import interfaces
from pyams_content.component.paragraph.interfaces.audio import IAudioParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
--- a/src/pyams_default_theme/component/paragraph/contact.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/contact.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,23 +12,18 @@
__docformat__ = 'restructuredtext'
+from persistent import Persistent
+from zope.interface import implementer
+from zope.location import Location
+from zope.schema.fieldproperty import FieldProperty
-# import standard library
-from persistent import Persistent
-
-# import interfaces
-from pyams_content.component.paragraph.interfaces.contact import have_gis, IContactParagraph
+from pyams_content.component.paragraph.interfaces.contact import IContactParagraph, have_gis
from pyams_content.features.renderer.interfaces import IContentRenderer
from pyams_default_theme.component.paragraph.interfaces.contact import IContactParagraphDefaultRendererSettings
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config, get_annotation_adapter
-from zope.interface import implementer
-from zope.location import locate, Location
-from zope.schema.fieldproperty import FieldProperty
from pyams_default_theme import _
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/component/paragraph/container.py Wed Nov 07 19:02:46 2018 +0100
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2008-2018 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.
+#
+
+__docformat__ = 'restructuredtext'
+
+from pyams_content.component.paragraph import IParagraphContainer, IParagraphContainerTarget
+from pyams_content.component.paragraph.interfaces import IParagraphRenderer
+from pyams_content.features.renderer.interfaces import ISharedContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.adapter import adapter_config
+
+
+@adapter_config(name='paragraphs-render', context=(IParagraphContainerTarget, IPyAMSLayer),
+ provides=ISharedContentRenderer)
+class ParagraphsContainerRenderer(BaseContentRenderer):
+ """Paragraphs container renderer"""
+
+ weight = 10
+
+ def __init__(self, context, request):
+ super(ParagraphsContainerRenderer, self).__init__(context, request)
+ paragraphs = [para for para in IParagraphContainer(self.context).values()
+ if para.visible]
+ registry = self.request.registry
+ self.renderers = [registry.queryMultiAdapter((paragraph, self.request), IParagraphRenderer)
+ for paragraph in paragraphs]
+
+ def update(self):
+ super(ParagraphsContainerRenderer, self).update()
+ for renderer in self.renderers:
+ if renderer is not None:
+ renderer.language = self.language
+ renderer.update()
+
+ def render(self):
+ result = ''
+ for renderer in self.renderers:
+ if renderer is not None:
+ result += renderer.render()
+ return result
--- a/src/pyams_default_theme/component/paragraph/frame.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/frame.py Wed Nov 07 19:02:46 2018 +0100
@@ -21,12 +21,11 @@
from pyams_content.component.illustration.interfaces import IIllustration
from pyams_content.component.paragraph.interfaces.frame import IFrameParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_content.reference.pictograms.interfaces import IPictogramTable
from pyams_default_theme.component.paragraph.interfaces.frame import IDefaultFrameParagraphRendererSettings, \
IFrameParagraphRendererSettings, ILateralFrameParagraphRendererSettings, ILeftFrameParagraphRendererSettings, \
IRightFrameParagraphRendererSettings
-from pyams_i18n.interfaces import II18n
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config, get_annotation_adapter
--- a/src/pyams_default_theme/component/paragraph/html.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/html.py Wed Nov 07 19:02:46 2018 +0100
@@ -15,7 +15,7 @@
from pyams_content.component.illustration import IIllustration
from pyams_content.component.paragraph.interfaces.html import IHTMLParagraph, IRawParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.features.renderer.skin import BaseContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
--- a/src/pyams_default_theme/component/paragraph/keypoint.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/keypoint.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,16 +12,10 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
from pyams_content.component.paragraph.interfaces.keypoint import IKeypointsParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
--- a/src/pyams_default_theme/component/paragraph/map.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/map.py Wed Nov 07 19:02:46 2018 +0100
@@ -16,24 +16,20 @@
from pyams_content.component.paragraph.interfaces.map import have_gis
if have_gis:
- # import standard library
+ from zope.interface import implementer
+ from zope.schema.fieldproperty import FieldProperty
- # import interfaces
from pyams_content.component.paragraph.interfaces.map import IMapParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
from pyams_default_theme.component.paragraph.interfaces.map import IMapParagraphDefaultRendererSettings
from pyams_gis.interfaces.configuration import IMapConfiguration
from pyams_gis.interfaces.utility import IMapManager
from pyams_skin.layer import IPyAMSLayer
-
- # import packages
- from pyams_content.features.renderer.skin import BaseContentRenderer
+ from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_gis.configuration import MapConfiguration
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config, get_annotation_adapter
from pyams_utils.registry import get_utility
- from zope.interface import implementer
- from zope.schema.fieldproperty import FieldProperty
from pyams_default_theme import _
--- a/src/pyams_default_theme/component/paragraph/milestone.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/milestone.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,19 +12,15 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
from pyams_content.component.paragraph.interfaces.milestone import IMilestoneParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
-from pyams_default_theme import _
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
+from pyams_default_theme import _
+
#
# Milestone paragraph default renderer
--- a/src/pyams_default_theme/component/paragraph/pictogram.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/pictogram.py Wed Nov 07 19:02:46 2018 +0100
@@ -14,7 +14,7 @@
from pyams_content.component.paragraph.interfaces.pictogram import IPictogramContainer, IPictogramParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.features.renderer.skin import BaseContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
--- a/src/pyams_default_theme/component/paragraph/verbatim.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/verbatim.py Wed Nov 07 19:02:46 2018 +0100
@@ -20,8 +20,8 @@
from pyams_content.component.illustration.interfaces import IIllustration
from pyams_content.component.paragraph.interfaces.verbatim import IVerbatimParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_default_theme.component.paragraph.interfaces.verbatim import ILateralVerbatimParagraphRendererSettings
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_i18n.interfaces import II18n
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
--- a/src/pyams_default_theme/component/paragraph/video.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/video.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,16 +12,10 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
from pyams_content.component.paragraph.interfaces.video import IVideoParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
--- a/src/pyams_default_theme/component/video/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/component/video/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,16 +12,10 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
from pyams_content.component.video.interfaces import IExternalVideoParagraph, IExternalVideoRenderer
from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
from pyams_utils.registry import get_current_registry
--- a/src/pyams_default_theme/features/footer/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/features/footer/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,27 +12,22 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
-from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
-from pyams_content.features.footer.interfaces import IFooterTarget, IFooterSettings
-from pyams_content.features.menu.interfaces import IMenuLinksContainerTarget, IMenuLinksContainer
-from pyams_default_theme.features.footer.interfaces import ISimpleFooterRendererSettings, ISimpleFooterLinksMenu
-from pyams_default_theme.layer import IPyAMSDefaultLayer
-from zope.location.interfaces import ISublocations
-
-# import packages
from persistent import Persistent
-from pyams_content.features.menu import Menu
-from pyams_utils.adapter import get_annotation_adapter, adapter_config, ContextAdapter
-from pyams_utils.traversing import get_parent
-from pyams_viewlet.viewlet import contentprovider_config, ViewContentProvider
from zope.interface import implementer
from zope.location import Location
+from zope.location.interfaces import ISublocations
from zope.schema.fieldproperty import FieldProperty
+from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
+from pyams_content.features.footer.interfaces import IFooterSettings, IFooterTarget
+from pyams_content.features.menu import Menu
+from pyams_content.features.menu.interfaces import IMenuLinksContainer, IMenuLinksContainerTarget
+from pyams_default_theme.features.footer.interfaces import ISimpleFooterLinksMenu, ISimpleFooterRendererSettings
+from pyams_default_theme.layer import IPyAMSDefaultLayer
+from pyams_utils.adapter import ContextAdapter, adapter_config, get_annotation_adapter
+from pyams_utils.traversing import get_parent
+from pyams_viewlet.viewlet import ViewContentProvider, contentprovider_config
+
@contentprovider_config(name='pyams.footer', layer=IPyAMSDefaultLayer)
class FooterContentProvider(ViewContentProvider):
--- a/src/pyams_default_theme/features/footer/skin/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/features/footer/skin/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,18 +12,25 @@
__docformat__ = 'restructuredtext'
+import logging
+logger = logging.getLogger('PyAMS (content)')
-# import standard library
+from pyramid.decorator import reify
+from zope.interface import implementer
-# import interfaces
+from pyams_cache.beaker import get_cache
+from pyams_content.features.renderer.interfaces import HIDDEN_RENDERER_NAME
+from pyams_default_theme.features.renderer import BaseContentRenderer
+from pyams_portal.interfaces import PREVIEW_MODE
+from pyams_portal.portlet import PORTLETS_CACHE_KEY, PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME
+from pyams_utils.interfaces import ICacheKeyValue
+from pyams_utils.interfaces.url import DISPLAY_CONTEXT
+from pyams_utils.traversing import get_parent
from pyams_content.component.association.interfaces import IAssociationInfo
from pyams_content.features.footer.interfaces import IFooterTarget, IFooterRenderer, IFooterSettings, \
IFooterRendererSettings
from pyams_default_theme.features.footer.interfaces import ISimpleFooterRendererSettings
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.footer.skin import BaseFooterRenderer
from pyams_default_theme.features.footer import SimpleFooterRendererSettings
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
@@ -31,13 +38,83 @@
from pyams_default_theme import _
-SIMPLE_FOOTER_RENDERER_NAME = 'PyAMS simple footer'
+#
+# Simple footer renderer
+#
+
+@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)
+ if context is None:
+ context = self.context
+ return get_parent(context, IFooterTarget)
+
+ @reify
+ def settings(self):
+ if self.settings_interface is None:
+ return None
+ target = self.settings_target
+ settings = IFooterSettings(target)
+ while settings.inherit:
+ settings = IFooterSettings(settings.parent)
+ return settings.settings
+
+ @reify
+ def cache_key(self):
+ return PORTLETS_CACHE_KEY.format(portlet=self.name,
+ hostname=self.request.host,
+ 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 = 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 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 footer content to cache key {0}".format(cache_key))
+ return result
+
+
+#
+# Hidden footer renderer
+#
+
+@adapter_config(name=HIDDEN_RENDERER_NAME, context=(IFooterTarget, IPyAMSLayer), provides=IFooterRenderer)
+class HiddenFooterRenderer(BaseFooterRenderer):
+ """Hidden footer renderer"""
+
+ name = HIDDEN_RENDERER_NAME
+ label = _("Hidden footer")
+ weight = -999
+
+ def render(self):
+ return ''
#
# Simple footer renderer
#
+SIMPLE_FOOTER_RENDERER_NAME = 'PyAMS simple footer'
+
+
@adapter_config(name=SIMPLE_FOOTER_RENDERER_NAME, context=(IFooterTarget, IPyAMSLayer),
provides=IFooterRenderer)
@adapter_config(name=SIMPLE_FOOTER_RENDERER_NAME, context=(IFooterSettings, IPyAMSLayer),
--- a/src/pyams_default_theme/features/header/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/features/header/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,26 +12,21 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
-from pyams_content.features.header.interfaces import IHeaderTarget, IHeaderSettings
-from pyams_content.features.menu.interfaces import IMenuLinksContainerTarget, IMenuLinksContainer
-from pyams_default_theme.features.header.interfaces import ISimpleHeaderRendererSettings, ISimpleHeaderTabsMenu
-from pyams_default_theme.layer import IPyAMSDefaultLayer
+from persistent import Persistent
+from zope.interface import implementer
+from zope.location import Location
from zope.location.interfaces import ISublocations
-# import packages
-from persistent import Persistent
from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
+from pyams_content.features.header.interfaces import IHeaderSettings, IHeaderTarget
from pyams_content.features.menu import Menu
+from pyams_content.features.menu.interfaces import IMenuLinksContainer, IMenuLinksContainerTarget
+from pyams_default_theme.features.header.interfaces import ISimpleHeaderRendererSettings, ISimpleHeaderTabsMenu
+from pyams_default_theme.layer import IPyAMSDefaultLayer
from pyams_file.property import FileProperty
-from pyams_utils.adapter import get_annotation_adapter, adapter_config, ContextAdapter
+from pyams_utils.adapter import ContextAdapter, adapter_config, get_annotation_adapter
from pyams_utils.traversing import get_parent
-from pyams_viewlet.viewlet import contentprovider_config, ViewContentProvider
-from zope.interface import implementer
-from zope.location import Location
+from pyams_viewlet.viewlet import ViewContentProvider, contentprovider_config
@contentprovider_config(name='pyams.header', layer=IPyAMSDefaultLayer)
--- a/src/pyams_default_theme/features/header/skin/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/features/header/skin/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,34 +12,116 @@
__docformat__ = 'restructuredtext'
+import logging
+logger = logging.getLogger('PyAMS (content)')
-# import standard library
+from pyramid.decorator import reify
+from pyramid.location import lineage
+from zope.interface import implementer
-# import interfaces
+from pyams_cache.beaker import get_cache
from pyams_content.component.association.interfaces import IAssociationInfo
from pyams_content.component.links.interfaces import IInternalLink
-from pyams_content.features.header.interfaces import IHeaderTarget, IHeaderRenderer, IHeaderSettings, \
- IHeaderRendererSettings
+from pyams_content.features.header.interfaces import IHeaderRenderer, IHeaderRendererSettings, IHeaderSettings, \
+ IHeaderTarget
+from pyams_content.features.renderer.interfaces import HIDDEN_RENDERER_NAME
+from pyams_default_theme.features.header import SimpleHeaderRendererSettings
from pyams_default_theme.features.header.interfaces import ISimpleHeaderRendererSettings
+from pyams_default_theme.features.header.skin.interfaces import IHeaderClass
+from pyams_default_theme.features.renderer import BaseContentRenderer
+from pyams_portal.interfaces import PREVIEW_MODE
+from pyams_portal.portlet import PORTLETS_CACHE_KEY, PORTLETS_CACHE_NAME, PORTLETS_CACHE_REGION
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.header.skin import BaseHeaderRenderer
-from pyams_default_theme.features.header import SimpleHeaderRendererSettings
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
-from pyramid.location import lineage
+from pyams_utils.interfaces import ICacheKeyValue
+from pyams_utils.traversing import get_parent
from pyams_default_theme import _
-SIMPLE_HEADER_RENDERER_NAME = 'PyAMS simple header'
+#
+# Base header renderer
+#
+
+@implementer(IHeaderRenderer)
+class BaseHeaderRenderer(BaseContentRenderer):
+ """Base header renderer"""
+
+ name = None
+ settings_key = None
+
+ @reify
+ def settings_target(self):
+ context = self.request.display_context
+ if context is None:
+ context = self.context
+ return get_parent(context, IHeaderTarget)
+
+ @reify
+ def settings(self):
+ if self.settings_interface is None:
+ return None
+ target = self.settings_target
+ settings = IHeaderSettings(target)
+ while settings.inherit:
+ settings = IHeaderSettings(settings.parent)
+ return settings.settings
+
+ @reify
+ def cache_key(self):
+ return PORTLETS_CACHE_KEY.format(portlet=self.name,
+ hostname=self.request.host,
+ context=ICacheKeyValue(self.settings_target),
+ lang=self.request.locale_name)
+
+ @property
+ def main_header_class(self):
+ request = self.request
+ return request.registry.queryMultiAdapter((request.context, request), IHeaderClass, default='')
+
+ def render(self):
+ preview_mode = self.request.annotations.get(PREVIEW_MODE, False)
+ if preview_mode:
+ return super(BaseHeaderRenderer, self).render()
+ else:
+ portlets_cache = get_cache(PORTLETS_CACHE_REGION, PORTLETS_CACHE_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))
+ except KeyError:
+ result = super(BaseHeaderRenderer, self).render()
+ portlets_cache.set_value(cache_key, result)
+ logger.debug("Storing header content to cache key {0}".format(cache_key))
+ return result
+
+
+#
+# Hidden header renderer
+#
+
+@adapter_config(name=HIDDEN_RENDERER_NAME, context=(IHeaderTarget, IPyAMSLayer), provides=IHeaderRenderer)
+class HiddenHeaderRenderer(BaseHeaderRenderer):
+ """Hidden header renderer"""
+
+ name = HIDDEN_RENDERER_NAME
+ label = _("Hidden header")
+ weight = -999
+
+ def render(self):
+ return ''
#
# Simple header renderer
#
+SIMPLE_HEADER_RENDERER_NAME = 'PyAMS simple header'
+
+
@adapter_config(name=SIMPLE_HEADER_RENDERER_NAME, context=(IHeaderTarget, IPyAMSLayer),
provides=IHeaderRenderer)
@adapter_config(name=SIMPLE_HEADER_RENDERER_NAME, context=(IHeaderSettings, IPyAMSLayer),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/header/skin/interfaces.py Wed Nov 07 19:02:46 2018 +0100
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2008-2018 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.
+#
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+
+
+class IHeaderClass(Interface):
+ """Custom header CSS class"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/renderer/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2008-2018 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.
+#
+
+__docformat__ = 'restructuredtext'
+
+from pyramid.decorator import reify
+from zope.interface import implementer
+
+from pyams_content.features.renderer import IContentRenderer, IRenderedContent, IRendererSettings
+from pyams_content.features.renderer.interfaces import HIDDEN_RENDERER_NAME
+from pyams_i18n.interfaces import II18n
+from pyams_skin.layer import IPyAMSLayer
+from pyams_template.template import get_view_template
+from pyams_utils.adapter import ContextRequestAdapter, adapter_config
+
+from pyams_content import _
+
+
+@implementer(IContentRenderer)
+class BaseContentRenderer(ContextRequestAdapter):
+ """Base content renderer"""
+
+ label = None
+ weight = 0
+
+ settings_interface = None
+ resources = ()
+
+ language = None
+ context_attrs = ()
+ i18n_context_attrs = ()
+
+ @reify
+ def settings(self):
+ if self.settings_interface is None:
+ return None
+ return IRendererSettings(self.context)
+
+ def update(self):
+ for resource in self.resources:
+ resource.need()
+ for attr in self.context_attrs:
+ setattr(self, attr, getattr(self.context, attr, None))
+ if self.i18n_context_attrs:
+ i18n = II18n(self.context, None)
+ if i18n is not None:
+ for attr in self.i18n_context_attrs:
+ setattr(self, attr, i18n.query_attribute(attr, lang=self.language, request=self.request))
+
+ render = get_view_template()
+
+
+@adapter_config(name=HIDDEN_RENDERER_NAME, context=(IRenderedContent, IPyAMSLayer), provides=IContentRenderer)
+class HiddenContentRenderer(BaseContentRenderer):
+ """Hidden content renderer"""
+
+ label = _("Hidden content")
+ weight = -999
+
+ @staticmethod
+ def render():
+ return ''
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/shared/form/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -0,0 +1,89 @@
+#
+# Copyright (c) 2008-2018 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.
+#
+
+__docformat__ = 'restructuredtext'
+
+from z3c.form import button, field
+from zope.interface import Interface
+
+from pyams_content.features.renderer.interfaces import ISharedContentRenderer
+from pyams_content.shared.form import IFormFieldContainer, IFormFieldContainerTarget
+from pyams_default_theme.features.renderer import BaseContentRenderer
+from pyams_form.form import InnerAddForm
+from pyams_form.help import FormHelp
+from pyams_form.interfaces.form import IFormHelp
+from pyams_i18n.interfaces import II18n
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.adapter import adapter_config
+
+
+class FormFieldContainerDisplayForm(InnerAddForm):
+ """Form fields container display form"""
+
+ @property
+ def legend(self):
+ return II18n(self.context).query_attribute('user_title', request=self.request)
+
+ @property
+ def fields(self):
+ fields = field.Fields(*IFormFieldContainer(self.context).get_fields())
+ if self.context.use_captcha:
+ # TODO: add captcha
+ # fields += field.Fields(Captcha(title='', description='', required=True))
+ pass
+ return fields
+
+ buttons = button.Buttons(Interface)
+
+ def updateWidgets(self, prefix=None):
+ super(FormFieldContainerDisplayForm, self).updateWidgets(prefix)
+ for widget in self.widgets.values():
+ field = IFormFieldContainer(self.context).get(widget.field.__name__)
+ if field is not None:
+ widget.placeholder = field.placeholder
+
+
+@adapter_config(context=(IFormFieldContainerTarget, IPyAMSLayer, FormFieldContainerDisplayForm),
+ provides=IFormHelp)
+class FormFieldContainerDisplayFormHelp(FormHelp):
+ """Form field container display form help adapter"""
+
+ def __new__(cls, context, request, view):
+ if not context.header:
+ return None
+ return FormHelp.__new__(cls)
+
+ @property
+ def message(self):
+ return II18n(self.context).query_attribute('header', request=self.request)
+
+ message_format = 'text'
+
+
+@adapter_config(name='form-render', context=(IFormFieldContainerTarget, IPyAMSLayer),
+ provides=ISharedContentRenderer)
+class FormFieldContainerRenderer(BaseContentRenderer):
+ """Form field container renderer"""
+
+ weight = 20
+ display_form = None
+
+ def __init__(self, context, request):
+ super(FormFieldContainerRenderer, self).__init__(context, request)
+ self.display_form = FormFieldContainerDisplayForm(context, self.request)
+
+ def update(self):
+ super(FormFieldContainerRenderer, self).update()
+ self.display_form.update()
+
+ def render(self):
+ return self.display_form.render()
--- a/src/pyams_default_theme/shared/imagemap/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/shared/imagemap/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,22 +12,16 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
from pyams_content.component.association.interfaces import IAssociationInfo
from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.shared.imagemap.interfaces import IWfImageMap, IImageMapParagraph
-from pyams_skin.layer import IPyAMSLayer, IPyAMSUserLayer
-from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
+from pyams_content.shared.imagemap.interfaces import IImageMapParagraph, IWfImageMap
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_default_theme.page import BasePreviewPage
from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.layer import IPyAMSLayer, IPyAMSUserLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
from pyams_default_theme import _
@@ -57,7 +51,7 @@
label = _("Default imagemap renderer")
- i18n_context_attrs = ('title', )
+ i18n_context_attrs = ('title',)
def get_item_info(self, item):
return IAssociationInfo(item, None)
--- a/src/pyams_default_theme/shared/logo/__init__.py Wed Nov 07 18:25:36 2018 +0100
+++ b/src/pyams_default_theme/shared/logo/__init__.py Wed Nov 07 19:02:46 2018 +0100
@@ -12,15 +12,10 @@
__docformat__ = 'restructuredtext'
-# import standard library
-
-# import interfaces
from pyams_content.features.renderer.interfaces import IContentRenderer
from pyams_content.shared.logo.interfaces import ILogosParagraph
+from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config