# HG changeset patch # User Thierry Florac # Date 1541613766 -3600 # Node ID 713edde7dbf1c36f4209e466cd64528685d9e679 # Parent 40bffafce365e78e96a45bb4713829b99d3c1bb6 Moved skin related features from PyAMS_content package diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/association/__init__.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/gallery/__init__.py --- 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""" diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/illustration/__init__.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/keynumber/__init__.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/audio.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/contact.py --- 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 _ diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/container.py --- /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 +# 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/frame.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/html.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/keypoint.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/map.py --- 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 _ diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/milestone.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/pictogram.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/verbatim.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/paragraph/video.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/component/video/__init__.py --- 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 diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/features/footer/__init__.py --- 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): diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/features/footer/skin/__init__.py --- 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), diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/features/header/__init__.py --- 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) diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/features/header/skin/__init__.py --- 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), diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/features/header/skin/interfaces.py --- /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 +# 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""" diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/features/renderer/__init__.py --- /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 +# 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 '' diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/shared/form/__init__.py --- /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 +# 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() diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/shared/imagemap/__init__.py --- 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) diff -r 40bffafce365 -r 713edde7dbf1 src/pyams_default_theme/shared/logo/__init__.py --- 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