# HG changeset patch # User Thierry Florac # Date 1529053495 -7200 # Node ID 0297878871995a06c064e5d460224313912a15e0 # Parent 22a501f58d0674f96eea0c76c17fe748151ab86d Added navigation portlets diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/__init__.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,20 @@ +# +# 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' + + +# import standard library + +# import interfaces + +# import packages diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/__init__.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,20 @@ +# +# 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' + + +# import standard library + +# import interfaces + +# import packages diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/double.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/double.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,80 @@ +# +# 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' + + +# import standard library + +# import interfaces +from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY +from pyams_content.component.illustration.interfaces import IBasicIllustrationTarget +from pyams_content.features.menu.interfaces import IMenusContainer, IMenusContainerTarget +from pyams_content.features.menu.portlet.navigation.interfaces.double import IDoubleNavigationPortletSettings, \ + IDoubleNavigationMenu, IDoubleNavigationMenusContainer +from pyams_utils.interfaces import VIEW_PERMISSION +from zope.lifecycleevent.interfaces import IObjectAddedEvent + +# import packages +from pyams_content.features.menu import MenusContainer +from pyams_portal.portlet import PortletSettings, portlet_config, Portlet +from pyams_utils.adapter import get_annotation_adapter, adapter_config +from pyramid.events import subscriber +from zope.interface import implementer, alsoProvides +from zope.schema.fieldproperty import FieldProperty + +from pyams_content import _ + + +DOUBLE_NAVIGATION_PORTLET_NAME = 'pyams_content.portlet.navigation.double' +DOUBLE_NAVIGATION_LINKS_KEY = '{0}::menus'.format(ASSOCIATION_CONTAINER_KEY) + + +@implementer(IDoubleNavigationPortletSettings, IMenusContainerTarget) +class DoubleNavigationPortletSettings(PortletSettings): + """Double navigation portlet settings""" + + title = FieldProperty(IDoubleNavigationPortletSettings['title']) + subtitle = FieldProperty(IDoubleNavigationPortletSettings['subtitle']) + + @property + def menus(self): + return get_annotation_adapter(self, DOUBLE_NAVIGATION_LINKS_KEY, MenusContainer, + markers=IDoubleNavigationMenusContainer, name='++ass++menus') + + +@adapter_config(name='menus', context=IDoubleNavigationPortletSettings, provides=IMenusContainer) +def simple_navigation_links_adapter(context): + """Double navigation menus factory""" + return context.menus + + +@portlet_config(permission=VIEW_PERMISSION) +class DoubleNavigationPortlet(Portlet): + """Double navigation portlet""" + + name = DOUBLE_NAVIGATION_PORTLET_NAME + label = _("Double navigation") + + settings_class = DoubleNavigationPortletSettings + + +@subscriber(IObjectAddedEvent, parent_selector=IDoubleNavigationMenusContainer) +def handle_added_navigation_menu(event): + """Add marker interface to added menus container""" + alsoProvides(event.object, IDoubleNavigationMenu, IBasicIllustrationTarget) + + +@subscriber(IObjectAddedEvent, parent_selector=IDoubleNavigationMenu) +def handle_added_navigation_menu_link(event): + """Add marker interface to added menu link""" + alsoProvides(event.object, IBasicIllustrationTarget) diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/interfaces/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/interfaces/__init__.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,1 @@ +# diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/interfaces/double.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/interfaces/double.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,47 @@ +# +# 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' + + +# import standard library + +# import interfaces +from pyams_portal.interfaces import IPortletSettings + +# import packages +from pyams_i18n.schema import I18nTextLineField +from zope.interface import Interface, Attribute + +from pyams_content import _ + + +class IDoubleNavigationPortletSettings(IPortletSettings): + """Double navigation portlet settings interface""" + + title = I18nTextLineField(title=_("Title"), + description=_("Portlet main title"), + required=False) + + subtitle = I18nTextLineField(title=_("Subtitle"), + description=_("Portlet subtitle"), + required=False) + + menus = Attribute("Navigation menus") + + +class IDoubleNavigationMenusContainer(Interface): + """Double navigation menus container marker interface""" + + +class IDoubleNavigationMenu(Interface): + """Double navigation menu marker interface""" diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,43 @@ +# +# 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' + + +# import standard library + +# import interfaces +from pyams_portal.interfaces import IPortletSettings + +# import packages +from pyams_i18n.schema import I18nTextLineField +from zope.interface import Interface, Attribute + +from pyams_content import _ + + +class ISimpleNavigationPortletSettings(IPortletSettings): + """Simple navigation portlet settings interface""" + + title = I18nTextLineField(title=_("Title"), + description=_("Portlet main title"), + required=False) + + subtitle = I18nTextLineField(title=_("Subtitle"), + description=_("Portlet subtitle"), + required=False) + + links = Attribute("Navigation links") + + +class ISimpleNavigationMenu(Interface): + """Simple navigation menu marker interface""" diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/simple.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/simple.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,73 @@ +# +# 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' + + +# import standard library + +# import interfaces +from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY +from pyams_content.component.illustration import IBasicIllustrationTarget +from pyams_content.features.menu.interfaces import IMenuLinksContainer, IMenuLinksContainerTarget +from pyams_content.features.menu.portlet.navigation.interfaces.simple import ISimpleNavigationPortletSettings, \ + ISimpleNavigationMenu +from pyams_utils.interfaces import VIEW_PERMISSION +from zope.lifecycleevent.interfaces import IObjectAddedEvent + +# import packages +from pyams_content.features.menu import Menu +from pyams_portal.portlet import PortletSettings, portlet_config, Portlet +from pyams_utils.adapter import get_annotation_adapter, adapter_config +from pyramid.events import subscriber +from zope.interface import implementer, alsoProvides +from zope.schema.fieldproperty import FieldProperty + +from pyams_content import _ + + +SIMPLE_NAVIGATION_PORTLET_NAME = 'pyams_content.portlet.navigation.simple' +SIMPLE_NAVIGATION_LINKS_KEY = '{0}::links'.format(ASSOCIATION_CONTAINER_KEY) + + +@implementer(ISimpleNavigationPortletSettings, IMenuLinksContainerTarget) +class SimpleNavigationPortletSettings(PortletSettings): + """Simple navigation portlet settings""" + + title = FieldProperty(ISimpleNavigationPortletSettings['title']) + subtitle = FieldProperty(ISimpleNavigationPortletSettings['subtitle']) + + @property + def links(self): + return get_annotation_adapter(self, SIMPLE_NAVIGATION_LINKS_KEY, Menu, + markers=ISimpleNavigationMenu, name='++ass++links') + + +@adapter_config(name='links', context=ISimpleNavigationPortletSettings, provides=IMenuLinksContainer) +def simple_navigation_links_adapter(context): + """Simple navigation links factory""" + return context.links + + +@portlet_config(permission=VIEW_PERMISSION) +class SimpleNavigationPortlet(Portlet): + """Simple navigation portlet""" + + name = SIMPLE_NAVIGATION_PORTLET_NAME + label = _("Simple navigation") + + settings_class = SimpleNavigationPortletSettings + + +@subscriber(IObjectAddedEvent, parent_selector=ISimpleNavigationMenu) +def handle_added_navigation_link(event): + alsoProvides(event.object, IBasicIllustrationTarget) diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/zmi/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/zmi/__init__.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,20 @@ +# +# 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' + + +# import standard library + +# import interfaces + +# import packages diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/zmi/double.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/zmi/double.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,100 @@ +# +# 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' + + +# import standard library + +# import interfaces +from pyams_content.component.illustration.interfaces import IIllustration +from pyams_content.component.links.interfaces import IInternalLink +from pyams_content.features.menu.portlet.navigation.interfaces.double import IDoubleNavigationPortletSettings, \ + IDoubleNavigationMenu, IDoubleNavigationMenusContainer +from pyams_form.interfaces.form import IInnerSubForm +from pyams_pagelet.interfaces import IPagelet +from pyams_portal.interfaces import IPortletPreviewer +from pyams_skin.layer import IPyAMSLayer +from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION +from pyams_workflow.interfaces import IWorkflowPublicationInfo + +# import packages +from pyams_content.component.association.interfaces import IAssociationInfo +from pyams_content.features.menu.zmi import MenusTable, IMenusView, MenusView +from pyams_form.form import AJAXEditForm +from pyams_pagelet.pagelet import pagelet_config +from pyams_portal.portlet import PortletPreviewer +from pyams_portal.zmi.portlet import PortletSettingsEditor, PortletSettingsPropertiesEditor +from pyams_template.template import template_config +from pyams_utils.adapter import adapter_config +from zope.interface import alsoProvides, Interface + +from pyams_content import _ + + +@pagelet_config(name='properties.html', context=IDoubleNavigationPortletSettings, layer=IPyAMSLayer, + permission=VIEW_SYSTEM_PERMISSION) +class DoubleNavigationPortletSettingsEditor(PortletSettingsEditor): + """Double navigation portlet settings editor""" + + settings = IDoubleNavigationPortletSettings + + +@adapter_config(name='properties.json', context=(IDoubleNavigationPortletSettings, IPyAMSLayer), provides=IPagelet) +class DoubleNavigationPortletSettingsAJAXEditor(AJAXEditForm, DoubleNavigationPortletSettingsEditor): + """Double navigation portlet settings editor, JSON renderer""" + + +class DoubleNavigationPortletMenusTable(MenusTable): + """Double navigation portlet menus table""" + + associations_name = 'menus' + + +@adapter_config(name='double-navigation-menus', + context=(IDoubleNavigationPortletSettings, IPyAMSLayer, PortletSettingsPropertiesEditor), + provides=IInnerSubForm) +@adapter_config(name='++ass++menus', context=(IDoubleNavigationMenusContainer, IPyAMSLayer), provides=IMenusView) +class DoubleNavigationPortletLinksView(MenusView): + """Double navigation portlet menus view""" + + title = _("Navigation menus") + + table_class = DoubleNavigationPortletMenusTable + weight = 10 + + +@adapter_config(context=(Interface, IPyAMSLayer, Interface, IDoubleNavigationPortletSettings), + provides=IPortletPreviewer) +@template_config(template='templates/double-preview.pt', layer=IPyAMSLayer) +class DoubleNavigationPortletPreviewer(PortletPreviewer): + """Double navigation portlet previewer""" + + @classmethod + def get_link_info(cls, link): + return IAssociationInfo(link) + + @classmethod + def get_link_status(cls, link): + if not IInternalLink.providedBy(link): + return True + target = link.get_target() + return (target is not None) and IWorkflowPublicationInfo(target).is_published() + + @classmethod + def get_link_illustration(cls, link): + illustration = IIllustration(link, None) + if (illustration is None) or not illustration.has_data(): + if IInternalLink.providedBy(link): + target = link.get_target() + illustration = IIllustration(target) + return illustration diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/zmi/simple.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/zmi/simple.py Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,100 @@ +# +# 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' + + +# import standard library + +# import interfaces +from pyams_content.component.illustration.interfaces import IIllustration +from pyams_content.component.links.interfaces import IInternalLink +from pyams_content.features.menu.portlet.navigation.interfaces.simple import ISimpleNavigationPortletSettings, \ + ISimpleNavigationMenu +from pyams_form.interfaces.form import IInnerSubForm +from pyams_pagelet.interfaces import IPagelet +from pyams_portal.interfaces import IPortletPreviewer +from pyams_skin.layer import IPyAMSLayer +from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION +from pyams_workflow.interfaces import IWorkflowPublicationInfo + +# import packages +from pyams_content.component.association.interfaces import IAssociationInfo +from pyams_content.features.menu.zmi import LinksTable, IMenuLinksView, MenuLinksView +from pyams_form.form import AJAXEditForm +from pyams_pagelet.pagelet import pagelet_config +from pyams_portal.portlet import PortletPreviewer +from pyams_portal.zmi.portlet import PortletSettingsEditor, PortletSettingsPropertiesEditor +from pyams_template.template import template_config +from pyams_utils.adapter import adapter_config +from zope.interface import alsoProvides, Interface + +from pyams_content import _ + + +@pagelet_config(name='properties.html', context=ISimpleNavigationPortletSettings, layer=IPyAMSLayer, + permission=VIEW_SYSTEM_PERMISSION) +class SimpleNavigationPortletSettingsEditor(PortletSettingsEditor): + """Simple navigation portlet settings editor""" + + settings = ISimpleNavigationPortletSettings + + +@adapter_config(name='properties.json', context=(ISimpleNavigationPortletSettings, IPyAMSLayer), provides=IPagelet) +class SimpleNavigationPortletSettingsAJAXEditor(AJAXEditForm, SimpleNavigationPortletSettingsEditor): + """Simple navigation portlet settings editor, JSON renderer""" + + +class SimpleNavigationPortletLinksTable(LinksTable): + """Simple navigation portlet links table""" + + associations_name = 'links' + + +@adapter_config(name='simple-navigation-links', + context=(ISimpleNavigationPortletSettings, IPyAMSLayer, PortletSettingsPropertiesEditor), + provides=IInnerSubForm) +@adapter_config(name='++ass++links', context=(ISimpleNavigationMenu, IPyAMSLayer), provides=IMenuLinksView) +class SimpleNavigationPortletLinksView(MenuLinksView): + """Simple navigation portlet links view""" + + title = _("Navigation links") + + table_class = SimpleNavigationPortletLinksTable + weight = 10 + + +@adapter_config(context=(Interface, IPyAMSLayer, Interface, ISimpleNavigationPortletSettings), + provides=IPortletPreviewer) +@template_config(template='templates/simple-preview.pt', layer=IPyAMSLayer) +class SimpleNavigationPortletPreviewer(PortletPreviewer): + """Simple navigation portlet previewer""" + + @classmethod + def get_link_info(cls, link): + return IAssociationInfo(link) + + @classmethod + def get_link_status(cls, link): + if not IInternalLink.providedBy(link): + return True + target = link.get_target() + return (target is not None) and IWorkflowPublicationInfo(target).is_published() + + @classmethod + def get_link_illustration(cls, link): + illustration = IIllustration(link, None) + if (illustration is None) or not illustration.has_data(): + if IInternalLink.providedBy(link): + target = link.get_target() + illustration = IIllustration(target) + return illustration diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/zmi/templates/double-preview.pt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/zmi/templates/double-preview.pt Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,26 @@ +
+ Title + +
    +
  • + Title +
      +
    • + + + + User title + – + Inner title + +
    • +
    +
  • +
+
diff -r 22a501f58d06 -r 029787887199 src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt Fri Jun 15 11:04:55 2018 +0200 @@ -0,0 +1,21 @@ +
+ Title + +
    +
  • + + + + User title + – + Inner title + +
  • +
+