Added portlet to display content's paragraphs
authorThierry Florac <thierry.florac@onf.fr>
Thu, 06 Sep 2018 17:43:49 +0200
changeset 930 814f7c5e04d1
parent 929 1440d627e103
child 934 437971f8a969
child 936 2b31cde8c028
Added portlet to display content's paragraphs
src/pyams_content/component/paragraph/container.py
src/pyams_content/component/paragraph/interfaces/__init__.py
src/pyams_content/component/paragraph/portlet/__init__.py
src/pyams_content/component/paragraph/portlet/interfaces/__init__.py
src/pyams_content/component/paragraph/portlet/zmi/__init__.py
src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt
src/pyams_content/generations/__init__.py
src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.mo
src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po
src/pyams_content/locales/pyams_content.pot
src/pyams_content/shared/common/portlet/__init__.py
src/pyams_content/shared/common/portlet/content/__init__.py
src/pyams_content/shared/common/portlet/content/interfaces/__init__.py
src/pyams_content/shared/common/portlet/content/skin/__init__.py
src/pyams_content/shared/common/portlet/content/skin/templates/content.pt
src/pyams_content/shared/common/portlet/content/zmi/__init__.py
src/pyams_content/shared/common/portlet/content/zmi/preview.pt
--- a/src/pyams_content/component/paragraph/container.py	Thu Sep 06 14:01:08 2018 +0200
+++ b/src/pyams_content/component/paragraph/container.py	Thu Sep 06 17:43:49 2018 +0200
@@ -42,23 +42,29 @@
         self[key] = value
         self.last_id += 1
 
-    def get_visible_paragraphs(self, anchors_only=False, factories=None):
-        for paragraph in self.values():
-            if not paragraph.visible:
-                continue
-            if anchors_only and not paragraph.anchor:
-                continue
-            if factories:
-                registry = get_global_registry()
-                has_factory = False
-                for factory_name in factories:
-                    factory = registry.queryUtility(IParagraphFactory, name=factory_name)
-                    has_factory = (factory is not None) and isinstance(paragraph, factory.content_type)
-                    if has_factory:
-                        break
-                if not has_factory:
+    def get_visible_paragraphs(self, names=None, anchors_only=False, factories=None):
+        if names:
+            for name in names:
+                paragraph = self.get(name)
+                if (paragraph is not None) and paragraph.visible:
+                    yield paragraph
+        else:
+            for paragraph in self.values():
+                if not paragraph.visible:
+                    continue
+                if anchors_only and not paragraph.anchor:
                     continue
-            yield paragraph
+                if factories:
+                    registry = get_global_registry()
+                    has_factory = False
+                    for factory_name in factories:
+                        factory = registry.queryUtility(IParagraphFactory, name=factory_name)
+                        has_factory = (factory is not None) and isinstance(paragraph, factory.content_type)
+                        if has_factory:
+                            break
+                    if not has_factory:
+                        continue
+                yield paragraph
 
 
 @adapter_config(context=IParagraphContainerTarget, provides=IParagraphContainer)
--- a/src/pyams_content/component/paragraph/interfaces/__init__.py	Thu Sep 06 14:01:08 2018 +0200
+++ b/src/pyams_content/component/paragraph/interfaces/__init__.py	Thu Sep 06 17:43:49 2018 +0200
@@ -15,20 +15,18 @@
 
 # import standard library
 
-# import interfaces
-from pyams_content.features.renderer import IRenderedContent
 from zope.annotation.interfaces import IAttributeAnnotatable
+from zope.container.constraints import containers, contains
 from zope.container.interfaces import IOrderedContainer
 from zope.contentprovider.interfaces import IContentProvider
-
-# import packages
-from pyams_i18n.schema import I18nTextLineField
-from zope.container.constraints import containers, contains
 from zope.interface import Interface, Attribute
 from zope.schema import Bool, List, Choice, Set
 
 from pyams_content import _
-
+# import interfaces
+from pyams_content.features.renderer import IRenderedContent
+# import packages
+from pyams_i18n.schema import I18nTextLineField
 
 PARAGRAPH_CONTAINER_KEY = 'pyams_content.paragraph'
 
@@ -66,7 +64,7 @@
     def append(self, value):
         """Add given value to container"""
 
-    def get_visible_paragraphs(self, anchors_only=False, factories=None):
+    def get_visible_paragraphs(self, names=None, anchors_only=False, factories=None):
         """Get visible paragraphs matching given arguments"""
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/portlet/__init__.py	Thu Sep 06 17:43:49 2018 +0200
@@ -0,0 +1,79 @@
+#
+# 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
+
+from zope.interface import implementer
+from zope.schema.fieldproperty import FieldProperty
+
+from pyams_content import _
+# import packages
+from pyams_content.component.paragraph import BaseParagraph
+# import interfaces
+from pyams_content.component.paragraph.interfaces import IParagraphFactory, IParagraphContainerTarget, \
+    IParagraphContainer
+from pyams_content.component.paragraph.portlet.interfaces import IParagraphContainerPortletSettings
+from pyams_i18n.interfaces import II18n
+from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
+from pyams_utils.factory import factory_config
+from pyams_utils.interfaces import VIEW_PERMISSION
+from pyams_utils.registry import get_global_registry
+from pyams_utils.request import check_request
+from pyams_utils.traversing import get_parent
+
+PARAGRAPH_CONTAINER_PORTLET_NAME = 'pyams_content.portlet.paragraphs'
+
+
+@implementer(IParagraphContainerPortletSettings)
+@factory_config(provided=IParagraphContainerPortletSettings)
+class ParagraphContainerPortletSettings(PortletSettings):
+    """Shared content portlet persistent settings"""
+
+    paragraphs = FieldProperty(IParagraphContainerPortletSettings['paragraphs'])
+    factories = FieldProperty(IParagraphContainerPortletSettings['factories'])
+    anchors_only = FieldProperty(IParagraphContainerPortletSettings['anchors_only'])
+
+    def get_paragraphs_labels(self):
+        if not self.paragraphs:
+            yield '--'
+        else:
+            target = get_parent(self, IParagraphContainerTarget)
+            if target is not None:
+                container = IParagraphContainer(target)
+                for name in self.paragraphs:
+                    paragraph = container.get(name)
+                    if name is not None:
+                        yield II18n(paragraph).query_attribute('title') or BaseParagraph.empty_title
+
+    def get_paragraph_types_labels(self):
+        if not self.factories:
+            yield '--'
+        else:
+            request = check_request()
+            registry = get_global_registry()
+            for factory_name in self.factories:
+                factory = registry.queryUtility(IParagraphFactory, name=factory_name)
+                if factory is not None:
+                    yield request.localizer.translate(factory.name)
+
+
+@portlet_config(permission=VIEW_PERMISSION)
+class ParagraphContainerPortlet(Portlet):
+    """Shared content portlet"""
+
+    name = PARAGRAPH_CONTAINER_PORTLET_NAME
+    label = _("Content paragraphs")
+
+    settings_factory = IParagraphContainerPortletSettings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/portlet/interfaces/__init__.py	Thu Sep 06 17:43:49 2018 +0200
@@ -0,0 +1,46 @@
+#
+# 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, Set, Choice, List
+
+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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/portlet/zmi/__init__.py	Thu Sep 06 17:43:49 2018 +0200
@@ -0,0 +1,88 @@
+#
+# 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
+
+from zope.interface import Interface, alsoProvides
+
+from pyams_content import _
+# import interfaces
+from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
+from pyams_content.component.paragraph.portlet.interfaces import IParagraphContainerPortletSettings
+# import packages
+from pyams_form.form import AJAXEditForm
+from pyams_form.interfaces.form import IInnerTabForm
+from pyams_pagelet.interfaces import IPagelet
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_portal.interfaces import IPortletPreviewer
+from pyams_portal.portlet import PortletPreviewer
+from pyams_portal.zmi.portlet import PortletSettingsEditor, PortletSettingsPropertiesEditor
+from pyams_skin.layer import IPyAMSLayer
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_utils.interfaces.data import IObjectData
+from pyams_utils.traversing import get_parent
+
+
+@pagelet_config(name='properties.html', context=IParagraphContainerPortletSettings, layer=IPyAMSLayer,
+                permission=VIEW_SYSTEM_PERMISSION)
+class ParagraphContainerPortletSettingsEditor(PortletSettingsEditor):
+    """Paragraph container portlet settings editor"""
+
+    settings = IParagraphContainerPortletSettings
+
+
+@adapter_config(name='properties', context=(Interface, IPyAMSLayer, ParagraphContainerPortletSettingsEditor),
+                provides=IInnerTabForm)
+class ParagraphContainerPortletSettingsPropertiesEditor(PortletSettingsPropertiesEditor):
+    """Paragraph container portlet settings editor"""
+
+    @property
+    def fields(self):
+        fields = super(ParagraphContainerPortletSettingsPropertiesEditor, self).fields
+        container = get_parent(self.context, IParagraphContainerTarget)
+        if container is None:
+            fields = fields.omit('paragraphs')
+        return fields
+
+    def updateWidgets(self, prefix=None):
+        super(ParagraphContainerPortletSettingsPropertiesEditor, self).updateWidgets(prefix)
+        if 'paragraphs' in self.widgets:
+            widget = self.widgets['paragraphs']
+            widget.object_data = {
+                'ams-select2-placeholder': self.request.localizer.translate(
+                    _("No filter, all paragraphs selected"))
+            }
+            alsoProvides(widget, IObjectData)
+        if 'factories' in self.widgets:
+            widget = self.widgets['factories']
+            widget.object_data = {
+                'ams-select2-placeholder': self.request.localizer.translate(
+                    _("No filter, all paragraph types selected"))
+            }
+            alsoProvides(widget, IObjectData)
+
+
+@adapter_config(name='properties.json', context=(IParagraphContainerPortletSettings, IPyAMSLayer), provides=IPagelet)
+class ParagraphContainerPortletConfigurationAJAXEditor(AJAXEditForm, ParagraphContainerPortletSettingsEditor):
+    """Paragraph container portlet settings editor, JSON renderer"""
+
+
+@adapter_config(context=(Interface, IPyAMSLayer, Interface, IParagraphContainerPortletSettings),
+                provides=IPortletPreviewer)
+@template_config(template='templates/preview.pt', layer=IPyAMSLayer)
+class ParagraphContainerPortletPreviewer(PortletPreviewer):
+    """Paragraph container portlet previewer"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt	Thu Sep 06 17:43:49 2018 +0200
@@ -0,0 +1,21 @@
+<tal:var define="settings view.settings" i18n:domain="pyams_content">
+	<div class="padding-5" tal:condition="settings.paragraphs">
+		<i class="fa fa-fw fa-${'check-' if settings.paragraphs else ''}square-o"></i>
+		<span i18n:translate="">Selected paragraphs: </span>
+		<ul>
+			<li tal:repeat="label settings.get_paragraphs_labels()">${label}</li>
+		</ul>
+	</div>
+	<tal:if condition="not:settings.paragraphs">
+		<div class="padding-5" i18n:translate="">Paragraphs filters:</div>
+		<div class="padding-x-10">
+			<i class="fa fa-fw fa-${'check-' if settings.factories else ''}square-o"></i>
+			<span i18n:translate="">Selected paragraph types: </span>
+			${', '.join(settings.get_paragraph_types_labels())}
+		</div>
+		<div class="padding-x-10">
+			<i class="fa fa-fw fa-${'check-' if settings.anchors_only else ''}square-o"></i>
+			<span i18n:translate="">Only display anchors</span>
+		</div>
+	</tal:if>
+</tal:var>
--- a/src/pyams_content/generations/__init__.py	Thu Sep 06 14:01:08 2018 +0200
+++ b/src/pyams_content/generations/__init__.py	Thu Sep 06 17:43:49 2018 +0200
@@ -63,6 +63,8 @@
         'pyams_content.features.review ReviewCommentsContainer',
     'pyams_portal.portlets.content ContentPortletSettings':
         'pyams_content.portlet.content SharedContentPortletSettings',
+    'pyams_content.shared.common.portlet.content SharedContentPortletSettings':
+        'pyams_content.component.paragraph.portlet ParagraphContainerPortletSettings',
     'pyams_content.component.association.menu MenusContainer':
         'pyams_content.features.menu MenusContainer',
     'pyams_content.component.association.menu Menu':
Binary file src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.mo has changed
--- a/src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po	Thu Sep 06 14:01:08 2018 +0200
+++ b/src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po	Thu Sep 06 17:43:49 2018 +0200
@@ -5,7 +5,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-09-06 08:55+0200\n"
+"POT-Creation-Date: 2018-09-06 16:56+0200\n"
 "PO-Revision-Date: 2015-09-10 10:42+0200\n"
 "Last-Translator: Thierry Florac <tflorac@ulthar.net>\n"
 "Language-Team: French\n"
@@ -675,11 +675,11 @@
 msgid "Selected paragraph is not visible"
 msgstr "le bloc sélectionné n'est pas visible"
 
-#: src/pyams_content/component/paragraph/container.py:90
+#: src/pyams_content/component/paragraph/container.py:97
 msgid "Paragraphs"
 msgstr "Blocs de contenu"
 
-#: src/pyams_content/component/paragraph/container.py:112
+#: src/pyams_content/component/paragraph/container.py:119
 msgid "no visible paragraph"
 msgstr "aucun bloc de contenu visible"
 
@@ -750,15 +750,15 @@
 msgid "Edit key points paragraph properties"
 msgstr "Propriétés des points clés"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:65
+#: src/pyams_content/component/paragraph/zmi/__init__.py:64
 msgid "Content block types..."
 msgstr "Types de blocs de contenu"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:79
+#: src/pyams_content/component/paragraph/zmi/__init__.py:78
 msgid "Content block types"
 msgstr "Types de blocs de contenu"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:89
+#: src/pyams_content/component/paragraph/zmi/__init__.py:88
 msgid ""
 "You can define which types of paragraphs are allowed in this container.\n"
 "\n"
@@ -777,13 +777,13 @@
 "REMARQUE : supprimer des types de la liste des types de blocs autorisés sera "
 "sans effet sur les contenus existants."
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:207
+#: src/pyams_content/component/paragraph/zmi/__init__.py:206
 #: src/pyams_content/shared/common/zmi/templates/preview-input.pt:39
 #: src/pyams_content/features/preview/zmi/__init__.py:45
 msgid "Preview"
 msgstr "Aperçu"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:212
+#: src/pyams_content/component/paragraph/zmi/__init__.py:211
 #: src/pyams_content/shared/common/zmi/workflow.py:123
 #: src/pyams_content/shared/common/zmi/workflow.py:210
 #: src/pyams_content/shared/common/zmi/workflow.py:250
@@ -802,15 +802,15 @@
 msgid "Cancel"
 msgstr "Annuler"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:214
+#: src/pyams_content/component/paragraph/zmi/__init__.py:213
 msgid "Submit"
 msgstr "Enregistrer"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:195
+#: src/pyams_content/component/paragraph/zmi/__init__.py:194
 msgid "Paragraph was correctly added."
 msgstr "Le bloc a été ajouté."
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:254
+#: src/pyams_content/component/paragraph/zmi/__init__.py:253
 msgid ""
 "You changed renderer selection. Don't omit to update new renderer "
 "properties..."
@@ -1009,6 +1009,68 @@
 msgid "Edit header paragraph properties"
 msgstr "Propriétés du chapô"
 
+#: src/pyams_content/component/paragraph/portlet/__init__.py:79
+msgid "Content paragraphs"
+msgstr "Blocs de contenu"
+
+#: src/pyams_content/component/paragraph/portlet/zmi/__init__.py:68
+msgid "No filter, all paragraphs selected"
+msgstr "Pas de filtre, tous les blocs sont acceptés"
+
+#: src/pyams_content/component/paragraph/portlet/zmi/__init__.py:75
+msgid "No filter, all paragraph types selected"
+msgstr "Pas de filtre, tous les types de blocs sont acceptés"
+
+#: src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:4
+msgid "Selected paragraphs:"
+msgstr "Blocs sélectionnés :"
+
+#: src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:10
+msgid "Paragraphs filters:"
+msgstr "Filtrage des blocs :"
+
+#: src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:13
+msgid "Selected paragraph types:"
+msgstr "Types de blocs :"
+
+#: src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:18
+msgid "Only display anchors"
+msgstr "Ne sélectionner que les ancres"
+
+#: src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:31
+msgid "Selected paragraphs"
+msgstr "Blocs sélectionnés"
+
+#: src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:32
+msgid ""
+"List of selected paragraphs; an empty selection means that all paragraphs "
+"will be selectable by following filters; otherwise, this selection will have "
+"priority"
+msgstr ""
+"Liste des blocs sélectionnés ; si la sélection est vide, tous les blocs de contenu "
+"pourront être sélectionnés via les filtres ci-dessous ; dans le cas contraire, cette "
+"sélection devient prioritaire et les autres filtres ne sont pas appliqués"
+
+#: src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:38
+msgid "Paragraph types"
+msgstr "Types de blocs"
+
+#: src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:39
+msgid ""
+"Select list of paragraph types you want to include; an empty selection means "
+"that all paragraphs types will be selected"
+msgstr ""
+"Liste des types de blocs que vous souhaitez sélectionner ; si la sélection est vide, "
+"tous les types de blocs seront pris en compte"
+
+#: src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:44
+msgid "Anchors only?"
+msgstr "Ancres seulement ?"
+
+#: src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:45
+msgid "If 'yes', only paragraphs set as 'anchors' will be selected"
+msgstr "Si 'oui', seuls les blocs définis comme ancres de navigation seront sélectionnés"
+
 #: src/pyams_content/component/paragraph/interfaces/milestone.py:41
 msgid "Is this milestone visible in front-office?"
 msgstr "Si 'non', ce jalon ne sera pas présenté aux internautes"
@@ -3019,18 +3081,6 @@
 msgid "This content is already retired and not visible."
 msgstr "Ce contenu est déjà retiré et n'est plus visible des internautes."
 
-#: src/pyams_content/shared/common/portlet/content/__init__.py:44
-msgid "Context content"
-msgstr "Contenu partagé"
-
-#: src/pyams_content/shared/common/portlet/content/zmi/preview.pt:2
-msgid "This is where the content will be displayed!!"
-msgstr "C'est ici que seront affichés les éléments du contenu."
-
-#: src/pyams_content/shared/common/portlet/content/skin/__init__.py:39
-msgid "Default content renderer"
-msgstr "Par défaut"
-
 #: src/pyams_content/shared/common/interfaces/types.py:43
 #: src/pyams_content/shared/form/zmi/field.py:156
 msgid "Name"
@@ -4982,7 +5032,7 @@
 msgid "List of selected pictograms which will be available to shared contents"
 msgstr "Liste des pictogrammes proposés dans les contenus partagés"
 
-#: src/pyams_content/features/renderer/zmi/__init__.py:72
+#: src/pyams_content/features/renderer/zmi/__init__.py:71
 #: src/pyams_content/features/renderer/zmi/templates/renderer-input.pt:4
 msgid "Edit renderer properties"
 msgstr "Propriétés de ce mode de rendu"
@@ -5707,6 +5757,15 @@
 msgid "Hidden header"
 msgstr "Ne pas afficher d'en-tête de pages"
 
+#~ msgid "Context content"
+#~ msgstr "Contenu partagé"
+
+#~ msgid "This is where the content will be displayed!!"
+#~ msgstr "C'est ici que seront affichés les éléments du contenu."
+
+#~ msgid "Default content renderer"
+#~ msgstr "Par défaut"
+
 #~ msgid "Form header"
 #~ msgstr "En-tête du formulaire"
 
@@ -5823,9 +5882,6 @@
 #~ msgid "Paragraphs types..."
 #~ msgstr "Types de paragraphes"
 
-#~ msgid "Paragraphs types"
-#~ msgstr "Types de paragraphes"
-
 #~ msgid "Paragraphs..."
 #~ msgstr "Paragraphes"
 
--- a/src/pyams_content/locales/pyams_content.pot	Thu Sep 06 14:01:08 2018 +0200
+++ b/src/pyams_content/locales/pyams_content.pot	Thu Sep 06 17:43:49 2018 +0200
@@ -6,7 +6,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-09-06 08:55+0200\n"
+"POT-Creation-Date: 2018-09-06 16:56+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -643,11 +643,11 @@
 msgid "Selected paragraph is not visible"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/container.py:90
+#: ./src/pyams_content/component/paragraph/container.py:97
 msgid "Paragraphs"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/container.py:112
+#: ./src/pyams_content/component/paragraph/container.py:119
 msgid "no visible paragraph"
 msgstr ""
 
@@ -718,15 +718,15 @@
 msgid "Edit key points paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:65
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:64
 msgid "Content block types..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:79
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:78
 msgid "Content block types"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:89
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:88
 msgid ""
 "You can define which types of paragraphs are allowed in this container.\n"
 "\n"
@@ -735,13 +735,13 @@
 "NOTICE: removing types from allowed types list will have no effect on already created contents!"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:207
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:206
 #: ./src/pyams_content/shared/common/zmi/templates/preview-input.pt:39
 #: ./src/pyams_content/features/preview/zmi/__init__.py:45
 msgid "Preview"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:212
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:211
 #: ./src/pyams_content/shared/common/zmi/workflow.py:123
 #: ./src/pyams_content/shared/common/zmi/workflow.py:210
 #: ./src/pyams_content/shared/common/zmi/workflow.py:250
@@ -760,15 +760,15 @@
 msgid "Cancel"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:214
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:213
 msgid "Submit"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:195
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:194
 msgid "Paragraph was correctly added."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:254
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:253
 msgid ""
 "You changed renderer selection. Don't omit to update new renderer "
 "properties..."
@@ -963,6 +963,63 @@
 msgid "Edit header paragraph properties"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/portlet/__init__.py:79
+msgid "Content paragraphs"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/zmi/__init__.py:68
+msgid "No filter, all paragraphs selected"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/zmi/__init__.py:75
+msgid "No filter, all paragraph types selected"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:4
+msgid "Selected paragraphs:"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:10
+msgid "Paragraphs filters:"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:13
+msgid "Selected paragraph types:"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/zmi/templates/preview.pt:18
+msgid "Only display anchors"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:31
+msgid "Selected paragraphs"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:32
+msgid ""
+"List of selected paragraphs; an empty selection means that all paragraphs "
+"will be selectable by following filters; otherwise, this selection will have "
+"priority"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:38
+msgid "Paragraph types"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:39
+msgid ""
+"Select list of paragraph types you want to include; an empty selection means "
+"that all paragraphs types will be selected"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:44
+msgid "Anchors only?"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/portlet/interfaces/__init__.py:45
+msgid "If 'yes', only paragraphs set as 'anchors' will be selected"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/milestone.py:41
 msgid "Is this milestone visible in front-office?"
 msgstr ""
@@ -2853,18 +2910,6 @@
 msgid "This content is already retired and not visible."
 msgstr ""
 
-#: ./src/pyams_content/shared/common/portlet/content/__init__.py:44
-msgid "Context content"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/portlet/content/zmi/preview.pt:2
-msgid "This is where the content will be displayed!!"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/portlet/content/skin/__init__.py:39
-msgid "Default content renderer"
-msgstr ""
-
 #: ./src/pyams_content/shared/common/interfaces/types.py:43
 #: ./src/pyams_content/shared/form/zmi/field.py:156
 msgid "Name"
@@ -4682,7 +4727,7 @@
 msgid "List of selected pictograms which will be available to shared contents"
 msgstr ""
 
-#: ./src/pyams_content/features/renderer/zmi/__init__.py:72
+#: ./src/pyams_content/features/renderer/zmi/__init__.py:71
 #: ./src/pyams_content/features/renderer/zmi/templates/renderer-input.pt:4
 msgid "Edit renderer properties"
 msgstr ""
--- a/src/pyams_content/shared/common/portlet/__init__.py	Thu Sep 06 14:01:08 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +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
-
-# import packages
--- a/src/pyams_content/shared/common/portlet/content/__init__.py	Thu Sep 06 14:01:08 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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.shared.common.portlet.content.interfaces import ISharedContentPortletSettings
-from pyams_utils.interfaces import VIEW_PERMISSION
-
-# import packages
-from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
-from pyams_utils.factory import factory_config
-from zope.interface import implementer
-
-from pyams_content import _
-
-
-SHARED_CONTENT_PORTLET_NAME = 'pyams_content.portlet.content'
-
-
-@implementer(ISharedContentPortletSettings)
-@factory_config(provided=ISharedContentPortletSettings)
-class SharedContentPortletSettings(PortletSettings):
-    """Shared content portlet persistent settings"""
-
-
-@portlet_config(permission=VIEW_PERMISSION)
-class SharedContentPortlet(Portlet):
-    """Shared content portlet"""
-
-    name = SHARED_CONTENT_PORTLET_NAME
-    label = _("Context content")
-
-    settings_factory = ISharedContentPortletSettings
--- a/src/pyams_content/shared/common/portlet/content/interfaces/__init__.py	Thu Sep 06 14:01:08 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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_portal.interfaces import IPortletSettings
-
-# import packages
-
-
-class ISharedContentPortletSettings(IPortletSettings):
-    """Shared content portlet settings interface"""
--- a/src/pyams_content/shared/common/portlet/content/skin/__init__.py	Thu Sep 06 14:01:08 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.shared.common.portlet.content.interfaces import ISharedContentPortletSettings
-from pyams_content.features.renderer.interfaces import ISharedContentRenderer
-from pyams_portal.interfaces import IPortalContext, IPortletRenderer
-from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_portal.portlet import PortletRenderer
-from pyams_template.template import template_config
-from pyams_utils.adapter import adapter_config
-from zope.interface import Interface
-
-from pyams_content import _
-
-
-@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, ISharedContentPortletSettings),
-                provides=IPortletRenderer)
-@template_config(template='templates/content.pt', layer=IPyAMSLayer)
-class SharedContentPortletRenderer(PortletRenderer):
-    """Shared content portlet renderer"""
-
-    label = _("Default content renderer")
-
-    def __init__(self, context, request, view, settings):
-        super(SharedContentPortletRenderer, self).__init__(context, request, view, settings)
-        registry = self.request.registry
-        self.renderers = [adapter for name, adapter in sorted(registry.getAdapters((self.context, self.request),
-                                                                                   ISharedContentRenderer),
-                                                              key=lambda x: x[1].weight)]
-
-    def update(self):
-        super(SharedContentPortletRenderer, self).update()
-        [renderer.update() for renderer in self.renderers]
--- a/src/pyams_content/shared/common/portlet/content/skin/templates/content.pt	Thu Sep 06 14:01:08 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-<div class="edito"
-	 tal:condition="view.renderers">
-	<tal:loop repeat="renderer view.renderers">
-		<tal:if condition="renderer"
-				content="structure renderer.render()">Renderer</tal:if>
-	</tal:loop>
-</div>
--- a/src/pyams_content/shared/common/portlet/content/zmi/__init__.py	Thu Sep 06 14:01:08 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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.shared.common.portlet.content.interfaces import ISharedContentPortletSettings
-from pyams_pagelet.interfaces import IPagelet
-from pyams_portal.interfaces import IPortletPreviewer
-from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
-
-# import packages
-from pyams_form.form import AJAXEditForm
-from pyams_pagelet.pagelet import pagelet_config
-from pyams_portal.portlet import PortletPreviewer
-from pyams_portal.zmi.portlet import PortletSettingsEditor
-from pyams_template.template import template_config
-from pyams_utils.adapter import adapter_config
-from zope.interface import Interface
-
-
-@pagelet_config(name='properties.html', context=ISharedContentPortletSettings, layer=IPyAMSLayer,
-                permission=VIEW_SYSTEM_PERMISSION)
-class SharedContentPortletSettingsEditor(PortletSettingsEditor):
-    """Shared content portlet settings editor"""
-
-    settings = ISharedContentPortletSettings
-
-
-@adapter_config(name='properties.json', context=(ISharedContentPortletSettings, IPyAMSLayer), provides=IPagelet)
-class SharedContentPortletConfigurationAJAXEditor(AJAXEditForm, SharedContentPortletSettingsEditor):
-    """Shared content portlet settings editor, JSON renderer"""
-
-
-@adapter_config(context=(Interface, IPyAMSLayer, Interface, ISharedContentPortletSettings),
-                provides=IPortletPreviewer)
-@template_config(template='preview.pt', layer=IPyAMSLayer)
-class SharedContentPortletPreviewer(PortletPreviewer):
-    """Shared content portlet previewer"""
--- a/src/pyams_content/shared/common/portlet/content/zmi/preview.pt	Thu Sep 06 14:01:08 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<tal:var define="settings view.settings" i18n:domain="pyams_content">
-	<span class="padding-5" i18n:translate="">This is where the content will be displayed!!</span>
-</tal:var>