Converted "interfaces" package to Python module
authorThierry Florac <thierry.florac@onf.fr>
Tue, 06 Nov 2018 14:40:22 +0100
changeset 1059 34e6d07ea2e9
parent 1058 1fe028e17f70
child 1060 29b1aaf9e080
Converted "interfaces" package to Python module
src/pyams_content/component/association/interfaces.py
src/pyams_content/component/association/interfaces/__init__.py
src/pyams_content/component/extfile/interfaces.py
src/pyams_content/component/extfile/interfaces/__init__.py
src/pyams_content/component/gallery/interfaces.py
src/pyams_content/component/gallery/interfaces/__init__.py
src/pyams_content/component/illustration/interfaces.py
src/pyams_content/component/illustration/interfaces/__init__.py
src/pyams_content/component/keynumber/interfaces.py
src/pyams_content/component/keynumber/interfaces/__init__.py
src/pyams_content/component/keynumber/portlet/interfaces.py
src/pyams_content/component/keynumber/portlet/interfaces/__init__.py
src/pyams_content/component/links/interfaces.py
src/pyams_content/component/links/interfaces/__init__.py
src/pyams_content/component/paragraph/portlet/interfaces.py
src/pyams_content/component/paragraph/portlet/interfaces/__init__.py
src/pyams_content/component/theme/interfaces.py
src/pyams_content/component/theme/interfaces/__init__.py
src/pyams_content/component/video/interfaces.py
src/pyams_content/component/video/interfaces/__init__.py
src/pyams_content/features/footer/interfaces.py
src/pyams_content/features/footer/interfaces/__init__.py
src/pyams_content/features/header/interfaces.py
src/pyams_content/features/header/interfaces/__init__.py
src/pyams_content/features/menu/interfaces.py
src/pyams_content/features/menu/interfaces/__init__.py
src/pyams_content/features/redirect/interfaces.py
src/pyams_content/features/redirect/interfaces/__init__.py
src/pyams_content/features/renderer/interfaces.py
src/pyams_content/features/renderer/interfaces/__init__.py
src/pyams_content/profile/interfaces.py
src/pyams_content/profile/interfaces/__init__.py
src/pyams_content/reference/interfaces.py
src/pyams_content/reference/interfaces/__init__.py
src/pyams_content/reference/pictograms/interfaces.py
src/pyams_content/reference/pictograms/interfaces/__init__.py
src/pyams_content/root/interfaces.py
src/pyams_content/root/interfaces/__init__.py
src/pyams_content/shared/blog/interfaces.py
src/pyams_content/shared/blog/interfaces/__init__.py
src/pyams_content/shared/form/interfaces.py
src/pyams_content/shared/form/interfaces/__init__.py
src/pyams_content/shared/imagemap/interfaces.py
src/pyams_content/shared/imagemap/interfaces/__init__.py
src/pyams_content/shared/logo/interfaces.py
src/pyams_content/shared/logo/interfaces/__init__.py
src/pyams_content/shared/news/interfaces.py
src/pyams_content/shared/news/interfaces/__init__.py
src/pyams_content/shared/site/interfaces.py
src/pyams_content/shared/site/interfaces/__init__.py
src/pyams_content/shared/topic/interfaces.py
src/pyams_content/shared/topic/interfaces/__init__.py
src/pyams_content/shared/view/interfaces.py
src/pyams_content/shared/view/interfaces/__init__.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/association/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.paragraph.interfaces import IBaseParagraph
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.container.interfaces import IOrderedContainer
+
+# import packages
+from zope.container.constraints import containers, contains
+from zope.interface import Interface, Attribute
+from zope.schema import Bool, Choice
+
+from pyams_content import _
+
+
+ASSOCIATION_CONTAINER_KEY = 'pyams_content.associations'
+
+
+class IAssociationItem(IAttributeAnnotatable):
+    """Base association item interface"""
+
+    containers('.IAssociationContainer')
+
+    icon_class = Attribute("Icon class in associations list")
+    icon_hint = Attribute("Icon hint in associations list")
+
+    visible = Bool(title=_("Visible?"),
+                   description=_("Is this item visible in front-office?"),
+                   required=True,
+                   default=True)
+
+    def is_visible(self, request=None):
+        """Is association item published?"""
+
+    def get_url(self, request=None, view_name=None):
+        """Get link URL"""
+
+
+class IAssociationInfo(Interface):
+    """Association information interface"""
+
+    pictogram = Attribute("Association pictogram")
+
+    user_title = Attribute("Association title proposed on public site")
+
+    user_icon = Attribute("Iocn associated with user title")
+
+    inner_title = Attribute("Inner content, if available")
+
+    human_size = Attribute("Content size, if available")
+
+
+class IAssociationContainer(IOrderedContainer):
+    """Associations container interface"""
+
+    contains(IAssociationItem)
+
+    def append(self, value, notify=True):
+        """Append given value to container"""
+
+    def get_visible_items(self, request=None):
+        """Get list of visible items"""
+
+
+class IAssociationContainerTarget(IAttributeAnnotatable):
+    """Associations container target interface"""
+
+
+class IAssociationRenderer(Interface):
+    """Association renderer adapter interface"""
+
+
+#
+# Associations paragraph
+#
+
+ASSOCIATION_PARAGRAPH_TYPE = 'Associations'
+ASSOCIATION_PARAGRAPH_NAME = _("Associations")
+ASSOCIATION_PARAGRAPH_RENDERERS = 'PyAMS.associations.renderers'
+
+
+class IAssociationParagraph(IBaseParagraph):
+    """Associations paragraph interface"""
+
+    renderer = Choice(title=_("Associations template"),
+                      description=_("Presentation template used for associations"),
+                      vocabulary=ASSOCIATION_PARAGRAPH_RENDERERS,
+                      default='default')
--- a/src/pyams_content/component/association/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.component.paragraph.interfaces import IBaseParagraph
-from zope.annotation.interfaces import IAttributeAnnotatable
-from zope.container.interfaces import IOrderedContainer
-
-# import packages
-from zope.container.constraints import containers, contains
-from zope.interface import Interface, Attribute
-from zope.schema import Bool, Choice
-
-from pyams_content import _
-
-
-ASSOCIATION_CONTAINER_KEY = 'pyams_content.associations'
-
-
-class IAssociationItem(IAttributeAnnotatable):
-    """Base association item interface"""
-
-    containers('.IAssociationContainer')
-
-    icon_class = Attribute("Icon class in associations list")
-    icon_hint = Attribute("Icon hint in associations list")
-
-    visible = Bool(title=_("Visible?"),
-                   description=_("Is this item visible in front-office?"),
-                   required=True,
-                   default=True)
-
-    def is_visible(self, request=None):
-        """Is association item published?"""
-
-    def get_url(self, request=None, view_name=None):
-        """Get link URL"""
-
-
-class IAssociationInfo(Interface):
-    """Association information interface"""
-
-    pictogram = Attribute("Association pictogram")
-
-    user_title = Attribute("Association title proposed on public site")
-
-    user_icon = Attribute("Iocn associated with user title")
-
-    inner_title = Attribute("Inner content, if available")
-
-    human_size = Attribute("Content size, if available")
-
-
-class IAssociationContainer(IOrderedContainer):
-    """Associations container interface"""
-
-    contains(IAssociationItem)
-
-    def append(self, value, notify=True):
-        """Append given value to container"""
-
-    def get_visible_items(self, request=None):
-        """Get list of visible items"""
-
-
-class IAssociationContainerTarget(IAttributeAnnotatable):
-    """Associations container target interface"""
-
-
-class IAssociationRenderer(Interface):
-    """Association renderer adapter interface"""
-
-
-#
-# Associations paragraph
-#
-
-ASSOCIATION_PARAGRAPH_TYPE = 'Associations'
-ASSOCIATION_PARAGRAPH_NAME = _("Associations")
-ASSOCIATION_PARAGRAPH_RENDERERS = 'PyAMS.associations.renderers'
-
-
-class IAssociationParagraph(IBaseParagraph):
-    """Associations paragraph interface"""
-
-    renderer = Choice(title=_("Associations template"),
-                      description=_("Presentation template used for associations"),
-                      vocabulary=ASSOCIATION_PARAGRAPH_RENDERERS,
-                      default='default')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/extfile/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+from zope.schema import Choice, TextLine
+
+from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem
+from pyams_i18n.schema import I18nAudioField, I18nFileField, I18nTextField, I18nTextLineField, I18nThumbnailImageField, \
+    I18nVideoField
+
+from pyams_content import _
+
+
+EXTFILE_CONTAINER_KEY = 'pyams_content.extfile'
+EXTFILE_LINKS_CONTAINER_KEY = 'pyams_content.extfile.links'
+
+
+class IBaseExtFile(IAssociationItem):
+    """Base external file interface"""
+
+    title = I18nTextLineField(title=_("Download link label"),
+                              description=_("Label of download link, as shown in front-office"),
+                              required=False)
+
+    description = I18nTextField(title=_("Description"),
+                                description=_("File description displayed by front-office template"),
+                                required=False)
+
+    author = TextLine(title=_("Author"),
+                      description=_("Name of document's author"),
+                      required=False)
+
+    language = Choice(title=_("Language"),
+                      description=_("File's content language"),
+                      vocabulary="PyAMS base languages",
+                      required=False)
+
+    filename = TextLine(title=_("Save file as..."),
+                        description=_("Name under which the file will be saved"),
+                        required=False)
+
+
+class IExtFile(IBaseExtFile):
+    """Generic external file interface"""
+
+    data = I18nFileField(title=_("File data"),
+                         description=_("File content"),
+                         required=True)
+
+
+class IExtMedia(IExtFile):
+    """External media file interface"""
+
+
+class IExtImage(IExtMedia):
+    """External image file interface"""
+
+    data = I18nThumbnailImageField(title=_("Image data"),
+                                   description=_("Image content"),
+                                   required=True)
+
+
+class IExtVideo(IExtMedia):
+    """External video file interface"""
+
+    data = I18nVideoField(title=_("Video data"),
+                          description=_("Video content"),
+                          required=True)
+
+
+class IExtAudio(IExtMedia):
+    """External audio file interface"""
+
+    data = I18nAudioField(title=_("Audio data"),
+                          description=_("Audio file content"),
+                          required=True)
+
+
+class IExtFileContainerTarget(IAssociationContainerTarget):
+    """External files container marker interface"""
+
+
+#
+# External files management
+#
+
+EXTFILE_MANAGER_INFO_KEY = 'pyams_content.extfile.manager'
+
+
+class IExtFileManagerInfo(Interface):
+    """External file manager interface"""
+
+    default_title_prefix = I18nTextLineField(title=_("Default title prefix"),
+                                             description=_("If used, this prefix will be automatically added to "
+                                                           "download link's label of all files"),
+                                             required=False)
--- a/src/pyams_content/component/extfile/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-from zope.interface import Interface
-from zope.schema import Choice, TextLine
-
-from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem
-from pyams_i18n.schema import I18nAudioField, I18nFileField, I18nTextField, I18nTextLineField, I18nThumbnailImageField, \
-    I18nVideoField
-
-from pyams_content import _
-
-
-EXTFILE_CONTAINER_KEY = 'pyams_content.extfile'
-EXTFILE_LINKS_CONTAINER_KEY = 'pyams_content.extfile.links'
-
-
-class IBaseExtFile(IAssociationItem):
-    """Base external file interface"""
-
-    title = I18nTextLineField(title=_("Download link label"),
-                              description=_("Label of download link, as shown in front-office"),
-                              required=False)
-
-    description = I18nTextField(title=_("Description"),
-                                description=_("File description displayed by front-office template"),
-                                required=False)
-
-    author = TextLine(title=_("Author"),
-                      description=_("Name of document's author"),
-                      required=False)
-
-    language = Choice(title=_("Language"),
-                      description=_("File's content language"),
-                      vocabulary="PyAMS base languages",
-                      required=False)
-
-    filename = TextLine(title=_("Save file as..."),
-                        description=_("Name under which the file will be saved"),
-                        required=False)
-
-
-class IExtFile(IBaseExtFile):
-    """Generic external file interface"""
-
-    data = I18nFileField(title=_("File data"),
-                         description=_("File content"),
-                         required=True)
-
-
-class IExtMedia(IExtFile):
-    """External media file interface"""
-
-
-class IExtImage(IExtMedia):
-    """External image file interface"""
-
-    data = I18nThumbnailImageField(title=_("Image data"),
-                                   description=_("Image content"),
-                                   required=True)
-
-
-class IExtVideo(IExtMedia):
-    """External video file interface"""
-
-    data = I18nVideoField(title=_("Video data"),
-                          description=_("Video content"),
-                          required=True)
-
-
-class IExtAudio(IExtMedia):
-    """External audio file interface"""
-
-    data = I18nAudioField(title=_("Audio data"),
-                          description=_("Audio file content"),
-                          required=True)
-
-
-class IExtFileContainerTarget(IAssociationContainerTarget):
-    """External files container marker interface"""
-
-
-#
-# External files management
-#
-
-EXTFILE_MANAGER_INFO_KEY = 'pyams_content.extfile.manager'
-
-
-class IExtFileManagerInfo(Interface):
-    """External file manager interface"""
-
-    default_title_prefix = I18nTextLineField(title=_("Default title prefix"),
-                                             description=_("If used, this prefix will be automatically added to "
-                                                           "download link's label of all files"),
-                                             required=False)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/gallery/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,124 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.container.constraints import containers, contains
+from zope.container.interfaces import IOrderedContainer
+from zope.interface import Interface
+from zope.schema import Bool, Choice, TextLine
+
+from pyams_content.component.paragraph.interfaces import IBaseParagraph
+from pyams_content.features.renderer.interfaces import IRenderedContent
+from pyams_file.schema import AudioField, MediaField
+from pyams_i18n.schema import I18nTextField, I18nTextLineField
+
+from pyams_content import _
+
+
+GALLERY_CONTAINER_KEY = 'pyams_content.gallery'
+GALLERY_RENDERERS = 'PyAMS.gallery.renderers'
+
+
+class IGalleryItem(Interface):
+    """Gallery item base interface"""
+
+    containers('.IGallery')
+
+
+class IGalleryFile(IGalleryItem):
+    """Gallery file marker interface"""
+
+    data = MediaField(title=_("Image or video data"),
+                      description=_("Image or video content"),
+                      required=True)
+
+    title = I18nTextLineField(title=_("Legend"),
+                              required=False)
+
+    alt_title = I18nTextLineField(title=_("Accessibility title"),
+                                  description=_("Alternate title used to describe media content"),
+                                  required=False)
+
+    description = I18nTextField(title=_("Description"),
+                                required=False)
+
+    author = TextLine(title=_("Author"),
+                      description=_("Name of document's author"),
+                      required=True)
+
+    sound = AudioField(title=_("Audio data"),
+                       description=_("Sound file associated with the current media"),
+                       required=False)
+
+    sound_title = I18nTextLineField(title=_("Sound title"),
+                                    description=_("Title of associated sound file"),
+                                    required=False)
+
+    sound_description = I18nTextField(title=_("Sound description"),
+                                      description=_("Short description of associated sound file"),
+                                      required=False)
+
+    visible = Bool(title=_("Visible media?"),
+                   description=_("If 'no', this media won't be displayed in front office"),
+                   required=True,
+                   default=True)
+
+
+GALLERY_FILE_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible')
+
+
+class IBaseGallery(IOrderedContainer, IAttributeAnnotatable, IRenderedContent):
+    """Base gallery interface"""
+
+    renderer = Choice(title=_("Gallery template"),
+                      description=_("Presentation template used for this gallery"),
+                      vocabulary=GALLERY_RENDERERS,
+                      default='default')
+
+    def append(self, value, notify=True):
+        """Append new file to gallery
+
+        @param value: the media object to append
+        @param boolean notify: if 'False', the given value object is pre-located so that
+            adding events are not notified
+        """
+
+    def get_visible_medias(self):
+        """Get iterator over visible medias"""
+
+
+class IGallery(IBaseGallery):
+    """Gallery interface"""
+
+    contains(IGalleryItem)
+
+    title = I18nTextLineField(title=_("Title"),
+                              description=_("Gallery title, as shown in front-office"),
+                              required=False)
+
+    description = I18nTextField(title=_("Description"),
+                                description=_("Gallery description displayed by front-office template"),
+                                required=False)
+
+
+class IGalleryTarget(IAttributeAnnotatable):
+    """Gallery container target marker interface"""
+
+
+GALLERY_PARAGRAPH_TYPE = 'Gallery'
+GALLERY_PARAGRAPH_NAME = _("Medias gallery")
+
+
+class IGalleryParagraph(IBaseGallery, IBaseParagraph):
+    """Gallery paragraph"""
--- a/src/pyams_content/component/gallery/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-from zope.annotation.interfaces import IAttributeAnnotatable
-from zope.container.constraints import containers, contains
-from zope.container.interfaces import IOrderedContainer
-from zope.interface import Interface
-from zope.schema import Bool, Choice, TextLine
-
-from pyams_content.component.paragraph.interfaces import IBaseParagraph
-from pyams_content.features.renderer.interfaces import IRenderedContent
-from pyams_file.schema import AudioField, MediaField
-from pyams_i18n.schema import I18nTextField, I18nTextLineField
-
-from pyams_content import _
-
-
-GALLERY_CONTAINER_KEY = 'pyams_content.gallery'
-GALLERY_RENDERERS = 'PyAMS.gallery.renderers'
-
-
-class IGalleryItem(Interface):
-    """Gallery item base interface"""
-
-    containers('.IGallery')
-
-
-class IGalleryFile(IGalleryItem):
-    """Gallery file marker interface"""
-
-    data = MediaField(title=_("Image or video data"),
-                      description=_("Image or video content"),
-                      required=True)
-
-    title = I18nTextLineField(title=_("Legend"),
-                              required=False)
-
-    alt_title = I18nTextLineField(title=_("Accessibility title"),
-                                  description=_("Alternate title used to describe media content"),
-                                  required=False)
-
-    description = I18nTextField(title=_("Description"),
-                                required=False)
-
-    author = TextLine(title=_("Author"),
-                      description=_("Name of document's author"),
-                      required=True)
-
-    sound = AudioField(title=_("Audio data"),
-                       description=_("Sound file associated with the current media"),
-                       required=False)
-
-    sound_title = I18nTextLineField(title=_("Sound title"),
-                                    description=_("Title of associated sound file"),
-                                    required=False)
-
-    sound_description = I18nTextField(title=_("Sound description"),
-                                      description=_("Short description of associated sound file"),
-                                      required=False)
-
-    visible = Bool(title=_("Visible media?"),
-                   description=_("If 'no', this media won't be displayed in front office"),
-                   required=True,
-                   default=True)
-
-
-GALLERY_FILE_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible')
-
-
-class IBaseGallery(IOrderedContainer, IAttributeAnnotatable, IRenderedContent):
-    """Base gallery interface"""
-
-    renderer = Choice(title=_("Gallery template"),
-                      description=_("Presentation template used for this gallery"),
-                      vocabulary=GALLERY_RENDERERS,
-                      default='default')
-
-    def append(self, value, notify=True):
-        """Append new file to gallery
-
-        @param value: the media object to append
-        @param boolean notify: if 'False', the given value object is pre-located so that
-            adding events are not notified
-        """
-
-    def get_visible_medias(self):
-        """Get iterator over visible medias"""
-
-
-class IGallery(IBaseGallery):
-    """Gallery interface"""
-
-    contains(IGalleryItem)
-
-    title = I18nTextLineField(title=_("Title"),
-                              description=_("Gallery title, as shown in front-office"),
-                              required=False)
-
-    description = I18nTextField(title=_("Description"),
-                                description=_("Gallery description displayed by front-office template"),
-                                required=False)
-
-
-class IGalleryTarget(IAttributeAnnotatable):
-    """Gallery container target marker interface"""
-
-
-GALLERY_PARAGRAPH_TYPE = 'Gallery'
-GALLERY_PARAGRAPH_NAME = _("Medias gallery")
-
-
-class IGalleryParagraph(IBaseGallery, IBaseParagraph):
-    """Gallery paragraph"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/illustration/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,105 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.interface import Interface
+from zope.schema import Choice, TextLine
+
+from pyams_content import _
+from pyams_content.component.paragraph.interfaces import IBaseParagraph
+from pyams_content.features.renderer.interfaces import IRenderedContent
+from pyams_i18n.schema import I18nTextField, I18nTextLineField, I18nThumbnailMediaField
+
+
+#
+# Illustration
+#
+
+BASIC_ILLUSTRATION_KEY = 'pyams_content.illustration.base'
+
+ILLUSTRATION_KEY = 'pyams_content.illustration'
+ILLUSTRATION_RENDERERS = 'PyAMS.illustration.renderers'
+
+LINK_ILLUSTRATION_KEY = '{0}::link'.format(ILLUSTRATION_KEY)
+
+
+class IBasicIllustration(Interface):
+    """Basic illustration interface"""
+
+    data = I18nThumbnailMediaField(title=_("Image or video data"),
+                                   description=_("Image or video content"),
+                                   required=False)
+
+    def has_data(self):
+        """Check if data is provided in any language"""
+
+    title = I18nTextLineField(title=_("Legend"),
+                              required=False)
+
+    alt_title = I18nTextLineField(title=_("Accessibility title"),
+                                  description=_("Alternate title used to describe image content"),
+                                  required=False)
+
+    author = TextLine(title=_("Author"),
+                      description=_("Name of picture's author"),
+                      required=False)
+
+
+class IIllustration(IBasicIllustration, IRenderedContent):
+    """Illustration paragraph"""
+
+    description = I18nTextField(title=_("Associated text"),
+                                description=_("Illustration description displayed in front-office templates"),
+                                required=False)
+
+    renderer = Choice(title=_("Illustration template"),
+                      description=_("Presentation template used for illustration"),
+                      vocabulary=ILLUSTRATION_RENDERERS,
+                      default='default')
+
+
+class ILinkIllustration(IBasicIllustration):
+    """Navigation link illustration interface"""
+
+
+class IIllustrationTargetBase(IAttributeAnnotatable):
+    """Illustration target base interface"""
+
+
+class IBasicIllustrationTarget(IIllustrationTargetBase):
+    """Basic illustration target marker interface"""
+
+
+class IIllustrationTarget(IBasicIllustrationTarget):
+    """Illustration target interface"""
+
+
+class ILinkIllustrationTarget(IIllustrationTargetBase):
+    """Link illustration target interface"""
+
+
+#
+# Illustration paragraph
+#
+
+ILLUSTRATION_PARAGRAPH_TYPE = 'Illustration'
+ILLUSTRATION_PARAGRAPH_NAME = _("Illustration")
+
+
+class IIllustrationParagraph(IIllustration, IBaseParagraph):
+    """Illustration paragraph"""
+
+    data = I18nThumbnailMediaField(title=_("Image or video data"),
+                                   description=_("Image or video content"),
+                                   required=True)
--- a/src/pyams_content/component/illustration/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-from zope.annotation.interfaces import IAttributeAnnotatable
-from zope.interface import Interface
-from zope.schema import Choice, TextLine
-
-from pyams_content import _
-from pyams_content.component.paragraph.interfaces import IBaseParagraph
-from pyams_content.features.renderer.interfaces import IRenderedContent
-from pyams_i18n.schema import I18nTextField, I18nTextLineField, I18nThumbnailMediaField
-
-
-#
-# Illustration
-#
-
-BASIC_ILLUSTRATION_KEY = 'pyams_content.illustration.base'
-
-ILLUSTRATION_KEY = 'pyams_content.illustration'
-ILLUSTRATION_RENDERERS = 'PyAMS.illustration.renderers'
-
-LINK_ILLUSTRATION_KEY = '{0}::link'.format(ILLUSTRATION_KEY)
-
-
-class IBasicIllustration(Interface):
-    """Basic illustration interface"""
-
-    data = I18nThumbnailMediaField(title=_("Image or video data"),
-                                   description=_("Image or video content"),
-                                   required=False)
-
-    def has_data(self):
-        """Check if data is provided in any language"""
-
-    title = I18nTextLineField(title=_("Legend"),
-                              required=False)
-
-    alt_title = I18nTextLineField(title=_("Accessibility title"),
-                                  description=_("Alternate title used to describe image content"),
-                                  required=False)
-
-    author = TextLine(title=_("Author"),
-                      description=_("Name of picture's author"),
-                      required=False)
-
-
-class IIllustration(IBasicIllustration, IRenderedContent):
-    """Illustration paragraph"""
-
-    description = I18nTextField(title=_("Associated text"),
-                                description=_("Illustration description displayed in front-office templates"),
-                                required=False)
-
-    renderer = Choice(title=_("Illustration template"),
-                      description=_("Presentation template used for illustration"),
-                      vocabulary=ILLUSTRATION_RENDERERS,
-                      default='default')
-
-
-class ILinkIllustration(IBasicIllustration):
-    """Navigation link illustration interface"""
-
-
-class IIllustrationTargetBase(IAttributeAnnotatable):
-    """Illustration target base interface"""
-
-
-class IBasicIllustrationTarget(IIllustrationTargetBase):
-    """Basic illustration target marker interface"""
-
-
-class IIllustrationTarget(IBasicIllustrationTarget):
-    """Illustration target interface"""
-
-
-class ILinkIllustrationTarget(IIllustrationTargetBase):
-    """Link illustration target interface"""
-
-
-#
-# Illustration paragraph
-#
-
-ILLUSTRATION_PARAGRAPH_TYPE = 'Illustration'
-ILLUSTRATION_PARAGRAPH_NAME = _("Illustration")
-
-
-class IIllustrationParagraph(IIllustration, IBaseParagraph):
-    """Illustration paragraph"""
-
-    data = I18nThumbnailMediaField(title=_("Image or video data"),
-                                   description=_("Image or video content"),
-                                   required=True)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,97 @@
+#
+# 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'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.paragraph.interfaces import IBaseParagraph
+from pyams_content.interfaces.container import IOrderedContainer
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField
+from zope.container.constraints import containers, contains
+from zope.interface import Interface
+from zope.schema import Bool, TextLine, Choice
+
+from pyams_content import _
+
+
+KEYNUMBER_CONTAINER_KEY = 'pyams_content.keynumbers'
+
+
+class IKeyNumber(IAttributeAnnotatable):
+    """Base key number interface"""
+
+    containers('.IKeyNumberContainer')
+
+    visible = Bool(title=_("Visible?"),
+                   description=_("Is this key number visible in front-office?"),
+                   required=True,
+                   default=True)
+
+    label = I18nTextLineField(title=_('key-number-label', default="Header"),
+                              description=_("Small text to be displayed above number (according to selected "
+                                            "renderer)"),
+                              required=False)
+
+    number = TextLine(title=_("Number"),
+                      description=_("Key number value"),
+                      required=True)
+
+    unit = I18nTextLineField(title=_('key-number-unit', default="Unit"),
+                             description=_("Displayed unit"),
+                             required=False)
+
+    text = I18nTextLineField(title=_("Associated text"),
+                             description=_("The way this text will be rendered depends on presentation template"),
+                             required=False)
+
+
+KEYNUMBER_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible')
+
+
+class IKeyNumberContainer(IOrderedContainer):
+    """Key numbers container interface"""
+
+    contains(IKeyNumber)
+
+    def append(self, value, notify=True):
+        """Append given key number to container"""
+
+    def get_visible_items(self):
+        """Get list of visible key numbers"""
+
+
+class IKeyNumberContainerTarget(Interface):
+    """Key numbers container target interface"""
+
+
+KEYNUMBER_PARAGRAPH_TYPE = 'KeyNumbers'
+KEYNUMBER_PARAGRAPH_NAME = _("Key numbers")
+KEYNUMBER_PARAGRAPH_RENDERERS = 'PyAMS.keynumbers.renderers'
+
+
+#
+# KeyNumber paragraph
+#
+
+class IKeyNumberParagraph(IKeyNumberContainerTarget, IBaseParagraph):
+    """Key numbers paragraph interface"""
+
+    renderer = Choice(title=_("Key numbers template"),
+                      description=_("Presentation template used for key numbers"),
+                      vocabulary=KEYNUMBER_PARAGRAPH_RENDERERS,
+                      default='default')
--- a/src/pyams_content/component/keynumber/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-#
-# 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'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.component.paragraph.interfaces import IBaseParagraph
-from pyams_content.interfaces.container import IOrderedContainer
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-# import packages
-from pyams_i18n.schema import I18nTextLineField
-from zope.container.constraints import containers, contains
-from zope.interface import Interface
-from zope.schema import Bool, TextLine, Choice
-
-from pyams_content import _
-
-
-KEYNUMBER_CONTAINER_KEY = 'pyams_content.keynumbers'
-
-
-class IKeyNumber(IAttributeAnnotatable):
-    """Base key number interface"""
-
-    containers('.IKeyNumberContainer')
-
-    visible = Bool(title=_("Visible?"),
-                   description=_("Is this key number visible in front-office?"),
-                   required=True,
-                   default=True)
-
-    label = I18nTextLineField(title=_('key-number-label', default="Header"),
-                              description=_("Small text to be displayed above number (according to selected "
-                                            "renderer)"),
-                              required=False)
-
-    number = TextLine(title=_("Number"),
-                      description=_("Key number value"),
-                      required=True)
-
-    unit = I18nTextLineField(title=_('key-number-unit', default="Unit"),
-                             description=_("Displayed unit"),
-                             required=False)
-
-    text = I18nTextLineField(title=_("Associated text"),
-                             description=_("The way this text will be rendered depends on presentation template"),
-                             required=False)
-
-
-KEYNUMBER_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible')
-
-
-class IKeyNumberContainer(IOrderedContainer):
-    """Key numbers container interface"""
-
-    contains(IKeyNumber)
-
-    def append(self, value, notify=True):
-        """Append given key number to container"""
-
-    def get_visible_items(self):
-        """Get list of visible key numbers"""
-
-
-class IKeyNumberContainerTarget(Interface):
-    """Key numbers container target interface"""
-
-
-KEYNUMBER_PARAGRAPH_TYPE = 'KeyNumbers'
-KEYNUMBER_PARAGRAPH_NAME = _("Key numbers")
-KEYNUMBER_PARAGRAPH_RENDERERS = 'PyAMS.keynumbers.renderers'
-
-
-#
-# KeyNumber paragraph
-#
-
-class IKeyNumberParagraph(IKeyNumberContainerTarget, IBaseParagraph):
-    """Key numbers paragraph interface"""
-
-    renderer = Choice(title=_("Key numbers template"),
-                      description=_("Presentation template used for key numbers"),
-                      vocabulary=KEYNUMBER_PARAGRAPH_RENDERERS,
-                      default='default')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/portlet/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_portal.interfaces import IPortletSettings
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField, I18nTextField
+from zope.interface import Attribute, Interface
+
+from pyams_content import _
+
+
+class IKeyNumberPortletSettings(IPortletSettings):
+    """Key numbers portlet settings interface"""
+
+    title = I18nTextLineField(title=_("Title"),
+                              description=_("Portlet title"),
+                              required=False)
+
+    teaser = I18nTextField(title=_("Teaser"),
+                           description=_("Short text displayed above key numbers"),
+                           required=False)
+
+    links = Attribute("Navigation links")
+
+
+class IKeyNumberPortletMenu(Interface):
+    """Key numbers portlet menu marker interface"""
--- a/src/pyams_content/component/keynumber/portlet/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_portal.interfaces import IPortletSettings
-
-# import packages
-from pyams_i18n.schema import I18nTextLineField, I18nTextField
-from zope.interface import Attribute, Interface
-
-from pyams_content import _
-
-
-class IKeyNumberPortletSettings(IPortletSettings):
-    """Key numbers portlet settings interface"""
-
-    title = I18nTextLineField(title=_("Title"),
-                              description=_("Portlet title"),
-                              required=False)
-
-    teaser = I18nTextField(title=_("Teaser"),
-                           description=_("Short text displayed above key numbers"),
-                           required=False)
-
-    links = Attribute("Navigation links")
-
-
-class IKeyNumberPortletMenu(Interface):
-    """Key numbers portlet menu marker interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/links/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem
+from pyams_content.reference.pictograms.interfaces import SELECTED_PICTOGRAM_VOCABULARY
+from pyams_sequence.interfaces import IInternalReference
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField, I18nTextField
+from pyams_utils.schema import MailAddressField
+from zope.interface import Attribute
+from zope.schema import Choice, TextLine, URI
+
+from pyams_content import _
+
+
+class IBaseLink(IAssociationItem):
+    """Base link interface"""
+
+    title = I18nTextLineField(title=_("Alternate title"),
+                              description=_("Link title, as shown in front-office"),
+                              required=False)
+
+    description = I18nTextField(title=_("Description"),
+                                description=_("Link description displayed by front-office template"),
+                                required=False)
+
+    pictogram_name = Choice(title=_("Pictogram"),
+                            description=_("Name of the pictogram associated with this link"),
+                            required=False,
+                            vocabulary=SELECTED_PICTOGRAM_VOCABULARY)
+
+    pictogram = Attribute("Selected pictogram object")
+
+    def get_editor_url(self):
+        """Get URL for use in HTML editor"""
+
+
+class IInternalLink(IBaseLink, IInternalReference):
+    """Internal link interface"""
+
+
+class IExternalLink(IBaseLink):
+    """External link interface"""
+
+    url = URI(title=_("Target URL"),
+              description=_("URL used to access external resource"),
+              required=True)
+
+    language = Choice(title=_("Language"),
+                      description=_("Language used in this remote resource"),
+                      vocabulary='PyAMS base languages',
+                      required=False)
+
+
+class IMailtoLink(IBaseLink):
+    """Mailto link interface"""
+
+    address = MailAddressField(title=_("Target address"),
+                               description=_("Target email address"),
+                               required=True)
+
+    address_name = TextLine(title=_("Address name"),
+                            description=_("Address as displayed in address book"),
+                            required=True)
+
+
+class ILinkContainerTarget(IAssociationContainerTarget):
+    """Links container marker interface"""
--- a/src/pyams_content/component/links/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem
-from pyams_content.reference.pictograms.interfaces import SELECTED_PICTOGRAM_VOCABULARY
-from pyams_sequence.interfaces import IInternalReference
-
-# import packages
-from pyams_i18n.schema import I18nTextLineField, I18nTextField
-from pyams_utils.schema import MailAddressField
-from zope.interface import Attribute
-from zope.schema import Choice, TextLine, URI
-
-from pyams_content import _
-
-
-class IBaseLink(IAssociationItem):
-    """Base link interface"""
-
-    title = I18nTextLineField(title=_("Alternate title"),
-                              description=_("Link title, as shown in front-office"),
-                              required=False)
-
-    description = I18nTextField(title=_("Description"),
-                                description=_("Link description displayed by front-office template"),
-                                required=False)
-
-    pictogram_name = Choice(title=_("Pictogram"),
-                            description=_("Name of the pictogram associated with this link"),
-                            required=False,
-                            vocabulary=SELECTED_PICTOGRAM_VOCABULARY)
-
-    pictogram = Attribute("Selected pictogram object")
-
-    def get_editor_url(self):
-        """Get URL for use in HTML editor"""
-
-
-class IInternalLink(IBaseLink, IInternalReference):
-    """Internal link interface"""
-
-
-class IExternalLink(IBaseLink):
-    """External link interface"""
-
-    url = URI(title=_("Target URL"),
-              description=_("URL used to access external resource"),
-              required=True)
-
-    language = Choice(title=_("Language"),
-                      description=_("Language used in this remote resource"),
-                      vocabulary='PyAMS base languages',
-                      required=False)
-
-
-class IMailtoLink(IBaseLink):
-    """Mailto link interface"""
-
-    address = MailAddressField(title=_("Target address"),
-                               description=_("Target email address"),
-                               required=True)
-
-    address_name = TextLine(title=_("Address name"),
-                            description=_("Address as displayed in address book"),
-                            required=True)
-
-
-class ILinkContainerTarget(IAssociationContainerTarget):
-    """Links container marker interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/portlet/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,68 @@
+#
+# 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'
+
+
+# import standard library
+
+# import packages
+from zope.schema import Bool, Choice, List, Set
+
+from pyams_content import _
+# import interfaces
+from pyams_content.component.paragraph.interfaces import PARAGRAPH_FACTORIES_VOCABULARY
+from pyams_portal.interfaces import IPortletSettings
+
+
+class IParagraphContainerPortletSettings(IPortletSettings):
+    """Paragraphs container portlet settings interface"""
+
+    paragraphs = List(title=_("Selected paragraphs"),
+                      description=_("List of selected paragraphs; an empty selection means that "
+                                    "all paragraphs will be selectable by following filters; otherwise, "
+                                    "this selection will have priority"),
+                      value_type=Choice(vocabulary='PyAMS content paragraphs'),
+                      required=False)
+
+    factories = Set(title=_("Paragraph types"),
+                    description=_("Select list of paragraph types you want to include; an empty "
+                                  "selection means that all paragraphs types will be selected"),
+                    required=False,
+                    value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY))
+
+    anchors_only = Bool(title=_("Anchors only?"),
+                        description=_("If 'yes', only paragraphs set as 'anchors' will be selected"),
+                        required=True,
+                        default=False)
+
+
+class IParagraphNavigationPortletSettings(IPortletSettings):
+    """Paragraphs container navigation settings interface"""
+
+    paragraphs = List(title=_("Selected paragraphs"),
+                      description=_("List of paragraphs selected for navigation; an empty selection means that "
+                                    "all paragraphs will be selectable by following filters; otherwise, "
+                                    "this selection will have priority"),
+                      value_type=Choice(vocabulary='PyAMS content paragraphs'),
+                      required=False)
+
+    factories = Set(title=_("Paragraph types"),
+                    description=_("Select list of paragraph types you want to use for navigation; an empty "
+                                  "selection means that all paragraphs types will be selected"),
+                    required=False,
+                    value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY))
+
+    anchors_only = Bool(title=_("Anchors only?"),
+                        description=_("If 'no', all paragraphs will be used as navigation anchors"),
+                        required=True,
+                        default=True)
--- a/src/pyams_content/component/paragraph/portlet/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-#
-# 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'
-
-
-# import standard library
-
-# import packages
-from zope.schema import Bool, Choice, List, Set
-
-from pyams_content import _
-# import interfaces
-from pyams_content.component.paragraph.interfaces import PARAGRAPH_FACTORIES_VOCABULARY
-from pyams_portal.interfaces import IPortletSettings
-
-
-class IParagraphContainerPortletSettings(IPortletSettings):
-    """Paragraphs container portlet settings interface"""
-
-    paragraphs = List(title=_("Selected paragraphs"),
-                      description=_("List of selected paragraphs; an empty selection means that "
-                                    "all paragraphs will be selectable by following filters; otherwise, "
-                                    "this selection will have priority"),
-                      value_type=Choice(vocabulary='PyAMS content paragraphs'),
-                      required=False)
-
-    factories = Set(title=_("Paragraph types"),
-                    description=_("Select list of paragraph types you want to include; an empty "
-                                  "selection means that all paragraphs types will be selected"),
-                    required=False,
-                    value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY))
-
-    anchors_only = Bool(title=_("Anchors only?"),
-                        description=_("If 'yes', only paragraphs set as 'anchors' will be selected"),
-                        required=True,
-                        default=False)
-
-
-class IParagraphNavigationPortletSettings(IPortletSettings):
-    """Paragraphs container navigation settings interface"""
-
-    paragraphs = List(title=_("Selected paragraphs"),
-                      description=_("List of paragraphs selected for navigation; an empty selection means that "
-                                    "all paragraphs will be selectable by following filters; otherwise, "
-                                    "this selection will have priority"),
-                      value_type=Choice(vocabulary='PyAMS content paragraphs'),
-                      required=False)
-
-    factories = Set(title=_("Paragraph types"),
-                    description=_("Select list of paragraph types you want to use for navigation; an empty "
-                                  "selection means that all paragraphs types will be selected"),
-                    required=False,
-                    value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY))
-
-    anchors_only = Bool(title=_("Anchors only?"),
-                        description=_("If 'no', all paragraphs will be used as navigation anchors"),
-                        required=True,
-                        default=True)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/theme/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,165 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_thesaurus.interfaces.thesaurus import IThesaurusContextManager, IThesaurusContextManagerTarget
+
+# import packages
+from pyams_sequence.schema import InternalReferenceField
+from pyams_thesaurus.schema import ThesaurusTermsListField
+from zope.interface import Interface, invariant, Invalid
+from zope.schema import Bool
+
+from pyams_content import _
+
+
+#
+# Tags management
+#
+
+TAGS_MANAGER_KEY = 'pyams_content.tags.manager'
+TAGS_INFO_KEY = 'pyams_content.tags.info'
+
+
+class ITagsManager(IThesaurusContextManager):
+    """Tags manager interface"""
+
+    enable_tags_search = Bool(title=_("Enable search by tag?"),
+                              description=_("If 'yes', displayed tags will lead to a search engine "
+                                            "displaying contents matching given tag"),
+                              required=True,
+                              default=False)
+
+    tags_search_target = InternalReferenceField(title=_("Tags search target"),
+                                                description=_("Site or folder where tags search is displayed"),
+                                                required=False)
+
+    @invariant
+    def check_search_target(self):
+        if self.enable_tags_search and not self.tags_search_target:
+            raise Invalid(_("You must specify search target when activating search by tags!"))
+
+
+class ITagsManagerTarget(IThesaurusContextManagerTarget):
+    """Marker interface for tags manager"""
+
+
+class ITagsInfo(Interface):
+    """Tags information interface"""
+
+    tags = ThesaurusTermsListField(title=_("Tags"),
+                                   required=False)
+
+
+class ITagsTarget(Interface):
+    """Tags target interface"""
+
+
+PORTLET_SETTINGS_TAGS_KEY = 'pyams_content.portlet.tags.settings'
+
+
+class IPortletTagsSettings(Interface):
+    """Interface for portlet settings managing tags"""
+
+    tags = ThesaurusTermsListField(title=_("Tags"),
+                                   required=False)
+
+
+class IPortletTagsSettingsTarget(Interface):
+    """Marker interface for portlet settings managing tags"""
+
+
+#
+# Themes management
+#
+
+THEMES_MANAGER_KEY = 'pyams_content.themes.manager'
+THEMES_INFO_KEY = 'pyams_content.themes.info'
+
+
+class IThemesManager(IThesaurusContextManager):
+    """Themes manager interface"""
+
+
+class IThemesManagerTarget(IThesaurusContextManagerTarget):
+    """Marker interface for tools managing themes"""
+
+
+class IThemesInfo(Interface):
+    """Themes information interface"""
+
+    themes = ThesaurusTermsListField(title=_("Themes"),
+                                     required=False)
+
+
+class IThemesTarget(Interface):
+    """Themes target interface"""
+
+
+PORTLET_SETTINGS_THEMES_KEY = 'pyams_content.portlet.themes.settings'
+
+
+class IPortletThemesSettings(Interface):
+    """Interface for portlet settings managing themes"""
+
+    themes = ThesaurusTermsListField(title=_("Themes"),
+                                     required=False)
+
+
+class IPortletThemesSettingsTarget(Interface):
+    """Marker interface for portlet settings managing themes"""
+
+
+#
+# Collections management
+#
+
+COLLECTIONS_MANAGER_KEY = 'pyams_content.collections.manager'
+COLLECTIONS_INFO_KEY = 'pyams_content.collections.info'
+
+
+class ICollectionsManager(IThesaurusContextManager):
+    """Collections manager interface"""
+
+
+class ICollectionsManagerTarget(IThesaurusContextManagerTarget):
+    """Marker interface for tools managing collections"""
+
+
+class ICollectionsInfo(Interface):
+    """Collections information interface"""
+
+    collections = ThesaurusTermsListField(title=_("Collections"),
+                                          required=False)
+
+
+class ICollectionsTarget(Interface):
+    """Collections target interface"""
+
+
+PORTLET_SETTINGS_COLLECTIONS_KEY = 'pyams_content.portlet.collections.settings'
+
+
+class IPortletCollectionsSettings(Interface):
+    """Interface for portlet settings managing collections"""
+
+    collections = ThesaurusTermsListField(title=_("Collections"),
+                                          required=False)
+
+
+class IPortletCollectionsSettingsTarget(Interface):
+    """Marker interface for portlet settings managing collections"""
--- a/src/pyams_content/component/theme/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_thesaurus.interfaces.thesaurus import IThesaurusContextManager, IThesaurusContextManagerTarget
-
-# import packages
-from pyams_sequence.schema import InternalReferenceField
-from pyams_thesaurus.schema import ThesaurusTermsListField
-from zope.interface import Interface, invariant, Invalid
-from zope.schema import Bool
-
-from pyams_content import _
-
-
-#
-# Tags management
-#
-
-TAGS_MANAGER_KEY = 'pyams_content.tags.manager'
-TAGS_INFO_KEY = 'pyams_content.tags.info'
-
-
-class ITagsManager(IThesaurusContextManager):
-    """Tags manager interface"""
-
-    enable_tags_search = Bool(title=_("Enable search by tag?"),
-                              description=_("If 'yes', displayed tags will lead to a search engine "
-                                            "displaying contents matching given tag"),
-                              required=True,
-                              default=False)
-
-    tags_search_target = InternalReferenceField(title=_("Tags search target"),
-                                                description=_("Site or folder where tags search is displayed"),
-                                                required=False)
-
-    @invariant
-    def check_search_target(self):
-        if self.enable_tags_search and not self.tags_search_target:
-            raise Invalid(_("You must specify search target when activating search by tags!"))
-
-
-class ITagsManagerTarget(IThesaurusContextManagerTarget):
-    """Marker interface for tags manager"""
-
-
-class ITagsInfo(Interface):
-    """Tags information interface"""
-
-    tags = ThesaurusTermsListField(title=_("Tags"),
-                                   required=False)
-
-
-class ITagsTarget(Interface):
-    """Tags target interface"""
-
-
-PORTLET_SETTINGS_TAGS_KEY = 'pyams_content.portlet.tags.settings'
-
-
-class IPortletTagsSettings(Interface):
-    """Interface for portlet settings managing tags"""
-
-    tags = ThesaurusTermsListField(title=_("Tags"),
-                                   required=False)
-
-
-class IPortletTagsSettingsTarget(Interface):
-    """Marker interface for portlet settings managing tags"""
-
-
-#
-# Themes management
-#
-
-THEMES_MANAGER_KEY = 'pyams_content.themes.manager'
-THEMES_INFO_KEY = 'pyams_content.themes.info'
-
-
-class IThemesManager(IThesaurusContextManager):
-    """Themes manager interface"""
-
-
-class IThemesManagerTarget(IThesaurusContextManagerTarget):
-    """Marker interface for tools managing themes"""
-
-
-class IThemesInfo(Interface):
-    """Themes information interface"""
-
-    themes = ThesaurusTermsListField(title=_("Themes"),
-                                     required=False)
-
-
-class IThemesTarget(Interface):
-    """Themes target interface"""
-
-
-PORTLET_SETTINGS_THEMES_KEY = 'pyams_content.portlet.themes.settings'
-
-
-class IPortletThemesSettings(Interface):
-    """Interface for portlet settings managing themes"""
-
-    themes = ThesaurusTermsListField(title=_("Themes"),
-                                     required=False)
-
-
-class IPortletThemesSettingsTarget(Interface):
-    """Marker interface for portlet settings managing themes"""
-
-
-#
-# Collections management
-#
-
-COLLECTIONS_MANAGER_KEY = 'pyams_content.collections.manager'
-COLLECTIONS_INFO_KEY = 'pyams_content.collections.info'
-
-
-class ICollectionsManager(IThesaurusContextManager):
-    """Collections manager interface"""
-
-
-class ICollectionsManagerTarget(IThesaurusContextManagerTarget):
-    """Marker interface for tools managing collections"""
-
-
-class ICollectionsInfo(Interface):
-    """Collections information interface"""
-
-    collections = ThesaurusTermsListField(title=_("Collections"),
-                                          required=False)
-
-
-class ICollectionsTarget(Interface):
-    """Collections target interface"""
-
-
-PORTLET_SETTINGS_COLLECTIONS_KEY = 'pyams_content.portlet.collections.settings'
-
-
-class IPortletCollectionsSettings(Interface):
-    """Interface for portlet settings managing collections"""
-
-    collections = ThesaurusTermsListField(title=_("Collections"),
-                                          required=False)
-
-
-class IPortletCollectionsSettingsTarget(Interface):
-    """Marker interface for portlet settings managing collections"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/video/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,79 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from zope.annotation import IAttributeAnnotatable
+from zope.contentprovider.interfaces import IContentProvider
+from zope.interface import Interface, Attribute
+from zope.schema import Choice, TextLine
+
+from pyams_content import _
+from pyams_content.component.paragraph.interfaces import IBaseParagraph
+from pyams_i18n.schema import I18nTextField, I18nTextLineField
+
+
+class IExternalVideoSettings(Interface):
+    """External video settings"""
+
+    video_id = Attribute("Video ID")
+
+
+class IExternalVideoProvider(Interface):
+    """External video provider"""
+
+    label = Attribute("Video provider label")
+    weight = Attribute("Video provider weight (used for ordering)")
+    settings_interface = Attribute("Video provider settings interface")
+
+
+class IExternalVideo(IAttributeAnnotatable):
+    """Base interface for external video integration"""
+
+    author = TextLine(title=_("Author"),
+                      description=_("Name of document's author"),
+                      required=True)
+
+    description = I18nTextField(title=_("Associated text"),
+                                description=_("Video description displayed by front-office template"),
+                                required=False)
+
+    provider_name = Choice(title=_("Video provider"),
+                           description=_("Name of external platform providing selected video"),
+                           required=False,
+                           vocabulary="PyAMS video providers")
+
+    def get_provider(self):
+        """Get external video provider utility"""
+
+    settings = Attribute("Video settings")
+
+
+EXTERNAL_VIDEO_PARAGRAPH_TYPE = 'External video'
+EXTERNAL_VIDEO_PARAGRAPH_NAME = _("External video")
+EXTERNAL_VIDEO_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.video.renderers'
+
+
+class IExternalVideoParagraph(IExternalVideo, IBaseParagraph):
+    """External video paragraph"""
+
+    title = I18nTextLineField(title=_("Legend"),
+                              required=False)
+
+    renderer = Choice(title=_("Video template"),
+                      description=_("Presentation template used for this video"),
+                      vocabulary=EXTERNAL_VIDEO_PARAGRAPH_RENDERERS,
+                      default='default')
+
+
+class IExternalVideoRenderer(IContentProvider):
+    """External video renderer"""
--- a/src/pyams_content/component/video/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-from zope.annotation import IAttributeAnnotatable
-from zope.contentprovider.interfaces import IContentProvider
-from zope.interface import Interface, Attribute
-from zope.schema import Choice, TextLine
-
-from pyams_content import _
-from pyams_content.component.paragraph.interfaces import IBaseParagraph
-from pyams_i18n.schema import I18nTextField, I18nTextLineField
-
-
-class IExternalVideoSettings(Interface):
-    """External video settings"""
-
-    video_id = Attribute("Video ID")
-
-
-class IExternalVideoProvider(Interface):
-    """External video provider"""
-
-    label = Attribute("Video provider label")
-    weight = Attribute("Video provider weight (used for ordering)")
-    settings_interface = Attribute("Video provider settings interface")
-
-
-class IExternalVideo(IAttributeAnnotatable):
-    """Base interface for external video integration"""
-
-    author = TextLine(title=_("Author"),
-                      description=_("Name of document's author"),
-                      required=True)
-
-    description = I18nTextField(title=_("Associated text"),
-                                description=_("Video description displayed by front-office template"),
-                                required=False)
-
-    provider_name = Choice(title=_("Video provider"),
-                           description=_("Name of external platform providing selected video"),
-                           required=False,
-                           vocabulary="PyAMS video providers")
-
-    def get_provider(self):
-        """Get external video provider utility"""
-
-    settings = Attribute("Video settings")
-
-
-EXTERNAL_VIDEO_PARAGRAPH_TYPE = 'External video'
-EXTERNAL_VIDEO_PARAGRAPH_NAME = _("External video")
-EXTERNAL_VIDEO_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.video.renderers'
-
-
-class IExternalVideoParagraph(IExternalVideo, IBaseParagraph):
-    """External video paragraph"""
-
-    title = I18nTextLineField(title=_("Legend"),
-                              required=False)
-
-    renderer = Choice(title=_("Video template"),
-                      description=_("Presentation template used for this video"),
-                      vocabulary=EXTERNAL_VIDEO_PARAGRAPH_RENDERERS,
-                      default='default')
-
-
-class IExternalVideoRenderer(IContentProvider):
-    """External video renderer"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/footer/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,61 @@
+#
+# 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'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.features.renderer.interfaces import IRenderedContent, IContentRenderer, IRendererSettings
+from pyams_utils.interfaces.inherit import IInheritInfo
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from zope.interface import Attribute
+from zope.schema import Choice
+
+from pyams_content import _
+
+
+FOOTER_SETTINGS_KEY = 'pyams_content.footer'
+FOOTER_RENDERER_SETTINGS_KEY = 'pyams_content.footer::{0}'
+
+FOOTER_RENDERERS = 'PyAMS.footer.renderers'
+
+
+class IFooterSettings(IInheritInfo, IRenderedContent):
+    """Footer settings interface"""
+
+    renderer = Choice(title=_("Footer template"),
+                      description=_("Presentation template used for this footer"),
+                      vocabulary=FOOTER_RENDERERS,
+                      required=False,
+                      default='hidden')
+
+    settings = Attribute("Renderer settings")
+
+
+class IFooterTarget(IAttributeAnnotatable):
+    """Footer target marker interface"""
+
+
+class IFooterRenderer(IContentRenderer):
+    """Footer renderer interface"""
+
+    name = Attribute("Renderer name")
+    settings_key = Attribute("Renderer settings key")
+    cache_key = Attribute("Renderer cache key")
+
+
+class IFooterRendererSettings(IRendererSettings):
+    """Footer renderer settings interface"""
--- a/src/pyams_content/features/footer/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#
-# 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'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.features.renderer.interfaces import IRenderedContent, IContentRenderer, IRendererSettings
-from pyams_utils.interfaces.inherit import IInheritInfo
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-# import packages
-from zope.interface import Attribute
-from zope.schema import Choice
-
-from pyams_content import _
-
-
-FOOTER_SETTINGS_KEY = 'pyams_content.footer'
-FOOTER_RENDERER_SETTINGS_KEY = 'pyams_content.footer::{0}'
-
-FOOTER_RENDERERS = 'PyAMS.footer.renderers'
-
-
-class IFooterSettings(IInheritInfo, IRenderedContent):
-    """Footer settings interface"""
-
-    renderer = Choice(title=_("Footer template"),
-                      description=_("Presentation template used for this footer"),
-                      vocabulary=FOOTER_RENDERERS,
-                      required=False,
-                      default='hidden')
-
-    settings = Attribute("Renderer settings")
-
-
-class IFooterTarget(IAttributeAnnotatable):
-    """Footer target marker interface"""
-
-
-class IFooterRenderer(IContentRenderer):
-    """Footer renderer interface"""
-
-    name = Attribute("Renderer name")
-    settings_key = Attribute("Renderer settings key")
-    cache_key = Attribute("Renderer cache key")
-
-
-class IFooterRendererSettings(IRendererSettings):
-    """Footer renderer settings interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/header/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,61 @@
+#
+# 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'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.features.renderer import IContentRenderer, IRendererSettings, IRenderedContent
+from pyams_utils.interfaces.inherit import IInheritInfo
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from zope.interface import Attribute
+from zope.schema import Choice
+
+from pyams_content import _
+
+
+HEADER_SETTINGS_KEY = 'pyams_content.header'
+HEADER_RENDERER_SETTINGS_KEY = 'pyams_content.header::{0}'
+
+HEADER_RENDERERS = 'PyAMS.header.renderers'
+
+
+class IHeaderSettings(IInheritInfo, IRenderedContent):
+    """Header settings interface"""
+
+    renderer = Choice(title=_("Header template"),
+                      description=_("Presentation template used for this header"),
+                      vocabulary=HEADER_RENDERERS,
+                      required=False,
+                      default='hidden')
+
+    settings = Attribute("Renderer settings")
+
+
+class IHeaderTarget(IAttributeAnnotatable):
+    """Header target marker interface"""
+
+
+class IHeaderRenderer(IContentRenderer):
+    """Header renderer interface"""
+
+    name = Attribute("Renderer name")
+    settings_key = Attribute("Renderer settings key")
+    cache_key = Attribute("Renderer cache key")
+
+
+class IHeaderRendererSettings(IRendererSettings):
+    """Header renderer settings interface"""
--- a/src/pyams_content/features/header/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#
-# 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'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.features.renderer import IContentRenderer, IRendererSettings, IRenderedContent
-from pyams_utils.interfaces.inherit import IInheritInfo
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-# import packages
-from zope.interface import Attribute
-from zope.schema import Choice
-
-from pyams_content import _
-
-
-HEADER_SETTINGS_KEY = 'pyams_content.header'
-HEADER_RENDERER_SETTINGS_KEY = 'pyams_content.header::{0}'
-
-HEADER_RENDERERS = 'PyAMS.header.renderers'
-
-
-class IHeaderSettings(IInheritInfo, IRenderedContent):
-    """Header settings interface"""
-
-    renderer = Choice(title=_("Header template"),
-                      description=_("Presentation template used for this header"),
-                      vocabulary=HEADER_RENDERERS,
-                      required=False,
-                      default='hidden')
-
-    settings = Attribute("Renderer settings")
-
-
-class IHeaderTarget(IAttributeAnnotatable):
-    """Header target marker interface"""
-
-
-class IHeaderRenderer(IContentRenderer):
-    """Header renderer interface"""
-
-    name = Attribute("Renderer name")
-    settings_key = Attribute("Renderer settings key")
-    cache_key = Attribute("Renderer cache key")
-
-
-class IHeaderRendererSettings(IRendererSettings):
-    """Header renderer settings interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,83 @@
+#
+# 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.container.constraints import containers, contains
+from zope.interface import Attribute, Interface
+from zope.schema import Bool, Choice
+
+from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationContainerTarget
+from pyams_content.reference.pictograms.interfaces import SELECTED_PICTOGRAM_VOCABULARY
+from pyams_i18n.schema import I18nTextLineField
+from pyams_sequence.interfaces import IInternalReference
+from pyams_sequence.schema import InternalReferenceField
+
+from pyams_content import _
+
+
+class IMenuLink(Interface):
+    """Menu link marker interface"""
+
+
+class IMenuInternalLink(IMenuLink):
+    """Menu internal link marker interface"""
+
+
+class IMenuExternalLink(IMenuLink):
+    """Menu external link marker interface"""
+
+
+class IMenuLinksContainer(IAssociationContainer):
+    """Menu links container interface"""
+
+    contains(IMenuLink)
+
+
+class IMenuLinksContainerTarget(IAssociationContainerTarget):
+    """Menu links container marker interface"""
+
+
+class IMenu(IMenuLinksContainer, IInternalReference):
+    """Menu container interface"""
+
+    containers('.IMenusContainer')
+
+    visible = Bool(title=_("Visible?"),
+                   description=_("Is this item visible in front-office?"),
+                   required=True,
+                   default=True)
+
+    title = I18nTextLineField(title=_("Menu title"),
+                              description=_("Displayed menu label"),
+                              required=True)
+
+    reference = InternalReferenceField(title=_("Internal reference"),
+                                       description=_("Direct reference to menu target"),
+                                       required=False)
+
+    pictogram_name = Choice(title=_("Pictogram"),
+                            description=_("Name of the pictogram associated with this menu"),
+                            required=False,
+                            vocabulary=SELECTED_PICTOGRAM_VOCABULARY)
+
+    pictogram = Attribute("Pictogram object reference")
+
+
+class IMenusContainer(IAssociationContainer):
+    """Menus container interface"""
+
+    contains(IMenu)
+
+
+class IMenusContainerTarget(IAssociationContainerTarget):
+    """Menus container target marker interface"""
--- a/src/pyams_content/features/menu/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-#
-# 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.container.constraints import containers, contains
-from zope.interface import Attribute, Interface
-from zope.schema import Bool, Choice
-
-from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationContainerTarget
-from pyams_content.reference.pictograms.interfaces import SELECTED_PICTOGRAM_VOCABULARY
-from pyams_i18n.schema import I18nTextLineField
-from pyams_sequence.interfaces import IInternalReference
-from pyams_sequence.schema import InternalReferenceField
-
-from pyams_content import _
-
-
-class IMenuLink(Interface):
-    """Menu link marker interface"""
-
-
-class IMenuInternalLink(IMenuLink):
-    """Menu internal link marker interface"""
-
-
-class IMenuExternalLink(IMenuLink):
-    """Menu external link marker interface"""
-
-
-class IMenuLinksContainer(IAssociationContainer):
-    """Menu links container interface"""
-
-    contains(IMenuLink)
-
-
-class IMenuLinksContainerTarget(IAssociationContainerTarget):
-    """Menu links container marker interface"""
-
-
-class IMenu(IMenuLinksContainer, IInternalReference):
-    """Menu container interface"""
-
-    containers('.IMenusContainer')
-
-    visible = Bool(title=_("Visible?"),
-                   description=_("Is this item visible in front-office?"),
-                   required=True,
-                   default=True)
-
-    title = I18nTextLineField(title=_("Menu title"),
-                              description=_("Displayed menu label"),
-                              required=True)
-
-    reference = InternalReferenceField(title=_("Internal reference"),
-                                       description=_("Direct reference to menu target"),
-                                       required=False)
-
-    pictogram_name = Choice(title=_("Pictogram"),
-                            description=_("Name of the pictogram associated with this menu"),
-                            required=False,
-                            vocabulary=SELECTED_PICTOGRAM_VOCABULARY)
-
-    pictogram = Attribute("Pictogram object reference")
-
-
-class IMenusContainer(IAssociationContainer):
-    """Menus container interface"""
-
-    contains(IMenu)
-
-
-class IMenusContainerTarget(IAssociationContainerTarget):
-    """Menus container target marker interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/redirect/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,102 @@
+#
+# 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'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.interfaces.container import IOrderedContainer
+from pyams_sequence.interfaces import IInternalReference
+
+# import packages
+from pyams_sequence.schema import InternalReferenceField
+from zope.container.constraints import contains, containers
+from zope.interface import Interface, Attribute, invariant, Invalid
+from zope.schema import Bool, TextLine
+
+from pyams_content import _
+
+
+REDIRECT_MANAGER_KEY = 'pyams_content.redirect'
+
+
+class IRedirectionRule(IInternalReference):
+    """Redirection rule interface"""
+
+    containers('.IRedirectManager')
+
+    active = Bool(title=_("Active rule?"),
+                  description=_("If 'no', selected rule is inactive"),
+                  required=True,
+                  default=False)
+
+    chained = Bool(title=_("Chained rule?"),
+                   description=_("If 'no', and if this rule is matching received request URL, the rule "
+                                 "returns a redirection response; otherwise, the rule just rewrites the "
+                                 "input URL which is forwarded to the next rule"),
+                   required=True,
+                   default=False)
+
+    permanent = Bool(title=_("Permanent redirect?"),
+                     description=_("Define if this redirection should be permanent or temporary"),
+                     required=True,
+                     default=True)
+
+    url_pattern = TextLine(title=_("URL pattern"),
+                           description=_("Regexp pattern of matching URLs for this redirection rule"),
+                           required=True)
+
+    pattern = Attribute("Compiled URL pattern")
+
+    reference = InternalReferenceField(title=_("Internal redirection target"),
+                                       description=_("Internal redirection reference. You can search a reference using "
+                                                     "'+' followed by internal number, of by entering text matching "
+                                                     "content title."),
+                                       required=False)
+
+    target_url = TextLine(title=_("Target URL"),
+                          description=_("URL to which source URL should be redirected"),
+                          required=False)
+
+    @invariant
+    def check_reference_and_target(self):
+        if self.reference and self.target_url:
+            raise Invalid(_("You can only provide an internal reference OR a target URL"))
+        elif not (self.reference or self.target_url):
+            raise Invalid(_("You must provide an internal reference OR a target URL"))
+
+    def match(self, source_url):
+        """Return regexp URL match on given URL"""
+
+    def rewrite(self, source_url, request):
+        """Rewrite given source URL"""
+
+
+class IRedirectionManager(IOrderedContainer):
+    """Redirection manager"""
+
+    contains(IRedirectionRule)
+
+    def get_active_items(self):
+        """Get iterator over active items"""
+
+    def get_response(self, request):
+        """Get new response for given request"""
+
+    def test_rules(self, source_url, request, check_inactive_rules=False):
+        """Test rules against given URL"""
+
+
+class IRedirectionManagerTarget(Interface):
+    """Redirection manager target marker interface"""
--- a/src/pyams_content/features/redirect/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-#
-# 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'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.interfaces.container import IOrderedContainer
-from pyams_sequence.interfaces import IInternalReference
-
-# import packages
-from pyams_sequence.schema import InternalReferenceField
-from zope.container.constraints import contains, containers
-from zope.interface import Interface, Attribute, invariant, Invalid
-from zope.schema import Bool, TextLine
-
-from pyams_content import _
-
-
-REDIRECT_MANAGER_KEY = 'pyams_content.redirect'
-
-
-class IRedirectionRule(IInternalReference):
-    """Redirection rule interface"""
-
-    containers('.IRedirectManager')
-
-    active = Bool(title=_("Active rule?"),
-                  description=_("If 'no', selected rule is inactive"),
-                  required=True,
-                  default=False)
-
-    chained = Bool(title=_("Chained rule?"),
-                   description=_("If 'no', and if this rule is matching received request URL, the rule "
-                                 "returns a redirection response; otherwise, the rule just rewrites the "
-                                 "input URL which is forwarded to the next rule"),
-                   required=True,
-                   default=False)
-
-    permanent = Bool(title=_("Permanent redirect?"),
-                     description=_("Define if this redirection should be permanent or temporary"),
-                     required=True,
-                     default=True)
-
-    url_pattern = TextLine(title=_("URL pattern"),
-                           description=_("Regexp pattern of matching URLs for this redirection rule"),
-                           required=True)
-
-    pattern = Attribute("Compiled URL pattern")
-
-    reference = InternalReferenceField(title=_("Internal redirection target"),
-                                       description=_("Internal redirection reference. You can search a reference using "
-                                                     "'+' followed by internal number, of by entering text matching "
-                                                     "content title."),
-                                       required=False)
-
-    target_url = TextLine(title=_("Target URL"),
-                          description=_("URL to which source URL should be redirected"),
-                          required=False)
-
-    @invariant
-    def check_reference_and_target(self):
-        if self.reference and self.target_url:
-            raise Invalid(_("You can only provide an internal reference OR a target URL"))
-        elif not (self.reference or self.target_url):
-            raise Invalid(_("You must provide an internal reference OR a target URL"))
-
-    def match(self, source_url):
-        """Return regexp URL match on given URL"""
-
-    def rewrite(self, source_url, request):
-        """Rewrite given source URL"""
-
-
-class IRedirectionManager(IOrderedContainer):
-    """Redirection manager"""
-
-    contains(IRedirectionRule)
-
-    def get_active_items(self):
-        """Get iterator over active items"""
-
-    def get_response(self, request):
-        """Get new response for given request"""
-
-    def test_rules(self, source_url, request, check_inactive_rules=False):
-        """Test rules against given URL"""
-
-
-class IRedirectionManagerTarget(Interface):
-    """Redirection manager target marker interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/renderer/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,57 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from zope.annotation import IAttributeAnnotatable
+from zope.contentprovider.interfaces import IContentProvider
+
+# import packages
+from zope.interface import Interface, Attribute
+
+
+HIDDEN_RENDERER_NAME = 'hidden'
+
+
+class IRenderedContent(IAttributeAnnotatable):
+    """Generic interface for any rendered content"""
+
+    renderer = Attribute("Selected renderer name")
+
+    def get_renderer(self, request=None):
+        """Get selected renderer implementation"""
+
+
+class IContentRenderer(IContentProvider):
+    """Content renderer interface"""
+
+    label = Attribute("Renderer label")
+    weight = Attribute("Renderer weight, used for ordering")
+
+    settings_interface = Attribute("Renderer settings interface")
+    resources = Attribute("Iterable of needed Fanstatic resources")
+
+    language = Attribute("Renderer language (if forced)")
+    context_attrs = Attribute("Context attributes defined into renderer")
+    i18n_context_attrs = Attribute("I18n context attributes defined into renderer")
+
+
+class ISharedContentRenderer(IContentRenderer):
+    """Shared content renderer interface"""
+
+
+class IRendererSettings(Interface):
+    """Base renderer settings interface"""
--- a/src/pyams_content/features/renderer/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from zope.annotation import IAttributeAnnotatable
-from zope.contentprovider.interfaces import IContentProvider
-
-# import packages
-from zope.interface import Interface, Attribute
-
-
-HIDDEN_RENDERER_NAME = 'hidden'
-
-
-class IRenderedContent(IAttributeAnnotatable):
-    """Generic interface for any rendered content"""
-
-    renderer = Attribute("Selected renderer name")
-
-    def get_renderer(self, request=None):
-        """Get selected renderer implementation"""
-
-
-class IContentRenderer(IContentProvider):
-    """Content renderer interface"""
-
-    label = Attribute("Renderer label")
-    weight = Attribute("Renderer weight, used for ordering")
-
-    settings_interface = Attribute("Renderer settings interface")
-    resources = Attribute("Iterable of needed Fanstatic resources")
-
-    language = Attribute("Renderer language (if forced)")
-    context_attrs = Attribute("Context attributes defined into renderer")
-    i18n_context_attrs = Attribute("I18n context attributes defined into renderer")
-
-
-class ISharedContentRenderer(IContentRenderer):
-    """Shared content renderer interface"""
-
-
-class IRendererSettings(Interface):
-    """Base renderer settings interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/profile/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from zope.schema import Choice, List, TextLine
+
+from pyams_content import _
+
+
+ADMIN_PROFILE_KEY = 'pyams_content.admin_profile'
+
+
+class IAdminProfile(IAttributeAnnotatable):
+    """User admin profile preferences"""
+
+    favorites = List(title=_("User favorites"),
+                     description=_("List of internal numbers of shared contents stored for quick access"),
+                     value_type=TextLine())
+
+    table_page_length = Choice(title=_("Default table length"),
+                               description=_("Default length used for inner tables and dashboards"),
+                               values=(10, 25, 50, 100),
+                               default=10)
--- a/src/pyams_content/profile/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-# import packages
-from zope.schema import Choice, List, TextLine
-
-from pyams_content import _
-
-
-ADMIN_PROFILE_KEY = 'pyams_content.admin_profile'
-
-
-class IAdminProfile(IAttributeAnnotatable):
-    """User admin profile preferences"""
-
-    favorites = List(title=_("User favorites"),
-                     description=_("List of internal numbers of shared contents stored for quick access"),
-                     value_type=TextLine())
-
-    table_page_length = Choice(title=_("Default table length"),
-                               description=_("Default length used for inner tables and dashboards"),
-                               values=(10, 25, 50, 100),
-                               default=10)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/reference/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.interfaces import IBaseContent
+from zope.container.interfaces import IContainer
+
+# import packages
+from zope.container.constraints import containers, contains
+
+
+class IReferenceInfo(IBaseContent):
+    """Base reference interface"""
+
+    containers('.IReferenceTable')
+
+
+class IReferenceTable(IBaseContent):
+    """Reference table interface"""
+
+    containers('.IReferenceTableContainer')
+    contains(IReferenceInfo)
+
+
+class IReferenceManager(IBaseContent, IContainer):
+    """References tables container"""
+
+    contains(IReferenceTable)
--- a/src/pyams_content/reference/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.interfaces import IBaseContent
-from zope.container.interfaces import IContainer
-
-# import packages
-from zope.container.constraints import containers, contains
-
-
-class IReferenceInfo(IBaseContent):
-    """Base reference interface"""
-
-    containers('.IReferenceTable')
-
-
-class IReferenceTable(IBaseContent):
-    """Reference table interface"""
-
-    containers('.IReferenceTableContainer')
-    contains(IReferenceInfo)
-
-
-class IReferenceManager(IBaseContent, IContainer):
-    """References tables container"""
-
-    contains(IReferenceTable)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/reference/pictograms/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.reference.interfaces import IReferenceInfo, IReferenceTable
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from pyams_i18n.schema import I18nImageField, I18nTextLineField
+from zope.container.constraints import containers, contains
+from zope.interface import Interface
+from zope.schema import List, Choice
+
+from pyams_content import _
+
+
+PICTOGRAM_VOCABULARY = 'PyAMS pictograms'
+SELECTED_PICTOGRAM_VOCABULARY = 'PyAMS selected pictograms'
+
+
+class IPictogram(IReferenceInfo):
+    """Pictogram interface
+
+    Pictograms are managed in a specific reference table to be easily reused by the application
+    into any shared content.
+    """
+
+    containers('.IPictogramTable')
+
+    image = I18nImageField(title=_("Image"),
+                           description=_("Pictogram content"),
+                           required=True)
+
+    alt_title = I18nTextLineField(title=_("Accessibility title"),
+                                  description=_("Alternate title used to describe image content"),
+                                  required=False)
+
+    header = I18nTextLineField(title=_('pictogram-header', default="Header"),
+                               description=_("Default header associated with this pictogram"),
+                               required=False)
+
+
+class IPictogramTable(IReferenceTable):
+    """Pictograms table interface"""
+
+    contains(IPictogram)
+
+
+PICTOGRAM_MANAGER_KEY = 'pyams_content.pictogram.manager'
+
+
+class IPictogramManager(Interface):
+    """Pictogram manager interface
+
+    A pictogram manager (typically, a shared tool) is a component which allows selection of a set of
+    pictogram which will be available for selection into shared content.
+    """
+
+    selected_pictograms = List(title=_("Selected pictograms"),
+                               description=_("List of selected pictograms which will be available to shared contents"),
+                               required=False,
+                               value_type=Choice(vocabulary='PyAMS pictograms'))
+
+
+class IPictogramManagerTarget(IAttributeAnnotatable):
+    """Pictogram manager target interface"""
--- a/src/pyams_content/reference/pictograms/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.reference.interfaces import IReferenceInfo, IReferenceTable
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-# import packages
-from pyams_i18n.schema import I18nImageField, I18nTextLineField
-from zope.container.constraints import containers, contains
-from zope.interface import Interface
-from zope.schema import List, Choice
-
-from pyams_content import _
-
-
-PICTOGRAM_VOCABULARY = 'PyAMS pictograms'
-SELECTED_PICTOGRAM_VOCABULARY = 'PyAMS selected pictograms'
-
-
-class IPictogram(IReferenceInfo):
-    """Pictogram interface
-
-    Pictograms are managed in a specific reference table to be easily reused by the application
-    into any shared content.
-    """
-
-    containers('.IPictogramTable')
-
-    image = I18nImageField(title=_("Image"),
-                           description=_("Pictogram content"),
-                           required=True)
-
-    alt_title = I18nTextLineField(title=_("Accessibility title"),
-                                  description=_("Alternate title used to describe image content"),
-                                  required=False)
-
-    header = I18nTextLineField(title=_('pictogram-header', default="Header"),
-                               description=_("Default header associated with this pictogram"),
-                               required=False)
-
-
-class IPictogramTable(IReferenceTable):
-    """Pictograms table interface"""
-
-    contains(IPictogram)
-
-
-PICTOGRAM_MANAGER_KEY = 'pyams_content.pictogram.manager'
-
-
-class IPictogramManager(Interface):
-    """Pictogram manager interface
-
-    A pictogram manager (typically, a shared tool) is a component which allows selection of a set of
-    pictogram which will be available for selection into shared content.
-    """
-
-    selected_pictograms = List(title=_("Selected pictograms"),
-                               description=_("List of selected pictograms which will be available to shared contents"),
-                               required=False,
-                               value_type=Choice(vocabulary='PyAMS pictograms'))
-
-
-class IPictogramManagerTarget(IAttributeAnnotatable):
-    """Pictogram manager target interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/root/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,74 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Attribute, Interface
+
+from pyams_content import _
+from pyams_content.interfaces import OPERATOR_ROLE, WEBMASTER_ROLE
+from pyams_portal.interfaces import DESIGNER_ROLE
+from pyams_security.interfaces import SYSTEM_ADMIN_ROLE
+from pyams_security.schema import Principal, PrincipalsSet
+from pyams_skin.interfaces.configuration import IBackOfficeConfiguration, IConfiguration
+from pyams_utils.interfaces.site import ISiteRoot as ISiteRootBase
+
+
+class ISiteRoot(ISiteRootBase):
+    """Main site root interface"""
+
+
+class ISiteRootRoles(Interface):
+    """Main site roles"""
+
+    managers = PrincipalsSet(title=_("Site managers"),
+                             role_id=SYSTEM_ADMIN_ROLE,
+                             required=False)
+
+    webmasters = PrincipalsSet(title=_("Webmasters"),
+                               role_id=WEBMASTER_ROLE,
+                               required=False)
+
+    designers = PrincipalsSet(title=_("Templates managers"),
+                              role_id=DESIGNER_ROLE,
+                              required=False)
+
+    operators = Principal(title=_("Operators group"),
+                          description=_("Name of group containing all roles owners"),
+                          role_id=OPERATOR_ROLE,
+                          required=False)
+
+
+class ISiteRootConfiguration(IConfiguration):
+    """Site root configuration interface"""
+
+
+class ISiteRootToolsConfiguration(Interface):
+    """Site root tools configuration interface"""
+
+    tables_name = Attribute("References tables manager name")
+
+    pictograms_table_name = Attribute("Pictograms reference table name")
+
+    tools_name = Attribute("Tools name")
+
+    views_tool_name = Attribute("Views tool name")
+    forms_tool_name = Attribute("Forms tool name")
+    imagemaps_tool_name = Attribute("Image maps tool name")
+    logos_tool_name = Attribute("Logos tool name")
+
+    news_tool_name = Attribute("News tool name")
+    topics_tool_name = Attribute("Topics tool name")
+
+
+class ISiteRootBackOfficeConfiguration(IBackOfficeConfiguration):
+    """Site root back-office configuration interface"""
--- a/src/pyams_content/root/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-from zope.interface import Attribute, Interface
-
-from pyams_content import _
-from pyams_content.interfaces import OPERATOR_ROLE, WEBMASTER_ROLE
-from pyams_portal.interfaces import DESIGNER_ROLE
-from pyams_security.interfaces import SYSTEM_ADMIN_ROLE
-from pyams_security.schema import Principal, PrincipalsSet
-from pyams_skin.interfaces.configuration import IBackOfficeConfiguration, IConfiguration
-from pyams_utils.interfaces.site import ISiteRoot as ISiteRootBase
-
-
-class ISiteRoot(ISiteRootBase):
-    """Main site root interface"""
-
-
-class ISiteRootRoles(Interface):
-    """Main site roles"""
-
-    managers = PrincipalsSet(title=_("Site managers"),
-                             role_id=SYSTEM_ADMIN_ROLE,
-                             required=False)
-
-    webmasters = PrincipalsSet(title=_("Webmasters"),
-                               role_id=WEBMASTER_ROLE,
-                               required=False)
-
-    designers = PrincipalsSet(title=_("Templates managers"),
-                              role_id=DESIGNER_ROLE,
-                              required=False)
-
-    operators = Principal(title=_("Operators group"),
-                          description=_("Name of group containing all roles owners"),
-                          role_id=OPERATOR_ROLE,
-                          required=False)
-
-
-class ISiteRootConfiguration(IConfiguration):
-    """Site root configuration interface"""
-
-
-class ISiteRootToolsConfiguration(Interface):
-    """Site root tools configuration interface"""
-
-    tables_name = Attribute("References tables manager name")
-
-    pictograms_table_name = Attribute("Pictograms reference table name")
-
-    tools_name = Attribute("Tools name")
-
-    views_tool_name = Attribute("Views tool name")
-    forms_tool_name = Attribute("Forms tool name")
-    imagemaps_tool_name = Attribute("Image maps tool name")
-    logos_tool_name = Attribute("Logos tool name")
-
-    news_tool_name = Attribute("News tool name")
-    topics_tool_name = Attribute("Topics tool name")
-
-
-class ISiteRootBackOfficeConfiguration(IBackOfficeConfiguration):
-    """Site root back-office configuration interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/blog/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,80 @@
+#
+# Copyright (c) 2008-2016 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.container.constraints import containers, contains
+from zope.container.interfaces import IContainer
+from zope.interface import Attribute, Interface
+from zope.schema import Text
+
+from pyams_content.shared.common.interfaces import ISharedSite, IBaseSharedTool, ISharedContent, \
+    IDeletableElement, IWfSharedContentPortalContext
+from pyams_i18n.schema import I18nTextField
+from pyams_sequence.interfaces import ISequentialIdTarget
+from pyams_workflow.interfaces import IWorkflowPublicationSupport
+
+from pyams_content import _
+
+
+BLOG_CONTENT_TYPE = 'blog'
+BLOG_CONTENT_NAME = _("Blog post")
+
+
+class IWfBlogPost(IWfSharedContentPortalContext):
+    """Blog topic interface"""
+
+
+class IWfBlogPostFactory(Interface):
+    """Blog post factory interface"""
+
+
+class IBlogPost(ISharedContent, IDeletableElement):
+    """Workflow managed blog post interface"""
+
+    containers('.IBlogFolder')
+
+
+class IBlogFolder(IContainer, IDeletableElement):
+    """Blog folder interface"""
+
+    containers('.IBlogManager', '.IBlogFolder')
+    contains('.IBlogFolder', '.IBlogPost')
+
+
+class IBlogFolderFactory(Interface):
+    """Blog folder factory interface"""
+
+
+class IBlogManager(ISharedSite, IBaseSharedTool, IWorkflowPublicationSupport, IDeletableElement, ISequentialIdTarget):
+    """Blog manager interface"""
+
+    contains(IBlogFolder)
+
+    folder_factory = Attribute("Blog folder factory")
+
+    topic_content_type = Attribute("Topic content type")
+    topic_content_factory = Attribute("Topic content factory")
+
+    description = I18nTextField(title=_("Meta-description"),
+                                description=_("The blog's description is 'hidden' into HTML's page headers; but it "
+                                              "can be seen, for example, in some search engines results as content's "
+                                              "description; if description is empty, content's header will be used."),
+                                required=False)
+
+    notepad = Text(title=_("Notepad"),
+                   description=_("Internal information to be known about this content"),
+                   required=False)
+
+
+class IBlogManagerFactory(Interface):
+    """Blog manager factory interface"""
--- a/src/pyams_content/shared/blog/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-#
-# Copyright (c) 2008-2016 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.container.constraints import containers, contains
-from zope.container.interfaces import IContainer
-from zope.interface import Attribute, Interface
-from zope.schema import Text
-
-from pyams_content.shared.common.interfaces import ISharedSite, IBaseSharedTool, ISharedContent, \
-    IDeletableElement, IWfSharedContentPortalContext
-from pyams_i18n.schema import I18nTextField
-from pyams_sequence.interfaces import ISequentialIdTarget
-from pyams_workflow.interfaces import IWorkflowPublicationSupport
-
-from pyams_content import _
-
-
-BLOG_CONTENT_TYPE = 'blog'
-BLOG_CONTENT_NAME = _("Blog post")
-
-
-class IWfBlogPost(IWfSharedContentPortalContext):
-    """Blog topic interface"""
-
-
-class IWfBlogPostFactory(Interface):
-    """Blog post factory interface"""
-
-
-class IBlogPost(ISharedContent, IDeletableElement):
-    """Workflow managed blog post interface"""
-
-    containers('.IBlogFolder')
-
-
-class IBlogFolder(IContainer, IDeletableElement):
-    """Blog folder interface"""
-
-    containers('.IBlogManager', '.IBlogFolder')
-    contains('.IBlogFolder', '.IBlogPost')
-
-
-class IBlogFolderFactory(Interface):
-    """Blog folder factory interface"""
-
-
-class IBlogManager(ISharedSite, IBaseSharedTool, IWorkflowPublicationSupport, IDeletableElement, ISequentialIdTarget):
-    """Blog manager interface"""
-
-    contains(IBlogFolder)
-
-    folder_factory = Attribute("Blog folder factory")
-
-    topic_content_type = Attribute("Topic content type")
-    topic_content_factory = Attribute("Topic content factory")
-
-    description = I18nTextField(title=_("Meta-description"),
-                                description=_("The blog's description is 'hidden' into HTML's page headers; but it "
-                                              "can be seen, for example, in some search engines results as content's "
-                                              "description; if description is empty, content's header will be used."),
-                                required=False)
-
-    notepad = Text(title=_("Notepad"),
-                   description=_("Internal information to be known about this content"),
-                   required=False)
-
-
-class IBlogManagerFactory(Interface):
-    """Blog manager factory interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/form/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,193 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.container.constraints import containers, contains
+from zope.container.interfaces import IContainer, IContained
+from zope.interface import Interface, Attribute
+from zope.schema import TextLine, Choice, Bool
+
+from pyams_content import _
+# import interfaces
+from pyams_content.shared.common.interfaces import ISharedContent, IWfSharedContentPortalContext, \
+    ISharedToolPortalContext
+# import packages
+from pyams_i18n.schema import I18nTextLineField, I18nTextField
+from pyams_utils.schema import MailAddressField, TextLineListField
+
+FORM_CONTENT_TYPE = 'form'
+FORM_CONTENT_NAME = _('Form')
+
+FORM_FIELD_CONTAINER_KEY = 'pyams_content.shared.form_fields'
+
+
+class IFormsManager(ISharedToolPortalContext):
+    """Forms manager interface"""
+
+
+class IFormsManagerFactory(Interface):
+    """Forms manager factory interface"""
+
+
+class IFormField(IContained):
+    """Form field interface"""
+
+    containers('.IFormFieldContainer')
+
+    name = TextLine(title=_("Field name"),
+                    description=_("Field internal name; must be unique for a given form"),
+                    required=True)
+
+    field_type = Choice(title=_("Field type"),
+                        description=_("Selected field type"),
+                        vocabulary='PyAMS form field types',
+                        required=True)
+
+    label = I18nTextLineField(title=_("Label"),
+                              description=_("User field label"),
+                              required=True)
+
+    description = I18nTextField(title=_("Description"),
+                                description=_("Field description can be displayed as hint"),
+                                required=False)
+
+    placeholder = TextLine(title=_("Placeholder"),
+                           description=_("Some field types like textline can display a placeholder"),
+                           required=False)
+
+    values = TextLineListField(title=_("Optional values"),
+                               description=_("List of available values (for 'choice' and 'list' field types)"),
+                               required=False)
+
+    default = I18nTextLineField(title=_("Default value"),
+                                description=_("Give default value if field type can use it"),
+                                required=False)
+
+    required = Bool(title=_("Required?"),
+                    description=_("Select 'yes' to set field as mandatory"),
+                    required=True,
+                    default=False)
+
+    visible = Bool(title=_("Visible?"),
+                   description=_("Select 'no' to hide given field..."),
+                   required=True,
+                   default=True)
+
+
+class IFormFieldFactory(Interface):
+    """Form field factory interface"""
+
+    label = Attribute("Factory label")
+    weight = Attribute("Factory weight")
+
+    def get_schema_field(self, field):
+        """Get schema field matching given form field"""
+
+
+class IFormFieldContainer(IContainer):
+    """Form fields container interface"""
+
+    contains(IFormField)
+
+    def append(self, field):
+        """Append given field to container"""
+
+    def get_fields(self):
+        """Get schema fields matching current fields"""
+
+
+class IFormFieldContainerTarget(Interface):
+    """Form fields container target marker interface"""
+
+
+class IWfForm(IWfSharedContentPortalContext):
+    """Form interface"""
+
+    user_title = I18nTextLineField(title=_("Form title"),
+                                   required=True)
+
+    handler = Choice(title=_("Form handler"),
+                     description=_("Select how form data is transmitted"),
+                     vocabulary='PyAMS form handlers')
+
+    auth_only = Bool(title=_("Authenticated only?"),
+                     description=_("If 'yes', only authenticated users will be able to see and submit form"),
+                     required=True,
+                     default=False)
+
+    use_captcha = Bool(title=_("Use captcha?"),
+                       description=_("If 'yes', a captcha will be added automatically to the form"),
+                       required=True,
+                       default=True)
+
+    submit_label = I18nTextLineField(title=_("Submit label"),
+                                     description=_("Label of form submit button"),
+                                     required=True)
+
+    def query_handler(self, handler=None):
+        """Get form handler utility"""
+
+
+class IWfFormFactory(Interface):
+    """Form factory interface"""
+
+
+class IForm(ISharedContent):
+    """Workflow managed form interface"""
+
+
+#
+# Form handler
+#
+
+class IFormHandler(Interface):
+    """Form handler interface"""
+
+    label = Attribute("Handler label")
+    target_interface = Attribute("Handler target marker interface")
+    handler_info = Attribute("Handler info interface")
+
+    def handle(self, data):
+        """Handle entered data"""
+
+
+class IFormHandlerInfo(Interface):
+    """Base handler info interface"""
+
+
+class IMailtoHandlerInfo(IFormHandlerInfo):
+    """Mailto form handler info interface"""
+
+    source_address = MailAddressField(title=_("Source address"),
+                                      description=_("Mail address from which form data is sent"),
+                                      required=True)
+
+    source_name = TextLine(title=_("Source name"),
+                           description=_("Name of mail data sender"),
+                           required=False)
+
+    target_address = MailAddressField(title=_("Recipient address"),
+                                      description=_("Mail address to which form data is sent"),
+                                      required=True)
+
+    target_name = TextLine(title=_("Recipient name"),
+                           description=_("Name of data recipient"),
+                           required=False)
+
+
+class IMailtoHandlerTarget(IAttributeAnnotatable):
+    """Mailto handler target marker interface"""
--- a/src/pyams_content/shared/form/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-from zope.annotation.interfaces import IAttributeAnnotatable
-from zope.container.constraints import containers, contains
-from zope.container.interfaces import IContainer, IContained
-from zope.interface import Interface, Attribute
-from zope.schema import TextLine, Choice, Bool
-
-from pyams_content import _
-# import interfaces
-from pyams_content.shared.common.interfaces import ISharedContent, IWfSharedContentPortalContext, \
-    ISharedToolPortalContext
-# import packages
-from pyams_i18n.schema import I18nTextLineField, I18nTextField
-from pyams_utils.schema import MailAddressField, TextLineListField
-
-FORM_CONTENT_TYPE = 'form'
-FORM_CONTENT_NAME = _('Form')
-
-FORM_FIELD_CONTAINER_KEY = 'pyams_content.shared.form_fields'
-
-
-class IFormsManager(ISharedToolPortalContext):
-    """Forms manager interface"""
-
-
-class IFormsManagerFactory(Interface):
-    """Forms manager factory interface"""
-
-
-class IFormField(IContained):
-    """Form field interface"""
-
-    containers('.IFormFieldContainer')
-
-    name = TextLine(title=_("Field name"),
-                    description=_("Field internal name; must be unique for a given form"),
-                    required=True)
-
-    field_type = Choice(title=_("Field type"),
-                        description=_("Selected field type"),
-                        vocabulary='PyAMS form field types',
-                        required=True)
-
-    label = I18nTextLineField(title=_("Label"),
-                              description=_("User field label"),
-                              required=True)
-
-    description = I18nTextField(title=_("Description"),
-                                description=_("Field description can be displayed as hint"),
-                                required=False)
-
-    placeholder = TextLine(title=_("Placeholder"),
-                           description=_("Some field types like textline can display a placeholder"),
-                           required=False)
-
-    values = TextLineListField(title=_("Optional values"),
-                               description=_("List of available values (for 'choice' and 'list' field types)"),
-                               required=False)
-
-    default = I18nTextLineField(title=_("Default value"),
-                                description=_("Give default value if field type can use it"),
-                                required=False)
-
-    required = Bool(title=_("Required?"),
-                    description=_("Select 'yes' to set field as mandatory"),
-                    required=True,
-                    default=False)
-
-    visible = Bool(title=_("Visible?"),
-                   description=_("Select 'no' to hide given field..."),
-                   required=True,
-                   default=True)
-
-
-class IFormFieldFactory(Interface):
-    """Form field factory interface"""
-
-    label = Attribute("Factory label")
-    weight = Attribute("Factory weight")
-
-    def get_schema_field(self, field):
-        """Get schema field matching given form field"""
-
-
-class IFormFieldContainer(IContainer):
-    """Form fields container interface"""
-
-    contains(IFormField)
-
-    def append(self, field):
-        """Append given field to container"""
-
-    def get_fields(self):
-        """Get schema fields matching current fields"""
-
-
-class IFormFieldContainerTarget(Interface):
-    """Form fields container target marker interface"""
-
-
-class IWfForm(IWfSharedContentPortalContext):
-    """Form interface"""
-
-    user_title = I18nTextLineField(title=_("Form title"),
-                                   required=True)
-
-    handler = Choice(title=_("Form handler"),
-                     description=_("Select how form data is transmitted"),
-                     vocabulary='PyAMS form handlers')
-
-    auth_only = Bool(title=_("Authenticated only?"),
-                     description=_("If 'yes', only authenticated users will be able to see and submit form"),
-                     required=True,
-                     default=False)
-
-    use_captcha = Bool(title=_("Use captcha?"),
-                       description=_("If 'yes', a captcha will be added automatically to the form"),
-                       required=True,
-                       default=True)
-
-    submit_label = I18nTextLineField(title=_("Submit label"),
-                                     description=_("Label of form submit button"),
-                                     required=True)
-
-    def query_handler(self, handler=None):
-        """Get form handler utility"""
-
-
-class IWfFormFactory(Interface):
-    """Form factory interface"""
-
-
-class IForm(ISharedContent):
-    """Workflow managed form interface"""
-
-
-#
-# Form handler
-#
-
-class IFormHandler(Interface):
-    """Form handler interface"""
-
-    label = Attribute("Handler label")
-    target_interface = Attribute("Handler target marker interface")
-    handler_info = Attribute("Handler info interface")
-
-    def handle(self, data):
-        """Handle entered data"""
-
-
-class IFormHandlerInfo(Interface):
-    """Base handler info interface"""
-
-
-class IMailtoHandlerInfo(IFormHandlerInfo):
-    """Mailto form handler info interface"""
-
-    source_address = MailAddressField(title=_("Source address"),
-                                      description=_("Mail address from which form data is sent"),
-                                      required=True)
-
-    source_name = TextLine(title=_("Source name"),
-                           description=_("Name of mail data sender"),
-                           required=False)
-
-    target_address = MailAddressField(title=_("Recipient address"),
-                                      description=_("Mail address to which form data is sent"),
-                                      required=True)
-
-    target_name = TextLine(title=_("Recipient name"),
-                           description=_("Name of data recipient"),
-                           required=False)
-
-
-class IMailtoHandlerTarget(IAttributeAnnotatable):
-    """Mailto handler target marker interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/imagemap/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,103 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.paragraph.interfaces import IBaseParagraph
+from pyams_content.shared.common.interfaces import ISharedTool, IWfSharedContent, ISharedContent
+from pyams_sequence.interfaces import IInternalReference
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from pyams_content.shared.imagemap.schema import MapArea
+from pyams_i18n.schema import I18nTextLineField, I18nImageField
+from pyams_sequence.schema import InternalReferenceField
+from pyams_utils.schema import PersistentDict
+from zope.interface import Interface
+from zope.schema import Object, Choice
+
+from pyams_content import _
+
+
+IMAGEMAP_CONTENT_TYPE = 'imagemap'
+IMAGEMAP_CONTENT_NAME = _("Image map")
+
+
+class IImageMapManager(ISharedTool):
+    """Image maps manager interface"""
+
+
+class IImageMapManagerFactory(Interface):
+    """Image maps manager factory interface"""
+
+
+class IImageMapArea(IAttributeAnnotatable):
+    """Image map area interface"""
+
+    link = Choice(title=_("Link target"),
+                  description=_("Internal or external link associated with this map area"),
+                  vocabulary="PyAMS content associations",
+                  required=True)
+
+    title = I18nTextLineField(title=_("Alternate title"),
+                              description=_("Alternate label associated with this area"),
+                              required=False)
+
+    area = MapArea(title=_("Map area coordinates"),
+                   description=_("List of coordinates of image area"),
+                   required=True)
+
+
+class IWfImageMap(IWfSharedContent):
+    """Image map interface"""
+
+    image = I18nImageField(title=_("Image"),
+                           description=_("Image supporting map areas"),
+                           required=True)
+
+    areas = PersistentDict(title=_("Image map areas"),
+                           description=_("List of defined map areas"),
+                           value_type=Object(schema=IImageMapArea),
+                           required=False)
+
+    def get_association(self, area):
+        """Get association for given area"""
+
+
+class IWfImageMapFactory(Interface):
+    """Image map factory interface"""
+
+
+class IImageMap(ISharedContent):
+    """Workflow managed image map interface"""
+
+
+IMAGEMAP_PARAGRAPH_TYPE = 'ImageMap'
+IMAGEMAP_PARAGRAPH_NAME = _("Image map")
+IMAGEMAP_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.imagemap.renderers'
+
+
+class IImageMapParagraph(IBaseParagraph, IInternalReference):
+    """Image map paragraph"""
+
+    reference = InternalReferenceField(title=_("Internal reference"),
+                                       description=_("Reference to image map object"),
+                                       content_type=IMAGEMAP_CONTENT_TYPE)
+
+    renderer = Choice(title=_("Image map template"),
+                      description=_("Presentation template used for this paragraph"),
+                      vocabulary=IMAGEMAP_PARAGRAPH_RENDERERS,
+                      default='default')
--- a/src/pyams_content/shared/imagemap/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.component.paragraph.interfaces import IBaseParagraph
-from pyams_content.shared.common.interfaces import ISharedTool, IWfSharedContent, ISharedContent
-from pyams_sequence.interfaces import IInternalReference
-from zope.annotation.interfaces import IAttributeAnnotatable
-
-# import packages
-from pyams_content.shared.imagemap.schema import MapArea
-from pyams_i18n.schema import I18nTextLineField, I18nImageField
-from pyams_sequence.schema import InternalReferenceField
-from pyams_utils.schema import PersistentDict
-from zope.interface import Interface
-from zope.schema import Object, Choice
-
-from pyams_content import _
-
-
-IMAGEMAP_CONTENT_TYPE = 'imagemap'
-IMAGEMAP_CONTENT_NAME = _("Image map")
-
-
-class IImageMapManager(ISharedTool):
-    """Image maps manager interface"""
-
-
-class IImageMapManagerFactory(Interface):
-    """Image maps manager factory interface"""
-
-
-class IImageMapArea(IAttributeAnnotatable):
-    """Image map area interface"""
-
-    link = Choice(title=_("Link target"),
-                  description=_("Internal or external link associated with this map area"),
-                  vocabulary="PyAMS content associations",
-                  required=True)
-
-    title = I18nTextLineField(title=_("Alternate title"),
-                              description=_("Alternate label associated with this area"),
-                              required=False)
-
-    area = MapArea(title=_("Map area coordinates"),
-                   description=_("List of coordinates of image area"),
-                   required=True)
-
-
-class IWfImageMap(IWfSharedContent):
-    """Image map interface"""
-
-    image = I18nImageField(title=_("Image"),
-                           description=_("Image supporting map areas"),
-                           required=True)
-
-    areas = PersistentDict(title=_("Image map areas"),
-                           description=_("List of defined map areas"),
-                           value_type=Object(schema=IImageMapArea),
-                           required=False)
-
-    def get_association(self, area):
-        """Get association for given area"""
-
-
-class IWfImageMapFactory(Interface):
-    """Image map factory interface"""
-
-
-class IImageMap(ISharedContent):
-    """Workflow managed image map interface"""
-
-
-IMAGEMAP_PARAGRAPH_TYPE = 'ImageMap'
-IMAGEMAP_PARAGRAPH_NAME = _("Image map")
-IMAGEMAP_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.imagemap.renderers'
-
-
-class IImageMapParagraph(IBaseParagraph, IInternalReference):
-    """Image map paragraph"""
-
-    reference = InternalReferenceField(title=_("Internal reference"),
-                                       description=_("Reference to image map object"),
-                                       content_type=IMAGEMAP_CONTENT_TYPE)
-
-    renderer = Choice(title=_("Image map template"),
-                      description=_("Presentation template used for this paragraph"),
-                      vocabulary=IMAGEMAP_PARAGRAPH_RENDERERS,
-                      default='default')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/logo/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,91 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+from zope.interface import Interface
+from zope.schema import URI, Choice, TextLine
+
+from pyams_content import _
+# import interfaces
+from pyams_content.component.paragraph import IBaseParagraph
+from pyams_content.shared.common.interfaces import ISharedTool, IWfSharedContent, ISharedContent
+# import packages
+from pyams_file.schema import ImageField
+from pyams_i18n.schema import I18nTextLineField
+from pyams_sequence.interfaces import IInternalReferencesList
+from pyams_sequence.schema import InternalReferencesListField
+
+LOGO_CONTENT_TYPE = 'logo'
+LOGO_CONTENT_NAME = _("Logo")
+
+
+class ILogosManager(ISharedTool):
+    """Logos manager interface"""
+
+
+class ILogosManagerFactory(Interface):
+    """Logos manager factory interface"""
+
+
+class IWfLogo(IWfSharedContent):
+    """Logo interface"""
+
+    title = I18nTextLineField(title=_("Title"),
+                              description=_("Full name of logo organization"),
+                              required=True)
+
+    acronym = TextLine(title=_("Acronym"),
+                       description=_("Matching logo acronym, without spaces or separators"),
+                       required=False)
+
+    url = URI(title=_("Target URL"),
+              description=_("URL used to access external resource"),
+              required=False)
+
+    image = ImageField(title=_("Image (colored)"),
+                       description=_("Image data"),
+                       required=True)
+
+    monochrome_image = ImageField(title=_("Image (monochrome)"),
+                                  description=_("An alternate image which can be used by some "
+                                                "presentation templates"),
+                                  required=False)
+
+
+class IWfLogoFactory(Interface):
+    """Logo factory interface"""
+
+
+class ILogo(ISharedContent):
+    """Workflow managed logo interface"""
+
+
+LOGOS_PARAGRAPH_TYPE = 'Logos'
+LOGOS_PARAGRAPH_NAME = _("Logos")
+LOGOS_PARAGRAPH_RENDERERS = 'PyAMS.shared.logos.renderers'
+
+
+class ILogosParagraph(IBaseParagraph, IInternalReferencesList):
+    """Logos paragraph"""
+
+    references = InternalReferencesListField(title=_("Logos references"),
+                                             description=_("List of internal logos references"),
+                                             content_type=LOGO_CONTENT_TYPE)
+
+    renderer = Choice(title=_("Logos template"),
+                      description=_("Presentation template used for this paragraph"),
+                      vocabulary=LOGOS_PARAGRAPH_RENDERERS,
+                      default='default')
--- a/src/pyams_content/shared/logo/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-from zope.interface import Interface
-from zope.schema import URI, Choice, TextLine
-
-from pyams_content import _
-# import interfaces
-from pyams_content.component.paragraph import IBaseParagraph
-from pyams_content.shared.common.interfaces import ISharedTool, IWfSharedContent, ISharedContent
-# import packages
-from pyams_file.schema import ImageField
-from pyams_i18n.schema import I18nTextLineField
-from pyams_sequence.interfaces import IInternalReferencesList
-from pyams_sequence.schema import InternalReferencesListField
-
-LOGO_CONTENT_TYPE = 'logo'
-LOGO_CONTENT_NAME = _("Logo")
-
-
-class ILogosManager(ISharedTool):
-    """Logos manager interface"""
-
-
-class ILogosManagerFactory(Interface):
-    """Logos manager factory interface"""
-
-
-class IWfLogo(IWfSharedContent):
-    """Logo interface"""
-
-    title = I18nTextLineField(title=_("Title"),
-                              description=_("Full name of logo organization"),
-                              required=True)
-
-    acronym = TextLine(title=_("Acronym"),
-                       description=_("Matching logo acronym, without spaces or separators"),
-                       required=False)
-
-    url = URI(title=_("Target URL"),
-              description=_("URL used to access external resource"),
-              required=False)
-
-    image = ImageField(title=_("Image (colored)"),
-                       description=_("Image data"),
-                       required=True)
-
-    monochrome_image = ImageField(title=_("Image (monochrome)"),
-                                  description=_("An alternate image which can be used by some "
-                                                "presentation templates"),
-                                  required=False)
-
-
-class IWfLogoFactory(Interface):
-    """Logo factory interface"""
-
-
-class ILogo(ISharedContent):
-    """Workflow managed logo interface"""
-
-
-LOGOS_PARAGRAPH_TYPE = 'Logos'
-LOGOS_PARAGRAPH_NAME = _("Logos")
-LOGOS_PARAGRAPH_RENDERERS = 'PyAMS.shared.logos.renderers'
-
-
-class ILogosParagraph(IBaseParagraph, IInternalReferencesList):
-    """Logos paragraph"""
-
-    references = InternalReferencesListField(title=_("Logos references"),
-                                             description=_("List of internal logos references"),
-                                             content_type=LOGO_CONTENT_TYPE)
-
-    renderer = Choice(title=_("Logos template"),
-                      description=_("Presentation template used for this paragraph"),
-                      vocabulary=LOGOS_PARAGRAPH_RENDERERS,
-                      default='default')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/news/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common.interfaces import ISharedContent, \
+    IWfSharedContentPortalContext, ISharedToolPortalContext
+
+# import packages
+from zope.interface import Interface
+
+from pyams_content import _
+
+
+NEWS_CONTENT_TYPE = 'news'
+NEWS_CONTENT_NAME = _("News topic")
+
+
+class INewsManager(ISharedToolPortalContext):
+    """News manager interface"""
+
+
+class INewsManagerFactory(Interface):
+    """News manager factory interface"""
+
+
+class IWfNewsEvent(IWfSharedContentPortalContext):
+    """News event interface"""
+
+
+class IWfNewsEventFactory(Interface):
+    """News event parent interface"""
+
+
+class INewsEvent(ISharedContent):
+    """Workflow managed news event interface"""
--- a/src/pyams_content/shared/news/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.shared.common.interfaces import ISharedContent, \
-    IWfSharedContentPortalContext, ISharedToolPortalContext
-
-# import packages
-from zope.interface import Interface
-
-from pyams_content import _
-
-
-NEWS_CONTENT_TYPE = 'news'
-NEWS_CONTENT_NAME = _("News topic")
-
-
-class INewsManager(ISharedToolPortalContext):
-    """News manager interface"""
-
-
-class INewsManagerFactory(Interface):
-    """News manager factory interface"""
-
-
-class IWfNewsEvent(IWfSharedContentPortalContext):
-    """News event interface"""
-
-
-class IWfNewsEventFactory(Interface):
-    """News event parent interface"""
-
-
-class INewsEvent(ISharedContent):
-    """Workflow managed news event interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/site/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,180 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from collections import OrderedDict
+
+from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.container.constraints import containers, contains
+from zope.container.interfaces import IContained, IContainer
+from zope.interface import Attribute, Interface
+from zope.schema import Bool, Choice, Text
+from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
+
+from pyams_content import _
+from pyams_content.interfaces import IBaseContent
+from pyams_content.shared.common.interfaces import IBaseContentManagerRoles, IBaseSharedTool, IDeletableElement, \
+    ISharedSite
+from pyams_content.shared.topic.interfaces import ITopic, IWfTopic, IWfTopicFactory
+from pyams_i18n.schema import I18nTextField, I18nTextLineField
+from pyams_sequence.interfaces import IInternalReference, ISequentialIdTarget
+from pyams_workflow.interfaces import IWorkflowPublicationSupport
+
+
+FOLDER_REDIRECT_DISPLAY_MODE = 'redirect'
+FOLDER_TEMPLATE_DISPLAY_MODE = 'template'
+
+FOLDER_DISPLAY_MODES = OrderedDict((
+    (FOLDER_REDIRECT_DISPLAY_MODE, _("Redirect to first visible sub-folder or content")),
+    (FOLDER_TEMPLATE_DISPLAY_MODE, _("Use presentation template"))
+))
+
+FOLDER_DISPLAY_MODE_VOCABULARY = SimpleVocabulary([SimpleTerm(v, title=t) for v, t in FOLDER_DISPLAY_MODES.items()])
+
+
+class ISiteElement(IContained, IDeletableElement):
+    """Base site element interface"""
+
+    containers('.ISiteContainer')
+
+    content_name = Attribute("Content name")
+
+
+class ISiteElementNavigation(Interface):
+    """Site element navigation interface"""
+
+    visible = Attribute("Visible element?")
+
+
+class ISiteContainer(IContainer, IContained, IWorkflowPublicationSupport):
+    """Base site container interface"""
+
+    contains(ISiteElement)
+
+    def get_visible_items(self, request=None):
+        """Iterator over container visible items"""
+
+    def get_folders_tree(self, selected=None):
+        """Get site tree in JSON format"""
+
+
+class ISiteFolder(IBaseContent, ISiteElement, ISiteContainer, ISequentialIdTarget):
+    """Site folder interface
+
+    A site folder is made to contain sub-folders and topics
+    """
+
+    header = I18nTextField(title=_("Header"),
+                           description=_("Heading displayed according to presentation template"),
+                           required=False)
+
+    description = I18nTextField(title=_("Meta-description"),
+                                description=_("The folder's description is 'hidden' into HTML's page headers; but it "
+                                              "can be seen, for example, in some search engines results as content's "
+                                              "description; if description is empty, content's header will be used."),
+                                required=False)
+
+    notepad = Text(title=_("Notepad"),
+                   description=_("Internal information to be known about this content"),
+                   required=False)
+
+    visible_in_list = Bool(title=_("Visible in folders list"),
+                           description=_("If 'no', folder will not be displayed into folders list"),
+                           required=True,
+                           default=True)
+
+    navigation_title = I18nTextLineField(title=_("Navigation title"),
+                                         description=_("Folder's title displayed in navigation pages; "
+                                                       "original title will be used if none is specified"),
+                                         required=False)
+
+    navigation_mode = Choice(title=_("Navigation mode"),
+                             description=_("Folder behaviour when navigating to folder URL"),
+                             required=True,
+                             vocabulary=FOLDER_DISPLAY_MODE_VOCABULARY,
+                             default=FOLDER_REDIRECT_DISPLAY_MODE)
+
+
+class ISiteFolderFactory(Interface):
+    """Site folder factory interface"""
+
+
+class ISiteFolderRoles(IBaseContentManagerRoles):
+    """Site folder roles interface"""
+
+
+class ISiteManager(ISharedSite, ISiteContainer, IBaseSharedTool, IDeletableElement, ISequentialIdTarget):
+    """Site manager interface"""
+
+    contains(ISiteElement)
+
+    folder_factory = Attribute("Folder factory")
+
+    topic_content_type = Attribute("Topic content type")
+    topic_content_factory = Attribute("Topic content factory")
+
+    description = I18nTextField(title=_("Meta-description"),
+                                description=_("The site's description is 'hidden' into HTML's page headers; but it "
+                                              "can be seen, for example, in some search engines results as content's "
+                                              "description; if description is empty, content's header will be used."),
+                                required=False)
+
+    notepad = Text(title=_("Notepad"),
+                   description=_("Internal information to be known about this content"),
+                   required=False)
+
+
+class ISiteManagerFactory(Interface):
+    """Site manager factory interface"""
+
+
+SITE_TOPIC_CONTENT_TYPE = 'site-topic'
+SITE_TOPIC_CONTENT_NAME = _("Site topic")
+
+
+class IWfSiteTopic(IWfTopic):
+    """Site topic interface"""
+
+
+class IWfSiteTopicFactory(IWfTopicFactory):
+    """Topic factory interface"""
+
+
+class ISiteTopic(ITopic, ISiteElement):
+    """Workflow managed site topic interface"""
+
+
+class IContentLink(ISiteElement, IInternalReference, IAttributeAnnotatable):
+    """Rented content interface"""
+
+    navigation_title = I18nTextLineField(title=_("Navigation title"),
+                                         description=_("Alternate content's title displayed in navigation pages; "
+                                                       "original title will be used if none is specified"),
+                                         required=False)
+
+    visible = Bool(title=_("Visible?"),
+                   description=_("If 'no', link is not visible"),
+                   required=True,
+                   default=True)
+
+
+class IContentSummaryInfo(Interface):
+    """Content interface for site summary page"""
+
+    context = Attribute("Link to adapted context")
+
+    title = Attribute("Content's title")
+
+    header = Attribute("Header")
+
+    button_title = Attribute("Button's target")
--- a/src/pyams_content/shared/site/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-from collections import OrderedDict
-
-from zope.annotation.interfaces import IAttributeAnnotatable
-from zope.container.constraints import containers, contains
-from zope.container.interfaces import IContained, IContainer
-from zope.interface import Attribute, Interface
-from zope.schema import Bool, Choice, Text
-from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
-
-from pyams_content import _
-from pyams_content.interfaces import IBaseContent
-from pyams_content.shared.common.interfaces import IBaseContentManagerRoles, IBaseSharedTool, IDeletableElement, \
-    ISharedSite
-from pyams_content.shared.topic.interfaces import ITopic, IWfTopic, IWfTopicFactory
-from pyams_i18n.schema import I18nTextField, I18nTextLineField
-from pyams_sequence.interfaces import IInternalReference, ISequentialIdTarget
-from pyams_workflow.interfaces import IWorkflowPublicationSupport
-
-
-FOLDER_REDIRECT_DISPLAY_MODE = 'redirect'
-FOLDER_TEMPLATE_DISPLAY_MODE = 'template'
-
-FOLDER_DISPLAY_MODES = OrderedDict((
-    (FOLDER_REDIRECT_DISPLAY_MODE, _("Redirect to first visible sub-folder or content")),
-    (FOLDER_TEMPLATE_DISPLAY_MODE, _("Use presentation template"))
-))
-
-FOLDER_DISPLAY_MODE_VOCABULARY = SimpleVocabulary([SimpleTerm(v, title=t) for v, t in FOLDER_DISPLAY_MODES.items()])
-
-
-class ISiteElement(IContained, IDeletableElement):
-    """Base site element interface"""
-
-    containers('.ISiteContainer')
-
-    content_name = Attribute("Content name")
-
-
-class ISiteElementNavigation(Interface):
-    """Site element navigation interface"""
-
-    visible = Attribute("Visible element?")
-
-
-class ISiteContainer(IContainer, IContained, IWorkflowPublicationSupport):
-    """Base site container interface"""
-
-    contains(ISiteElement)
-
-    def get_visible_items(self, request=None):
-        """Iterator over container visible items"""
-
-    def get_folders_tree(self, selected=None):
-        """Get site tree in JSON format"""
-
-
-class ISiteFolder(IBaseContent, ISiteElement, ISiteContainer, ISequentialIdTarget):
-    """Site folder interface
-
-    A site folder is made to contain sub-folders and topics
-    """
-
-    header = I18nTextField(title=_("Header"),
-                           description=_("Heading displayed according to presentation template"),
-                           required=False)
-
-    description = I18nTextField(title=_("Meta-description"),
-                                description=_("The folder's description is 'hidden' into HTML's page headers; but it "
-                                              "can be seen, for example, in some search engines results as content's "
-                                              "description; if description is empty, content's header will be used."),
-                                required=False)
-
-    notepad = Text(title=_("Notepad"),
-                   description=_("Internal information to be known about this content"),
-                   required=False)
-
-    visible_in_list = Bool(title=_("Visible in folders list"),
-                           description=_("If 'no', folder will not be displayed into folders list"),
-                           required=True,
-                           default=True)
-
-    navigation_title = I18nTextLineField(title=_("Navigation title"),
-                                         description=_("Folder's title displayed in navigation pages; "
-                                                       "original title will be used if none is specified"),
-                                         required=False)
-
-    navigation_mode = Choice(title=_("Navigation mode"),
-                             description=_("Folder behaviour when navigating to folder URL"),
-                             required=True,
-                             vocabulary=FOLDER_DISPLAY_MODE_VOCABULARY,
-                             default=FOLDER_REDIRECT_DISPLAY_MODE)
-
-
-class ISiteFolderFactory(Interface):
-    """Site folder factory interface"""
-
-
-class ISiteFolderRoles(IBaseContentManagerRoles):
-    """Site folder roles interface"""
-
-
-class ISiteManager(ISharedSite, ISiteContainer, IBaseSharedTool, IDeletableElement, ISequentialIdTarget):
-    """Site manager interface"""
-
-    contains(ISiteElement)
-
-    folder_factory = Attribute("Folder factory")
-
-    topic_content_type = Attribute("Topic content type")
-    topic_content_factory = Attribute("Topic content factory")
-
-    description = I18nTextField(title=_("Meta-description"),
-                                description=_("The site's description is 'hidden' into HTML's page headers; but it "
-                                              "can be seen, for example, in some search engines results as content's "
-                                              "description; if description is empty, content's header will be used."),
-                                required=False)
-
-    notepad = Text(title=_("Notepad"),
-                   description=_("Internal information to be known about this content"),
-                   required=False)
-
-
-class ISiteManagerFactory(Interface):
-    """Site manager factory interface"""
-
-
-SITE_TOPIC_CONTENT_TYPE = 'site-topic'
-SITE_TOPIC_CONTENT_NAME = _("Site topic")
-
-
-class IWfSiteTopic(IWfTopic):
-    """Site topic interface"""
-
-
-class IWfSiteTopicFactory(IWfTopicFactory):
-    """Topic factory interface"""
-
-
-class ISiteTopic(ITopic, ISiteElement):
-    """Workflow managed site topic interface"""
-
-
-class IContentLink(ISiteElement, IInternalReference, IAttributeAnnotatable):
-    """Rented content interface"""
-
-    navigation_title = I18nTextLineField(title=_("Navigation title"),
-                                         description=_("Alternate content's title displayed in navigation pages; "
-                                                       "original title will be used if none is specified"),
-                                         required=False)
-
-    visible = Bool(title=_("Visible?"),
-                   description=_("If 'no', link is not visible"),
-                   required=True,
-                   default=True)
-
-
-class IContentSummaryInfo(Interface):
-    """Content interface for site summary page"""
-
-    context = Attribute("Link to adapted context")
-
-    title = Attribute("Content's title")
-
-    header = Attribute("Header")
-
-    button_title = Attribute("Button's target")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/topic/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+
+from pyams_content import _
+from pyams_content.shared.common.interfaces import ISharedContent, ISharedToolPortalContext, \
+    IWfSharedContentPortalContext
+
+
+TOPIC_CONTENT_TYPE = 'topic'
+TOPIC_CONTENT_NAME = _("Topic")
+
+
+class ITopicManager(ISharedToolPortalContext):
+    """Topic manager interface"""
+
+
+class ITopicManagerFactory(Interface):
+    """Topic manager factory interface"""
+
+
+class IWfTopic(IWfSharedContentPortalContext):
+    """Topic interface"""
+
+
+class IWfTopicFactory(Interface):
+    """Topic parent interface"""
+
+
+class ITopic(ISharedContent):
+    """Workflow managed topic interface"""
--- a/src/pyams_content/shared/topic/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-from zope.interface import Interface
-
-from pyams_content import _
-from pyams_content.shared.common.interfaces import ISharedContent, ISharedToolPortalContext, \
-    IWfSharedContentPortalContext
-
-
-TOPIC_CONTENT_TYPE = 'topic'
-TOPIC_CONTENT_NAME = _("Topic")
-
-
-class ITopicManager(ISharedToolPortalContext):
-    """Topic manager interface"""
-
-
-class ITopicManagerFactory(Interface):
-    """Topic manager factory interface"""
-
-
-class IWfTopic(IWfSharedContentPortalContext):
-    """Topic interface"""
-
-
-class IWfTopicFactory(Interface):
-    """Topic parent interface"""
-
-
-class ITopic(ISharedContent):
-    """Workflow managed topic interface"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/view/interfaces.py	Tue Nov 06 14:40:22 2018 +0100
@@ -0,0 +1,261 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common.interfaces import ISharedContent, IWfSharedContent, ISharedTool, \
+    CONTENT_TYPES_VOCABULARY
+from pyams_content.shared.common.interfaces.types import ALL_DATA_TYPES_VOCABULARY
+from pyams_sequence.interfaces import IInternalReferencesList
+
+# import packages
+from pyams_thesaurus.schema import ThesaurusTermsListField
+from zope.interface import Interface, Attribute
+from zope.schema import Set, Choice, Bool, Int
+from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
+
+from pyams_content import _
+
+
+VIEW_CONTENT_TYPE = 'view'
+VIEW_CONTENT_NAME = _('View')
+
+
+CREATION_DATE_ORDER = 'created_date'
+UPDATE_DATE_ORDER = 'modified_date'
+PUBLICATION_DATE_ORDER = 'publication_date'
+FIRSTPUBLICATION_DATE_ORDER = 'first_publication_date'
+
+VIEW_ORDERS = (
+    {'id': CREATION_DATE_ORDER, 'title': _("Creation date")},
+    {'id': UPDATE_DATE_ORDER, 'title': _("Last update date")},
+    {'id': PUBLICATION_DATE_ORDER, 'title': _("Current publication date")},
+    {'id': FIRSTPUBLICATION_DATE_ORDER, 'title': _("First publication date")}
+)
+
+VIEW_ORDER_VOCABULARY = SimpleVocabulary([SimpleTerm(item['id'], title=item['title'])
+                                          for item in VIEW_ORDERS])
+
+
+class IViewsManager(ISharedTool):
+    """Views manager interface"""
+
+
+class IViewsManagerFactory(Interface):
+    """Views manager factory interface"""
+
+
+class IWfView(IWfSharedContent):
+    """View interface"""
+
+    select_context_type = Bool(title=_("Select context type?"),
+                               description=_("If 'yes', content type will be extracted from context"),
+                               required=True,
+                               default=False)
+
+    selected_content_types = Set(title=_("Other content types"),
+                                 description=_("Selected content types; leave empty for all"),
+                                 value_type=Choice(vocabulary=CONTENT_TYPES_VOCABULARY),
+                                 required=False)
+
+    def get_content_types(self, context):
+        """Get content types for given context"""
+
+    select_context_datatype = Bool(title=_("Select context data type?"),
+                                   description=_("If 'yes', content data type (if available) will be extracted from "
+                                                 "context"),
+                                   required=True,
+                                   default=False)
+
+    selected_datatypes = Set(title=_("Other data types"),
+                             description=_("Selected data types; leave empty for all"),
+                             value_type=Choice(vocabulary=ALL_DATA_TYPES_VOCABULARY),
+                             required=False)
+
+    def get_data_types(self, context):
+        """Get data types for given context"""
+
+    order_by = Choice(title=_("Order by"),
+                      description=_("Property to use to sort results"),
+                      vocabulary=VIEW_ORDER_VOCABULARY,
+                      required=True,
+                      default=FIRSTPUBLICATION_DATE_ORDER)
+
+    reversed_order = Bool(title=_("Reversed order?"),
+                          description=_("If 'yes', items order will be reversed"),
+                          required=True,
+                          default=True)
+
+    limit = Int(title=_("Results count limit"),
+                description=_("Maximum number of results that the view may retrieve"),
+                required=False)
+
+    is_using_context = Attribute("Check if view is using context settings")
+
+    def get_results(self, context, sort_index=None, reverse=True, limit=None, ignore_cache=False):
+        """Get results of catalog query"""
+
+
+class IWfViewFactory(Interface):
+    """View factory interface"""
+
+
+class IView(ISharedContent):
+    """Workflow managed view interface"""
+
+
+class IViewSettings(Interface):
+    """Base interface for view settings adapters"""
+
+    is_using_context = Attribute("Check if view settings are using context")
+
+
+class IViewQuery(Interface):
+    """View query interface"""
+
+    def get_results(self, context, sort_index, reverse, limit):
+        """Get results of catalog query"""
+
+
+class IViewQueryExtension(Interface):
+    """Base view query extension"""
+
+    weight = Attribute("Extension weight")
+
+
+class IViewQueryParamsExtension(IViewQueryExtension):
+    """View query extension interface"""
+
+    def get_params(self, context):
+        """Add params to catalog query"""
+
+
+class IViewQueryEsParamsExtension(IViewQueryExtension):
+    """View query parameters extension for Elasticsearch"""
+
+    def get_es_params(self, context):
+        """Add params to Elasticsearch query"""
+
+
+class IViewQueryFilterExtension(IViewQueryExtension):
+    """View query filter extension"""
+
+    def filter(self, context, items):
+        """Filter items after catalog query"""
+
+
+VIEW_REFERENCES_SETTINGS_KEY = 'pyams_content.view.references'
+
+
+ALWAYS_REFERENCE_MODE = 'always'
+IFEMPTY_REFERENCE_MODE = 'if_empty'
+
+REFERENCES_MODES = {ALWAYS_REFERENCE_MODE: _("Always include selected internal references"),
+                    IFEMPTY_REFERENCE_MODE: _("Include selected internal references only if empty")}
+
+REFERENCES_MODES_VOCABULARY = SimpleVocabulary([SimpleTerm(v, title=t)
+                                                for v, t in REFERENCES_MODES.items()])
+
+
+class IViewInternalReferencesSettings(IViewSettings, IInternalReferencesList):
+    """View internal references settings"""
+
+    references_mode = Choice(title=_("Internal references usage"),
+                             description=_("Specify how selected references are included into view results"),
+                             vocabulary=REFERENCES_MODES_VOCABULARY,
+                             required=True,
+                             default=ALWAYS_REFERENCE_MODE)
+
+    exclude_context = Bool(title=_("Exclude context?"),
+                           description=_("If 'yes', context will be excluded from results list"),
+                           required=True,
+                           default=True)
+
+
+VIEW_TAGS_SETTINGS_KEY = 'pyams_content.view.tags'
+
+
+class IViewTagsSettings(IViewSettings):
+    """View tags settings"""
+
+    select_context_tags = Bool(title=_("Select context tags?"),
+                               description=_("If 'yes', tags will be extracted from context"),
+                               required=False,
+                               default=False)
+
+    tags = ThesaurusTermsListField(title=_("Other tags"),
+                                   required=False)
+
+    def get_tags(self, context):
+        """Get all tags for given context"""
+
+    def get_tags_index(self, context):
+        """Get all tags index values for given context"""
+
+
+VIEW_THEMES_SETTINGS_KEY = 'pyams_content.view.themes'
+
+
+class IViewThemesSettings(IViewSettings):
+    """View themes settings"""
+
+    select_context_themes = Bool(title=_("Select context themes?"),
+                                 description=_("If 'yes', themes will be extracted from context"),
+                                 required=False,
+                                 default=False)
+
+    themes = ThesaurusTermsListField(title=_("Other themes"),
+                                     required=False)
+
+    def get_themes(self, context):
+        """Get all themes for given context"""
+
+    def get_themes_index(self, context):
+        """Get all themes index values for given context"""
+
+
+VIEW_COLLECTIONS_SETTINGS_KEY = 'pyams_content.view.collections'
+
+
+class IViewCollectionsSettings(IViewSettings):
+    """View collections settings"""
+
+    select_context_collections = Bool(title=_("Select context collections?"),
+                                      description=_("If 'yes', collections will be extracted from context"),
+                                      required=False,
+                                      default=False)
+
+    collections = ThesaurusTermsListField(title=_("Other collections"),
+                                          required=False)
+
+    def get_collections(self, context):
+        """Get all collections for given context"""
+
+    def get_collections_index(self, context):
+        """Get all collections index values for given context"""
+
+
+VIEWS_MERGERS_VOCABULARY = 'pyams_content.views.mergers'
+
+
+class IViewsMerger(Interface):
+    """Interface used to define views mergers
+
+    Mergers are used to merge results of several views.
+    """
+
+    def get_results(self, views, context, ignore_cache=False):
+        """Merge results of several views together"""
--- a/src/pyams_content/shared/view/interfaces/__init__.py	Mon Nov 05 13:20:10 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,261 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.shared.common.interfaces import ISharedContent, IWfSharedContent, ISharedTool, \
-    CONTENT_TYPES_VOCABULARY
-from pyams_content.shared.common.interfaces.types import ALL_DATA_TYPES_VOCABULARY
-from pyams_sequence.interfaces import IInternalReferencesList
-
-# import packages
-from pyams_thesaurus.schema import ThesaurusTermsListField
-from zope.interface import Interface, Attribute
-from zope.schema import Set, Choice, Bool, Int
-from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
-
-from pyams_content import _
-
-
-VIEW_CONTENT_TYPE = 'view'
-VIEW_CONTENT_NAME = _('View')
-
-
-CREATION_DATE_ORDER = 'created_date'
-UPDATE_DATE_ORDER = 'modified_date'
-PUBLICATION_DATE_ORDER = 'publication_date'
-FIRSTPUBLICATION_DATE_ORDER = 'first_publication_date'
-
-VIEW_ORDERS = (
-    {'id': CREATION_DATE_ORDER, 'title': _("Creation date")},
-    {'id': UPDATE_DATE_ORDER, 'title': _("Last update date")},
-    {'id': PUBLICATION_DATE_ORDER, 'title': _("Current publication date")},
-    {'id': FIRSTPUBLICATION_DATE_ORDER, 'title': _("First publication date")}
-)
-
-VIEW_ORDER_VOCABULARY = SimpleVocabulary([SimpleTerm(item['id'], title=item['title'])
-                                          for item in VIEW_ORDERS])
-
-
-class IViewsManager(ISharedTool):
-    """Views manager interface"""
-
-
-class IViewsManagerFactory(Interface):
-    """Views manager factory interface"""
-
-
-class IWfView(IWfSharedContent):
-    """View interface"""
-
-    select_context_type = Bool(title=_("Select context type?"),
-                               description=_("If 'yes', content type will be extracted from context"),
-                               required=True,
-                               default=False)
-
-    selected_content_types = Set(title=_("Other content types"),
-                                 description=_("Selected content types; leave empty for all"),
-                                 value_type=Choice(vocabulary=CONTENT_TYPES_VOCABULARY),
-                                 required=False)
-
-    def get_content_types(self, context):
-        """Get content types for given context"""
-
-    select_context_datatype = Bool(title=_("Select context data type?"),
-                                   description=_("If 'yes', content data type (if available) will be extracted from "
-                                                 "context"),
-                                   required=True,
-                                   default=False)
-
-    selected_datatypes = Set(title=_("Other data types"),
-                             description=_("Selected data types; leave empty for all"),
-                             value_type=Choice(vocabulary=ALL_DATA_TYPES_VOCABULARY),
-                             required=False)
-
-    def get_data_types(self, context):
-        """Get data types for given context"""
-
-    order_by = Choice(title=_("Order by"),
-                      description=_("Property to use to sort results"),
-                      vocabulary=VIEW_ORDER_VOCABULARY,
-                      required=True,
-                      default=FIRSTPUBLICATION_DATE_ORDER)
-
-    reversed_order = Bool(title=_("Reversed order?"),
-                          description=_("If 'yes', items order will be reversed"),
-                          required=True,
-                          default=True)
-
-    limit = Int(title=_("Results count limit"),
-                description=_("Maximum number of results that the view may retrieve"),
-                required=False)
-
-    is_using_context = Attribute("Check if view is using context settings")
-
-    def get_results(self, context, sort_index=None, reverse=True, limit=None, ignore_cache=False):
-        """Get results of catalog query"""
-
-
-class IWfViewFactory(Interface):
-    """View factory interface"""
-
-
-class IView(ISharedContent):
-    """Workflow managed view interface"""
-
-
-class IViewSettings(Interface):
-    """Base interface for view settings adapters"""
-
-    is_using_context = Attribute("Check if view settings are using context")
-
-
-class IViewQuery(Interface):
-    """View query interface"""
-
-    def get_results(self, context, sort_index, reverse, limit):
-        """Get results of catalog query"""
-
-
-class IViewQueryExtension(Interface):
-    """Base view query extension"""
-
-    weight = Attribute("Extension weight")
-
-
-class IViewQueryParamsExtension(IViewQueryExtension):
-    """View query extension interface"""
-
-    def get_params(self, context):
-        """Add params to catalog query"""
-
-
-class IViewQueryEsParamsExtension(IViewQueryExtension):
-    """View query parameters extension for Elasticsearch"""
-
-    def get_es_params(self, context):
-        """Add params to Elasticsearch query"""
-
-
-class IViewQueryFilterExtension(IViewQueryExtension):
-    """View query filter extension"""
-
-    def filter(self, context, items):
-        """Filter items after catalog query"""
-
-
-VIEW_REFERENCES_SETTINGS_KEY = 'pyams_content.view.references'
-
-
-ALWAYS_REFERENCE_MODE = 'always'
-IFEMPTY_REFERENCE_MODE = 'if_empty'
-
-REFERENCES_MODES = {ALWAYS_REFERENCE_MODE: _("Always include selected internal references"),
-                    IFEMPTY_REFERENCE_MODE: _("Include selected internal references only if empty")}
-
-REFERENCES_MODES_VOCABULARY = SimpleVocabulary([SimpleTerm(v, title=t)
-                                                for v, t in REFERENCES_MODES.items()])
-
-
-class IViewInternalReferencesSettings(IViewSettings, IInternalReferencesList):
-    """View internal references settings"""
-
-    references_mode = Choice(title=_("Internal references usage"),
-                             description=_("Specify how selected references are included into view results"),
-                             vocabulary=REFERENCES_MODES_VOCABULARY,
-                             required=True,
-                             default=ALWAYS_REFERENCE_MODE)
-
-    exclude_context = Bool(title=_("Exclude context?"),
-                           description=_("If 'yes', context will be excluded from results list"),
-                           required=True,
-                           default=True)
-
-
-VIEW_TAGS_SETTINGS_KEY = 'pyams_content.view.tags'
-
-
-class IViewTagsSettings(IViewSettings):
-    """View tags settings"""
-
-    select_context_tags = Bool(title=_("Select context tags?"),
-                               description=_("If 'yes', tags will be extracted from context"),
-                               required=False,
-                               default=False)
-
-    tags = ThesaurusTermsListField(title=_("Other tags"),
-                                   required=False)
-
-    def get_tags(self, context):
-        """Get all tags for given context"""
-
-    def get_tags_index(self, context):
-        """Get all tags index values for given context"""
-
-
-VIEW_THEMES_SETTINGS_KEY = 'pyams_content.view.themes'
-
-
-class IViewThemesSettings(IViewSettings):
-    """View themes settings"""
-
-    select_context_themes = Bool(title=_("Select context themes?"),
-                                 description=_("If 'yes', themes will be extracted from context"),
-                                 required=False,
-                                 default=False)
-
-    themes = ThesaurusTermsListField(title=_("Other themes"),
-                                     required=False)
-
-    def get_themes(self, context):
-        """Get all themes for given context"""
-
-    def get_themes_index(self, context):
-        """Get all themes index values for given context"""
-
-
-VIEW_COLLECTIONS_SETTINGS_KEY = 'pyams_content.view.collections'
-
-
-class IViewCollectionsSettings(IViewSettings):
-    """View collections settings"""
-
-    select_context_collections = Bool(title=_("Select context collections?"),
-                                      description=_("If 'yes', collections will be extracted from context"),
-                                      required=False,
-                                      default=False)
-
-    collections = ThesaurusTermsListField(title=_("Other collections"),
-                                          required=False)
-
-    def get_collections(self, context):
-        """Get all collections for given context"""
-
-    def get_collections_index(self, context):
-        """Get all collections index values for given context"""
-
-
-VIEWS_MERGERS_VOCABULARY = 'pyams_content.views.mergers'
-
-
-class IViewsMerger(Interface):
-    """Interface used to define views mergers
-
-    Mergers are used to merge results of several views.
-    """
-
-    def get_results(self, views, context, ignore_cache=False):
-        """Merge results of several views together"""