# HG changeset patch # User Thierry Florac # Date 1605270180 -3600 # Node ID 43de10a58806635ab888256d5b5c893ea9ee5b9f # Parent 45eb6e5705c04e5f33402377daf94e950a5012cf Added HTML paragraph renderer including logo diff -r 45eb6e5705c0 -r 43de10a58806 src/pyams_default_theme/component/paragraph/html.py --- a/src/pyams_default_theme/component/paragraph/html.py Mon Sep 28 15:50:58 2020 +0200 +++ b/src/pyams_default_theme/component/paragraph/html.py Fri Nov 13 13:23:00 2020 +0100 @@ -11,18 +11,27 @@ # from fanstatic import ConfigurationError +from persistent import Persistent +from zope.location import Location +from zope.schema.fieldproperty import FieldProperty from pyams_content.component.illustration import IIllustration +from pyams_content.component.links import InternalReferenceMixin from pyams_content.component.paragraph.interfaces.html import IHTMLParagraph, IRawParagraph from pyams_content.features.renderer.interfaces import IContentRenderer from pyams_default_theme import library +from pyams_default_theme.component.paragraph.interfaces.html import \ + IHTMLParagraphWithLogosRendererSettings from pyams_default_theme.features.renderer import BaseContentRenderer +from pyams_default_theme.shared.logo import DISABLED_LINK, INTERNAL_FIRST from pyams_skin.layer import IPyAMSLayer from pyams_template.template import template_config from pyams_utils.adapter import adapter_config, get_annotation_adapter +from pyams_utils.factory import factory_config from pyams_utils.fanstatic import ExternalResource from pyams_utils.interfaces.text import IHTMLRenderer from pyams_utils.pygments import IPygmentsCodeConfiguration, render_source +from pyams_utils.url import canonical_url, relative_url __docformat__ = 'restructuredtext' @@ -139,6 +148,7 @@ """HTML paragraph default renderer""" label = _("Default rich text renderer") + weight = 10 i18n_context_attrs = ('title', 'body',) @@ -152,3 +162,69 @@ renderer = self.illustration_renderer = self.illustration.get_renderer(self.request) if renderer is not None: renderer.update() + + +# +# HTML paragraph renderer with logos +# + +HTML_PARAGRAPH_WITH_LOGOS_RENDERER_SETTINGS_KEY = 'pyams_content.html.renderer:text-with-logos' + + +@factory_config(IHTMLParagraphWithLogosRendererSettings) +class HTMLParagraphWithLogosRendererSettings(Persistent, Location, InternalReferenceMixin): + """HTML paragraph with logos renderer settings""" + + reference = FieldProperty(IHTMLParagraphWithLogosRendererSettings['reference']) + position = FieldProperty(IHTMLParagraphWithLogosRendererSettings['position']) + target_priority = FieldProperty(IHTMLParagraphWithLogosRendererSettings['target_priority']) + force_canonical_url = FieldProperty(IHTMLParagraphWithLogosRendererSettings['force_canonical_url']) + + +@adapter_config(context=IHTMLParagraph, provides=IHTMLParagraphWithLogosRendererSettings) +def html_paragraph_with_logos_renderer_settings_factory(context): + """HTML paragraph with logos renderer settings factory""" + return get_annotation_adapter(context, HTML_PARAGRAPH_WITH_LOGOS_RENDERER_SETTINGS_KEY, + IHTMLParagraphWithLogosRendererSettings) + + +@adapter_config(name='text-with-logos', + context=(IHTMLParagraph, IPyAMSLayer), + provides=IContentRenderer) +@template_config(template='templates/html-logos.pt', layer=IPyAMSLayer) +class HTMLParagraphWithLogosRenderer(HTMLParagraphDefaultRenderer): + """HTML paragraph renderer with logos""" + + label = _("Rich text renderer with logos") + weight = 20 + + settings_interface = IHTMLParagraphWithLogosRendererSettings + + def get_internal_url(self, logo): + if logo is not None: + if self.settings.force_canonical_url: + url_getter = canonical_url + else: + url_getter = relative_url + return url_getter(logo, request=self.request) + return None + + @staticmethod + def get_external_url(logo): + return logo.url + + def get_logo_url(self): + priority = self.settings.target_priority + if priority == DISABLED_LINK: + return None + logo = self.settings.target + if logo is None: + return None + order = [self.get_external_url, self.get_internal_url] + if priority == INTERNAL_FIRST: + order = reversed(order) + for getter in order: + result = getter(logo) + if result is not None: + return result + return None diff -r 45eb6e5705c0 -r 43de10a58806 src/pyams_default_theme/component/paragraph/interfaces/html.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_default_theme/component/paragraph/interfaces/html.py Fri Nov 13 13:23:00 2020 +0100 @@ -0,0 +1,76 @@ +# +# Copyright (c) 2015-2020 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. +# + +"""PyAMS_default_theme.component module + +""" + +from zope.schema import Bool, Choice +from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary + +from pyams_content.shared.logo import LOGO_CONTENT_TYPE +from pyams_default_theme.shared.logo.interfaces import EXTERNAL_FIRST, TARGET_PRIORITY_VOCABULARY +from pyams_sequence.interfaces import IInternalReference +from pyams_sequence.schema import InternalReferenceField + + +__docformat__ = 'restructuredtext' + +from pyams_default_theme import _ + + +ABOVE_ALIGN = 'above' +LEFT_ALIGN = 'left' +RIGHT_ALIGN = 'right' +BELOW_ALIGN = 'below' + +LOGO_POSITION = ( + {'id': ABOVE_ALIGN, 'title': _("Centered above text")}, + {'id': LEFT_ALIGN, 'title': _("Left aligned (default)")}, + {'id': RIGHT_ALIGN, 'title': _("Right aligned")}, + {'id': BELOW_ALIGN, 'title': _("Centered below text")} +) + +LOGO_POSITION_VOCABULARY = SimpleVocabulary([SimpleTerm(item['id'], title=item['title']) + for item in LOGO_POSITION]) + + +class IHTMLParagraphWithLogosRendererSettings(IInternalReference): + """HTML paragraph with logos renderer settings interface""" + + reference = InternalReferenceField(title=_("Selected logo"), + description=_("Selected logo. You can " + "search a reference using '+' followed by " + "internal number, of by entering text " + "matching content title."), + content_type=LOGO_CONTENT_TYPE, + required=True) + + position = Choice(title=_("Logo position"), + required=True, + vocabulary=LOGO_POSITION_VOCABULARY, + default=LEFT_ALIGN) + + target_priority = Choice(title=_("Links priority"), + description=_("Order in which internal and external links are " + "evaluated on logo"), + required=True, + vocabulary=TARGET_PRIORITY_VOCABULARY, + default=EXTERNAL_FIRST) + + force_canonical_url = Bool(title=_("Force canonical URL"), + description=_("By default, internal links use a \"relative\" URL, " + "which tries to display link target in the current " + "context; by using a canonical URL, you can display " + "target in it's attachment context (if defined)"), + required=False, + default=False) diff -r 45eb6e5705c0 -r 43de10a58806 src/pyams_default_theme/component/paragraph/templates/html-logos.pt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_default_theme/component/paragraph/templates/html-logos.pt Fri Nov 13 13:23:00 2020 +0100 @@ -0,0 +1,83 @@ + + ${structure:renderer.render()} +

${title}

+ ${structure:renderer.render()} + + +
${structure:tales:html(view.body, 'oid_to_href;glossary')}
+
+ + + + +
+ ${structure:tales:html(view.body, 'oid_to_href;glossary')} +
+
+ +
+ +
+ ${structure:tales:html(view.body, 'oid_to_href;glossary')} +
+
+
+ +
+
+ ${structure:tales:html(view.body, 'oid_to_href;glossary')} +
+ +
+
+ +
+ ${structure:tales:html(view.body, 'oid_to_href;glossary')} +
+ +
+
+
+
+ ${structure:renderer.render()} +
+ ${structure:provider:pyams.associations} +