merge default doc-dc
authorDamien Correia
Fri, 25 May 2018 17:07:21 +0200
branchdoc-dc
changeset 653 238b75a21396
parent 652 b438528e5bb3 (current diff)
parent 559 5ddb2d0bef4b (diff)
child 654 339bbc810b91
merge default
--- a/src/pyams_content/component/illustration/__init__.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/component/illustration/__init__.py	Fri May 25 17:07:21 2018 +0200
@@ -21,7 +21,6 @@
 from pyams_content.features.checker.interfaces import IContentChecker, MISSING_VALUE, MISSING_LANG_VALUE
 from pyams_file.interfaces import IFileInfo, IImage, IResponsiveImage
 from pyams_i18n.interfaces import INegotiator, II18n, II18nManager
-from zope.annotation.interfaces import IAnnotations
 from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent
 from zope.location.interfaces import ISublocations
 from zope.traversing.interfaces import ITraversable
@@ -31,7 +30,7 @@
 from pyams_content.features.checker import BaseContentChecker
 from pyams_content.features.renderer import RenderedContentMixin, RenderersVocabulary
 from pyams_i18n.property import I18nFileProperty
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.factory import factory_config
 from pyams_utils.registry import query_utility, get_utility
 from pyams_utils.request import check_request
@@ -42,7 +41,6 @@
 from zope.container.contained import Contained
 from zope.interface import implementer, alsoProvides
 from zope.lifecycleevent import ObjectCreatedEvent, ObjectAddedEvent
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 
 from pyams_content import _
@@ -75,15 +73,13 @@
 @adapter_config(context=IIllustrationTarget, provides=IIllustration)
 def illustration_factory(context):
     """Illustration factory"""
-    annotations = IAnnotations(context)
-    illustration = annotations.get(ILLUSTRATION_KEY)
-    if illustration is None:
-        illustration = annotations[ILLUSTRATION_KEY] = Illustration()
-        registry = get_current_registry()
-        registry.notify(ObjectCreatedEvent(illustration))
-        locate(illustration, context, '++illustration++')
-        registry.notify(ObjectAddedEvent(illustration, context, '++illustration++'))
-    return illustration
+
+    def illustration_callback(illustration):
+        get_current_registry().notify(ObjectAddedEvent(illustration, context, illustration.__name__))
+
+    return get_annotation_adapter(context, ILLUSTRATION_KEY, Illustration,
+                                  name='++illustration++',
+                                  callback=illustration_callback)
 
 
 def update_illustration_properties(illustration):
--- a/src/pyams_content/component/paragraph/keynumber.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/component/paragraph/keynumber.py	Fri May 25 17:07:21 2018 +0200
@@ -24,7 +24,6 @@
 from pyams_content.features.checker.interfaces import IContentChecker, MISSING_VALUE, MISSING_LANG_VALUE
 from pyams_form.interfaces.form import IFormContextPermissionChecker
 from pyams_i18n.interfaces import II18n, II18nManager, INegotiator
-from zope.annotation.interfaces import IAnnotations
 from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent
 from zope.location.interfaces import ISublocations
 from zope.traversing.interfaces import ITraversable
@@ -34,7 +33,7 @@
 from pyams_content.component.paragraph import BaseParagraph, BaseParagraphFactory, BaseParagraphContentChecker
 from pyams_content.features.checker import BaseContentChecker
 from pyams_content.features.renderer import RenderersVocabulary
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.factory import factory_config
 from pyams_utils.registry import get_current_registry, get_utility, utility_config
 from pyams_utils.request import check_request
@@ -158,13 +157,7 @@
 @adapter_config(context=IKeyNumberContainerTarget, provides=IKeyNumberContainer)
 def keynumber_container_factory(target):
     """Key number container factory"""
-    annotations = IAnnotations(target)
-    container = annotations.get(KEYNUMBER_CONTAINER_KEY)
-    if container is None:
-        container = annotations[KEYNUMBER_CONTAINER_KEY] = KeyNumberContainer()
-        get_current_registry().notify(ObjectCreatedEvent(container))
-        locate(container, target, '++keynumbers++')
-    return container
+    return get_annotation_adapter(target, KEYNUMBER_CONTAINER_KEY, KeyNumberContainer, name='++keynumbers++')
 
 
 @adapter_config(name='keynumbers', context=IKeyNumberContainerTarget, provides=ITraversable)
--- a/src/pyams_content/component/paragraph/milestone.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/component/paragraph/milestone.py	Fri May 25 17:07:21 2018 +0200
@@ -25,7 +25,6 @@
 from pyams_content.features.checker.interfaces import IContentChecker, MISSING_VALUE, MISSING_LANG_VALUE, ERROR_VALUE
 from pyams_form.interfaces.form import IFormContextPermissionChecker
 from pyams_i18n.interfaces import II18n, II18nManager, INegotiator
-from zope.annotation.interfaces import IAnnotations
 from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent
 from zope.location.interfaces import ISublocations
 from zope.traversing.interfaces import ITraversable
@@ -35,7 +34,7 @@
 from pyams_content.component.paragraph import BaseParagraph, BaseParagraphFactory, BaseParagraphContentChecker
 from pyams_content.features.checker import BaseContentChecker
 from pyams_content.features.renderer import RenderersVocabulary
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.factory import factory_config
 from pyams_utils.registry import get_current_registry, get_utility, utility_config
 from pyams_utils.request import check_request
@@ -174,13 +173,7 @@
 @adapter_config(context=IMilestoneContainerTarget, provides=IMilestoneContainer)
 def milestone_container_factory(target):
     """Milestone container factory"""
-    annotations = IAnnotations(target)
-    container = annotations.get(MILESTONE_CONTAINER_KEY)
-    if container is None:
-        container = annotations[MILESTONE_CONTAINER_KEY] = MilestoneContainer()
-        get_current_registry().notify(ObjectCreatedEvent(container))
-        locate(container, target, '++milestones++')
-    return container
+    return get_annotation_adapter(target, MILESTONE_CONTAINER_KEY, MilestoneContainer, name='++milestones++')
 
 
 @adapter_config(name='milestones', context=IMilestoneContainerTarget, provides=ITraversable)
--- a/src/pyams_content/component/paragraph/pictogram.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/component/paragraph/pictogram.py	Fri May 25 17:07:21 2018 +0200
@@ -26,7 +26,6 @@
 from pyams_content.reference.pictograms.interfaces import IPictogramTable
 from pyams_form.interfaces.form import IFormContextPermissionChecker
 from pyams_i18n.interfaces import II18n, II18nManager, INegotiator
-from zope.annotation import IAnnotations
 from zope.lifecycleevent import IObjectAddedEvent, ObjectModifiedEvent, ObjectCreatedEvent
 from zope.location.interfaces import ISublocations
 from zope.traversing.interfaces import ITraversable
@@ -36,7 +35,7 @@
 from pyams_content.component.paragraph import BaseParagraph, BaseParagraphFactory, BaseParagraphContentChecker
 from pyams_content.features.checker import BaseContentChecker
 from pyams_content.features.renderer import RenderersVocabulary
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.factory import factory_config
 from pyams_utils.registry import query_utility, get_current_registry, get_utility, utility_config
 from pyams_utils.request import check_request
@@ -164,13 +163,7 @@
 @adapter_config(context=IPictogramContainerTarget, provides=IPictogramContainer)
 def pictogram_container_factory(target):
     """Pictogram container factory"""
-    annotations = IAnnotations(target)
-    container = annotations.get(PICTOGRAM_CONTAINER_KEY)
-    if container is None:
-        container = annotations[PICTOGRAM_CONTAINER_KEY] = PictogramContainer()
-        get_current_registry().notify(ObjectCreatedEvent(container))
-        locate(container, target, '++pictos++')
-    return container
+    return get_annotation_adapter(target, PICTOGRAM_CONTAINER_KEY, PictogramContainer, name='++pictos++')
 
 
 @adapter_config(name='pictos', context=IPictogramContainerTarget, provides=ITraversable)
--- a/src/pyams_content/component/theme/__init__.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/component/theme/__init__.py	Fri May 25 17:07:21 2018 +0200
@@ -19,17 +19,13 @@
 from pyams_content.component.theme.interfaces import IThemesManagerTarget, IThemesManager, THEMES_MANAGER_KEY, \
     IThemesTarget, IThemesInfo, THEMES_INFO_KEY
 from pyams_content.features.checker.interfaces import IContentChecker, ERROR_VALUE
-from zope.annotation.interfaces import IAnnotations
 
 # import packages
 from persistent import Persistent
 from pyams_content.features.checker import BaseContentChecker
-from pyams_utils.adapter import adapter_config
-from pyramid.threadlocal import get_current_registry
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
 from zope.container.contained import Contained
 from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 
 from pyams_content import _
@@ -46,13 +42,7 @@
 @adapter_config(context=IThemesManagerTarget, provides=IThemesManager)
 def themes_manager_factory(target):
     """Themes manager factory"""
-    annotations = IAnnotations(target)
-    manager = annotations.get(THEMES_MANAGER_KEY)
-    if manager is None:
-        manager = annotations[THEMES_MANAGER_KEY] = ThemesManager()
-        get_current_registry().notify(ObjectCreatedEvent(manager))
-        locate(manager, target, '++themes-manager++')
-    return manager
+    return get_annotation_adapter(target, THEMES_MANAGER_KEY, ThemesManager, name='++themes-manager++')
 
 
 @implementer(IThemesInfo)
@@ -65,13 +55,7 @@
 @adapter_config(context=IThemesTarget, provides=IThemesInfo)
 def themes_info_factory(target):
     """Themes info factory"""
-    annotations = IAnnotations(target)
-    info = annotations.get(THEMES_INFO_KEY)
-    if info is None:
-        info = annotations[THEMES_INFO_KEY] = ThemesInfo()
-        get_current_registry().notify(ObjectCreatedEvent(info))
-        locate(info, target, '++themes++')
-    return info
+    return get_annotation_adapter(target, THEMES_INFO_KEY, ThemesInfo, name='++themes++')
 
 
 @adapter_config(name='themes', context=IThemesTarget, provides=IContentChecker)
--- a/src/pyams_content/component/theme/portlet.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/component/theme/portlet.py	Fri May 25 17:07:21 2018 +0200
@@ -18,15 +18,13 @@
 # import interfaces
 from pyams_content.component.theme.interfaces import IPortletThemesSettings, IPortletThemesSettingsTarget, \
     PORTLET_SETTINGS_THEMES_KEY
-from zope.annotation.interfaces import IAnnotations
 from zope.traversing.interfaces import ITraversable
 
 # import packages
 from persistent import Persistent
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from zope.container.contained import Contained
 from zope.interface import implementer
-from zope.location import locate
 
 
 @implementer(IPortletThemesSettings)
@@ -37,12 +35,7 @@
 @adapter_config(context=IPortletThemesSettingsTarget, provides=IPortletThemesSettings)
 def portlet_themes_settings_factory(context):
     """Portlet themes settings adapter"""
-    annotations = IAnnotations(context)
-    settings = annotations.get(PORTLET_SETTINGS_THEMES_KEY)
-    if settings is None:
-        settings = annotations[PORTLET_SETTINGS_THEMES_KEY] = PortletThemesSettings()
-        locate(settings, context, '++themes++')
-    return settings
+    return get_annotation_adapter(context, PORTLET_SETTINGS_THEMES_KEY, PortletThemesSettings, name='++themes++')
 
 
 @adapter_config(name='themes', context=IPortletThemesSettingsTarget, provides=ITraversable)
--- a/src/pyams_content/component/video/__init__.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/component/video/__init__.py	Fri May 25 17:07:21 2018 +0200
@@ -9,8 +9,6 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
-from pyams_i18n.interfaces import II18nManager, INegotiator, II18n
-from pyams_utils.traversing import get_parent
 
 __docformat__ = 'restructuredtext'
 
@@ -21,15 +19,15 @@
 # import interfaces
 from pyams_content.component.video.interfaces import IExternalVideo, IExternalVideoProvider, IExternalVideoSettings
 from pyams_content.features.checker.interfaces import IContentChecker, MISSING_VALUE, MISSING_LANG_VALUE
-from zope.annotation import IAnnotations
+from pyams_i18n.interfaces import II18nManager, INegotiator, II18n
 
 # import packages
 from pyams_content.features.checker import BaseContentChecker, VALUE_OK
-from pyams_utils.adapter import adapter_config
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
 from pyams_utils.registry import query_utility, get_utility
+from pyams_utils.traversing import get_parent
 from zope.container.contained import Contained
 from zope.interface import implementer
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 
 from pyams_content import _
@@ -62,15 +60,10 @@
     """External video settings factory"""
     if not context.provider_name:
         return None
-    annotations = IAnnotations(context)
+    provider = context.get_provider()
     settings_key = EXTERNAL_VIDEO_SETTINGS_KEY.format(context.provider_name.lower())
-    settings = annotations.get(settings_key)
-    if settings is None:
-        provider = context.get_provider()
-        if provider is not None:
-            settings = annotations[settings_key] = IExternalVideoSettings(provider)
-            locate(settings, context)
-    return settings
+    return get_annotation_adapter(context, settings_key,
+                                  factory=lambda: IExternalVideoSettings(provider))
 
 
 @adapter_config(context=IExternalVideo, provides=IContentChecker)
--- a/src/pyams_content/features/alert/container.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/features/alert/container.py	Fri May 25 17:07:21 2018 +0200
@@ -17,17 +17,14 @@
 
 # import interfaces
 from pyams_content.features.alert.interfaces import IAlertContainer, IAlertItem, IAlertTarget, ALERT_CONTAINER_KEY
-from zope.annotation.interfaces import IAnnotations
 from zope.location.interfaces import ISublocations
 from zope.traversing.interfaces import ITraversable
 
 # import packages
 from pyams_catalog.utils import index_object
-from pyams_utils.adapter import adapter_config, ContextAdapter
-from pyams_utils.registry import get_current_registry
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from zope.container.ordered import OrderedContainer
 from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent
 from zope.location import locate
 
 
@@ -55,13 +52,7 @@
 @adapter_config(context=IAlertTarget, provides=IAlertContainer)
 def alert_container_factory(target):
     """Alert container factory"""
-    annotations = IAnnotations(target)
-    container = annotations.get(ALERT_CONTAINER_KEY)
-    if container is None:
-        container = annotations[ALERT_CONTAINER_KEY] = AlertContainer()
-        get_current_registry().notify(ObjectCreatedEvent(container))
-        locate(container, target, '++alert++')
-    return container
+    return get_annotation_adapter(target, ALERT_CONTAINER_KEY, AlertContainer, name='++alert++')
 
 
 @adapter_config(name='alert', context=IAlertTarget, provides=ITraversable)
--- a/src/pyams_content/features/review/__init__.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/features/review/__init__.py	Fri May 25 17:07:21 2018 +0200
@@ -29,7 +29,6 @@
 from pyams_security.interfaces.notification import INotificationSettings
 from pyramid_chameleon.interfaces import IChameleonTranslate
 from pyramid_mailer.interfaces import IMailer
-from zope.annotation.interfaces import IAnnotations
 from zope.location.interfaces import ISublocations
 from zope.traversing.interfaces import ITraversable
 
@@ -37,7 +36,7 @@
 from persistent import Persistent
 from pyams_mail.message import HTMLMessage
 from pyams_security.principal import MissingPrincipal
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.container import BTreeOrderedContainer
 from pyams_utils.registry import query_utility, get_utility
 from pyams_utils.request import check_request, query_request
@@ -47,7 +46,6 @@
 from pyramid_chameleon.zpt import PageTemplateFile
 from zope.container.contained import Contained
 from zope.interface import implementer
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 
 from pyams_content import _
@@ -97,12 +95,8 @@
 @adapter_config(context=IReviewTarget, provides=IReviewComments)
 def shared_content_review_comments_factory(context):
     """Shared content review comments factory"""
-    annotations = IAnnotations(context)
-    comments = annotations.get(REVIEW_COMMENTS_ANNOTATION_KEY)
-    if comments is None:
-        comments = annotations[REVIEW_COMMENTS_ANNOTATION_KEY] = ReviewCommentsContainer()
-        locate(comments, context, '++review-comments++')
-    return comments
+    return get_annotation_adapter(context, REVIEW_COMMENTS_ANNOTATION_KEY, ReviewCommentsContainer,
+                                  name='++review-comments++')
 
 
 @adapter_config(name='review-comments', context=IReviewTarget, provides=ITraversable)
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	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po	Fri May 25 17:07:21 2018 +0200
@@ -5,7 +5,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-05-15 16:31+0200\n"
+"POT-Creation-Date: 2018-05-24 09:43+0200\n"
 "PO-Revision-Date: 2015-09-10 10:42+0200\n"
 "Last-Translator: Thierry Florac <tflorac@ulthar.net>\n"
 "Language-Team: French\n"
@@ -81,13 +81,13 @@
 msgid "Medias gallery"
 msgstr "Galerie de médias"
 
-#: src/pyams_content/component/gallery/__init__.py:161
+#: src/pyams_content/component/gallery/__init__.py:159
 msgid "Gallery"
 msgstr "Galerie de médias"
 
 #: src/pyams_content/component/gallery/zmi/file.py:58
 #: src/pyams_content/component/gallery/zmi/file.py:69
-#: src/pyams_content/component/gallery/zmi/paragraph.py:176
+#: src/pyams_content/component/gallery/zmi/paragraph.py:174
 msgid "Add media(s)"
 msgstr "Ajouter des médias"
 
@@ -107,15 +107,15 @@
 msgid "Audio content"
 msgstr "Contenu audio associé"
 
-#: src/pyams_content/component/gallery/zmi/paragraph.py:58
+#: src/pyams_content/component/gallery/zmi/paragraph.py:56
 msgid "Medias gallery..."
 msgstr "Galerie de médias"
 
-#: src/pyams_content/component/gallery/zmi/paragraph.py:69
+#: src/pyams_content/component/gallery/zmi/paragraph.py:67
 msgid "Add new gallery"
 msgstr "Ajout d'une galerie de médias"
 
-#: src/pyams_content/component/gallery/zmi/paragraph.py:101
+#: src/pyams_content/component/gallery/zmi/paragraph.py:99
 msgid "Edit gallery properties"
 msgstr "Propriétés de la galerie de médias"
 
@@ -131,8 +131,8 @@
 #: src/pyams_content/component/gallery/interfaces/__init__.py:61
 #: src/pyams_content/component/extfile/interfaces/__init__.py:44
 #: src/pyams_content/component/illustration/interfaces/__init__.py:56
-#: src/pyams_content/component/paragraph/interfaces/video.py:48
-#: src/pyams_content/component/paragraph/interfaces/verbatim.py:44
+#: src/pyams_content/component/paragraph/interfaces/video.py:47
+#: src/pyams_content/component/paragraph/interfaces/verbatim.py:43
 #: src/pyams_content/component/video/interfaces/__init__.py:52
 msgid "Author"
 msgstr "Auteur"
@@ -140,7 +140,7 @@
 #: src/pyams_content/component/gallery/zmi/interfaces.py:37
 #: src/pyams_content/component/gallery/interfaces/__init__.py:62
 #: src/pyams_content/component/extfile/interfaces/__init__.py:45
-#: src/pyams_content/component/paragraph/interfaces/video.py:49
+#: src/pyams_content/component/paragraph/interfaces/video.py:48
 #: src/pyams_content/component/video/interfaces/__init__.py:53
 msgid "Name of document's author"
 msgstr "Sous la forme \"Prénom Nom / Organisme\""
@@ -216,7 +216,7 @@
 #: src/pyams_content/component/gallery/interfaces/__init__.py:98
 #: src/pyams_content/component/extfile/interfaces/__init__.py:40
 #: src/pyams_content/component/illustration/interfaces/__init__.py:52
-#: src/pyams_content/component/paragraph/interfaces/video.py:44
+#: src/pyams_content/component/paragraph/interfaces/video.py:43
 #: src/pyams_content/component/links/interfaces/__init__.py:37
 #: src/pyams_content/component/video/interfaces/__init__.py:48
 #: src/pyams_content/shared/common/interfaces/__init__.py:145
@@ -273,9 +273,9 @@
 
 #: src/pyams_content/component/gallery/interfaces/__init__.py:94
 #: src/pyams_content/component/extfile/interfaces/__init__.py:36
-#: src/pyams_content/component/paragraph/zmi/milestone.py:257
+#: src/pyams_content/component/paragraph/zmi/milestone.py:246
 #: src/pyams_content/component/paragraph/zmi/container.py:224
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:46
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:45
 #: src/pyams_content/component/links/zmi/reverse.py:71
 #: src/pyams_content/shared/common/zmi/dashboard.py:109
 #: src/pyams_content/shared/common/zmi/templates/advanced-search.pt:188
@@ -314,15 +314,15 @@
 #: src/pyams_content/component/extfile/__init__.py:223
 #: src/pyams_content/component/extfile/__init__.py:240
 #: src/pyams_content/shared/imagemap/interfaces/__init__.py:66
-#: src/pyams_content/shared/logo/interfaces/__init__.py:47
+#: src/pyams_content/shared/logo/interfaces/__init__.py:46
 #: src/pyams_content/reference/pictograms/interfaces/__init__.py:44
 msgid "Image"
 msgstr "Image"
 
 #: src/pyams_content/component/extfile/__init__.py:255
 #: src/pyams_content/component/extfile/__init__.py:260
-#: src/pyams_content/component/paragraph/video.py:51
-#: src/pyams_content/component/paragraph/video.py:64
+#: src/pyams_content/component/paragraph/video.py:49
+#: src/pyams_content/component/paragraph/video.py:62
 msgid "Video"
 msgstr "Vidéo"
 
@@ -404,7 +404,7 @@
 msgstr "Titre présenté aux internautes"
 
 #: src/pyams_content/component/extfile/interfaces/__init__.py:41
-#: src/pyams_content/component/paragraph/interfaces/video.py:45
+#: src/pyams_content/component/paragraph/interfaces/video.py:44
 #: src/pyams_content/component/video/interfaces/__init__.py:49
 msgid "File description displayed by front-office template"
 msgstr "Description du fichier, présentée aux internautes"
@@ -453,7 +453,7 @@
 "aux normes d'accessibilité."
 
 #: src/pyams_content/component/extfile/interfaces/__init__.py:81
-#: src/pyams_content/shared/logo/interfaces/__init__.py:48
+#: src/pyams_content/shared/logo/interfaces/__init__.py:47
 msgid "Image data"
 msgstr "Fichier"
 
@@ -463,7 +463,7 @@
 "Cliquez sur le bouton 'Parcourir...' pour sélectionner un nouveau contenu..."
 
 #: src/pyams_content/component/extfile/interfaces/__init__.py:89
-#: src/pyams_content/component/paragraph/interfaces/video.py:52
+#: src/pyams_content/component/paragraph/interfaces/video.py:51
 msgid "Video data"
 msgstr "Fichier"
 
@@ -479,21 +479,21 @@
 
 #: src/pyams_content/component/illustration/paragraph.py:40
 #: src/pyams_content/component/illustration/paragraph.py:47
-#: src/pyams_content/component/illustration/__init__.py:135
+#: src/pyams_content/component/illustration/__init__.py:134
 #: src/pyams_content/component/illustration/zmi/__init__.py:54
 #: src/pyams_content/component/illustration/zmi/__init__.py:81
 msgid "Illustration"
 msgstr "Illustration"
 
-#: src/pyams_content/component/illustration/zmi/paragraph.py:59
+#: src/pyams_content/component/illustration/zmi/paragraph.py:57
 msgid "Illustration..."
 msgstr "Illustration"
 
-#: src/pyams_content/component/illustration/zmi/paragraph.py:70
+#: src/pyams_content/component/illustration/zmi/paragraph.py:68
 msgid "Add new illustration"
 msgstr "Ajout d'une illustration"
 
-#: src/pyams_content/component/illustration/zmi/paragraph.py:104
+#: src/pyams_content/component/illustration/zmi/paragraph.py:102
 msgid "Edit illustration properties"
 msgstr "Propriétés de l'illustration"
 
@@ -516,172 +516,172 @@
 "><strong>ATTENTION :</strong> certains modes de rendu ne prennent pas en "
 "compte tous les types de médias !</span>"
 
-#: src/pyams_content/component/paragraph/milestone.py:206
-#: src/pyams_content/component/paragraph/milestone.py:228
-#: src/pyams_content/component/paragraph/zmi/milestone.py:308
+#: src/pyams_content/component/paragraph/milestone.py:205
+#: src/pyams_content/component/paragraph/milestone.py:227
+#: src/pyams_content/component/paragraph/zmi/milestone.py:297
 msgid "Milestones"
 msgstr "Chronologie"
 
-#: src/pyams_content/component/paragraph/milestone.py:237
+#: src/pyams_content/component/paragraph/milestone.py:236
 msgid "Milestones paragraph"
 msgstr "Chronologie"
 
-#: src/pyams_content/component/paragraph/milestone.py:141
+#: src/pyams_content/component/paragraph/milestone.py:140
 msgid "Selected paragraph is missing"
 msgstr "le bloc sélectionné est introuvable"
 
-#: src/pyams_content/component/paragraph/milestone.py:144
+#: src/pyams_content/component/paragraph/milestone.py:143
 msgid "Selected paragraph is not visible"
 msgstr "le bloc sélectionné n'est pas visible"
 
-#: src/pyams_content/component/paragraph/keypoint.py:47
-#: src/pyams_content/component/paragraph/interfaces/keypoint.py:40
+#: src/pyams_content/component/paragraph/keypoint.py:44
+#: src/pyams_content/component/paragraph/interfaces/keypoint.py:39
 msgid "Key points"
 msgstr "Points clés"
 
-#: src/pyams_content/component/paragraph/keypoint.py:62
+#: src/pyams_content/component/paragraph/keypoint.py:59
 msgid "Key points paragraph"
 msgstr "Points clés"
 
-#: src/pyams_content/component/paragraph/container.py:82
+#: src/pyams_content/component/paragraph/container.py:73
 msgid "Paragraphs"
 msgstr "Blocs de contenu"
 
-#: src/pyams_content/component/paragraph/container.py:104
+#: src/pyams_content/component/paragraph/container.py:95
 msgid "no visible paragraph"
 msgstr "aucun bloc de contenu visible"
 
-#: src/pyams_content/component/paragraph/pictogram.py:197
-#: src/pyams_content/component/paragraph/pictogram.py:219
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:312
+#: src/pyams_content/component/paragraph/pictogram.py:195
+#: src/pyams_content/component/paragraph/pictogram.py:217
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:301
 msgid "Pictograms"
 msgstr "Pictogrammes"
 
-#: src/pyams_content/component/paragraph/pictogram.py:228
+#: src/pyams_content/component/paragraph/pictogram.py:226
 msgid "Pictograms paragraph"
 msgstr "Pictogrammes"
 
-#: src/pyams_content/component/paragraph/pictogram.py:136
+#: src/pyams_content/component/paragraph/pictogram.py:134
 msgid "Selected pictogram is missing"
 msgstr "le pictogramme sélectionné est introuvable"
 
-#: src/pyams_content/component/paragraph/keynumber.py:190
-#: src/pyams_content/component/paragraph/keynumber.py:213
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:287
+#: src/pyams_content/component/paragraph/keynumber.py:189
+#: src/pyams_content/component/paragraph/keynumber.py:212
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:276
 msgid "Key numbers"
 msgstr "Chiffres-clés"
 
-#: src/pyams_content/component/paragraph/keynumber.py:222
+#: src/pyams_content/component/paragraph/keynumber.py:221
 msgid "Key numbers paragraph"
 msgstr "Chiffres-clés"
 
-#: src/pyams_content/component/paragraph/frame.py:52
+#: src/pyams_content/component/paragraph/frame.py:50
 msgid "Framed text"
 msgstr "Encadré"
 
-#: src/pyams_content/component/paragraph/frame.py:62
+#: src/pyams_content/component/paragraph/frame.py:60
 msgid "Framed text paragraph"
 msgstr "Encadré"
 
-#: src/pyams_content/component/paragraph/verbatim.py:50
+#: src/pyams_content/component/paragraph/verbatim.py:48
 msgid "Verbatim"
 msgstr "Verbatim"
 
-#: src/pyams_content/component/paragraph/verbatim.py:62
+#: src/pyams_content/component/paragraph/verbatim.py:60
 msgid "Verbatim paragraph"
 msgstr "Verbatim"
 
-#: src/pyams_content/component/paragraph/html.py:59
+#: src/pyams_content/component/paragraph/html.py:61
 msgid "Raw HTML "
 msgstr "Code HTML"
 
-#: src/pyams_content/component/paragraph/html.py:68
+#: src/pyams_content/component/paragraph/html.py:71
 msgid "Raw HTML paragraph"
 msgstr "Code HTML"
 
-#: src/pyams_content/component/paragraph/html.py:106
+#: src/pyams_content/component/paragraph/html.py:117
 msgid "Rich text"
 msgstr "Texte enrichi"
 
-#: src/pyams_content/component/paragraph/html.py:115
+#: src/pyams_content/component/paragraph/html.py:127
 msgid "Rich text paragraph"
 msgstr "Texte enrichi"
 
-#: src/pyams_content/component/paragraph/contact.py:47
-#: src/pyams_content/component/paragraph/contact.py:76
+#: src/pyams_content/component/paragraph/contact.py:45
+#: src/pyams_content/component/paragraph/contact.py:74
 msgid "Contact card"
 msgstr "Fiche contact"
 
-#: src/pyams_content/component/paragraph/header.py:47
-#: src/pyams_content/component/paragraph/interfaces/header.py:40
+#: src/pyams_content/component/paragraph/header.py:44
+#: src/pyams_content/component/paragraph/interfaces/header.py:39
 #: src/pyams_content/features/alert/interfaces.py:65
 #: src/pyams_content/features/alert/zmi/container.py:158
 msgid "Header"
 msgstr "Chapô"
 
-#: src/pyams_content/component/paragraph/header.py:62
+#: src/pyams_content/component/paragraph/header.py:59
 msgid "Header paragraph"
 msgstr "Chapô"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:79
+#: src/pyams_content/component/paragraph/zmi/milestone.py:77
 msgid "Milestones..."
 msgstr "Chronologie"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:90
+#: src/pyams_content/component/paragraph/zmi/milestone.py:88
 msgid "Add new milestone paragraph"
 msgstr "Ajout d'une chronologie"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:122
+#: src/pyams_content/component/paragraph/zmi/milestone.py:120
 msgid "Edit milestone paragraph properties"
 msgstr "Propriétés de la chronologie"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:266
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:50
+#: src/pyams_content/component/paragraph/zmi/milestone.py:255
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:49
 msgid "Associated label"
 msgstr "Information associée"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:275
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:54
+#: src/pyams_content/component/paragraph/zmi/milestone.py:264
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:53
 msgid "Anchor"
 msgstr "Ancre"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:323
+#: src/pyams_content/component/paragraph/zmi/milestone.py:312
 msgid "Add milestone"
 msgstr "Ajouter un jalon"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:334
+#: src/pyams_content/component/paragraph/zmi/milestone.py:323
 msgid "Add new milestone"
 msgstr "Ajout d'un jalon"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:367
+#: src/pyams_content/component/paragraph/zmi/milestone.py:356
 msgid "Edit milestone properties"
 msgstr "Propriétés du jalon"
 
-#: src/pyams_content/component/paragraph/zmi/milestone.py:356
+#: src/pyams_content/component/paragraph/zmi/milestone.py:345
 msgid "Milestone was correctly added"
 msgstr "Le jalon a été ajouté."
 
-#: src/pyams_content/component/paragraph/zmi/keypoint.py:52
+#: src/pyams_content/component/paragraph/zmi/keypoint.py:50
 msgid "Key points..."
 msgstr "Points clés"
 
-#: src/pyams_content/component/paragraph/zmi/keypoint.py:63
+#: src/pyams_content/component/paragraph/zmi/keypoint.py:61
 msgid "Add new key points paragraph"
 msgstr "Ajout de points clés"
 
-#: src/pyams_content/component/paragraph/zmi/keypoint.py:95
+#: src/pyams_content/component/paragraph/zmi/keypoint.py:93
 msgid "Edit key points paragraph properties"
 msgstr "Propriétés des points clés"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:63
+#: src/pyams_content/component/paragraph/zmi/__init__.py:66
 msgid "Content block types..."
 msgstr "Types de blocs de contenu"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:76
+#: src/pyams_content/component/paragraph/zmi/__init__.py:79
 msgid "Content block types"
 msgstr "Types de blocs de contenu"
 
-#: src/pyams_content/component/paragraph/zmi/__init__.py:93
+#: src/pyams_content/component/paragraph/zmi/__init__.py:96
 msgid ""
 "You can define which types of paragraphs are allowed in this container.\n"
 "\n"
@@ -700,27 +700,55 @@
 "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:197
+#: src/pyams_content/component/paragraph/zmi/__init__.py:208
+#: src/pyams_content/features/preview/zmi/__init__.py:45
+msgid "Preview"
+msgstr "Aperçu"
+
+#: src/pyams_content/component/paragraph/zmi/__init__.py:213
+#: src/pyams_content/shared/common/zmi/workflow.py:115
+#: src/pyams_content/shared/common/zmi/workflow.py:207
+#: src/pyams_content/shared/common/zmi/workflow.py:252
+#: src/pyams_content/shared/common/zmi/workflow.py:311
+#: src/pyams_content/shared/common/zmi/workflow.py:405
+#: src/pyams_content/shared/common/zmi/workflow.py:466
+#: src/pyams_content/shared/common/zmi/workflow.py:511
+#: src/pyams_content/shared/common/zmi/workflow.py:557
+#: src/pyams_content/shared/common/zmi/workflow.py:605
+#: src/pyams_content/shared/common/zmi/workflow.py:650
+#: src/pyams_content/shared/common/zmi/workflow.py:696
+#: src/pyams_content/shared/common/zmi/workflow.py:752
+#: src/pyams_content/shared/common/zmi/__init__.py:276
+#: src/pyams_content/shared/common/zmi/owner.py:74
+#: src/pyams_content/features/review/zmi/__init__.py:90
+msgid "Cancel"
+msgstr "Annuler"
+
+#: src/pyams_content/component/paragraph/zmi/__init__.py:215
+msgid "Submit"
+msgstr "Enregistrer"
+
+#: src/pyams_content/component/paragraph/zmi/__init__.py:200
 msgid "Paragraph was correctly added."
 msgstr "Le bloc a été ajouté."
 
-#: src/pyams_content/component/paragraph/zmi/video.py:57
+#: src/pyams_content/component/paragraph/zmi/video.py:55
 msgid "Video paragraph..."
 msgstr "Vidéo"
 
-#: src/pyams_content/component/paragraph/zmi/video.py:68
+#: src/pyams_content/component/paragraph/zmi/video.py:66
 msgid "Add new video paragraph"
 msgstr "Ajout d'une vidéo"
 
-#: src/pyams_content/component/paragraph/zmi/video.py:115
-#: src/pyams_content/component/video/zmi/paragraph.py:208
+#: src/pyams_content/component/paragraph/zmi/video.py:113
+#: src/pyams_content/component/video/zmi/paragraph.py:209
 msgid "Edit video properties"
 msgstr "Propriétés de la vidéo"
 
-#: src/pyams_content/component/paragraph/zmi/video.py:86
-#: src/pyams_content/component/paragraph/zmi/video.py:136
-#: src/pyams_content/component/video/zmi/paragraph.py:102
-#: src/pyams_content/component/video/zmi/paragraph.py:236
+#: src/pyams_content/component/paragraph/zmi/video.py:84
+#: src/pyams_content/component/paragraph/zmi/video.py:134
+#: src/pyams_content/component/video/zmi/paragraph.py:103
+#: src/pyams_content/component/video/zmi/paragraph.py:238
 msgid "HTML content"
 msgstr "Contenu HTML"
 
@@ -764,133 +792,133 @@
 "Vérifiez le paramétrage des types de blocs de contenu autorisés pour pouvoir "
 "ajouter de nouveaux blocs."
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:81
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:79
 msgid "Pictograms..."
 msgstr "Pictogrammes"
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:92
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:90
 msgid "Add new pictogram paragraph"
 msgstr "Ajout de pictogrammes"
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:124
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:122
 msgid "Edit pictogram paragraph properties"
 msgstr "Propriétés des pictogrammes"
 
 #. Default: Header
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:275
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:264
 msgid "pictogram-item-header"
 msgstr "En-tête"
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:290
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:271
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:59
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:55
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:279
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:260
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:58
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:54
 msgid "Associated text"
 msgstr "Texte associé"
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:327
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:316
 #: src/pyams_content/reference/pictograms/zmi/__init__.py:59
 msgid "Add pictogram"
 msgstr "Ajouter un pictogramme"
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:338
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:327
 #: src/pyams_content/reference/pictograms/zmi/__init__.py:70
 msgid "Add new pictogram"
 msgstr "Ajout d'un pictogramme"
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:376
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:365
 #: src/pyams_content/reference/pictograms/zmi/__init__.py:100
 msgid "Edit pictogram properties"
 msgstr "Propriétés du pictogramme"
 
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:365
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:354
 msgid "Pictogram was correctly added"
 msgstr "Le pictogramme a été ajouté."
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:78
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:76
 msgid "Key numbers..."
 msgstr "Chiffres-clés"
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:89
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:87
 msgid "Add new key number paragraph"
 msgstr "Ajout de chiffres-clés"
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:121
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:119
 msgid "Edit key number paragraph properties"
 msgstr "Propriétés des chiffres-clés"
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:253
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:46
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:242
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:45
 msgid "Number"
 msgstr "Chiffre"
 
 #. Default: Header
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:262
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:50
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:251
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:49
 msgid "key-number-label"
 msgstr "En-tête"
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:302
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:291
 msgid "Add keynumber"
 msgstr "Ajouter un chiffre-clé"
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:313
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:302
 msgid "Add new keynumber"
 msgstr "Ajout d'un chiffre-clé"
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:346
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:335
 msgid "Edit keynumber properties"
 msgstr "Propriétés du chiffre-clé"
 
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:335
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:324
 msgid "Key number was correctly added"
 msgstr "Le chiffre-clé a été ajouté."
 
-#: src/pyams_content/component/paragraph/zmi/frame.py:85
+#: src/pyams_content/component/paragraph/zmi/frame.py:84
 msgid "Framed text..."
 msgstr "Encadré"
 
-#: src/pyams_content/component/paragraph/zmi/frame.py:97
+#: src/pyams_content/component/paragraph/zmi/frame.py:96
 msgid "Add new framed text paragraph"
 msgstr "Ajout d'un encadré"
 
-#: src/pyams_content/component/paragraph/zmi/frame.py:133
+#: src/pyams_content/component/paragraph/zmi/frame.py:132
 msgid "Edit framed text paragraph properties"
 msgstr "Propriétés de l'encadré"
 
-#: src/pyams_content/component/paragraph/zmi/verbatim.py:58
+#: src/pyams_content/component/paragraph/zmi/verbatim.py:56
 msgid "Verbatim..."
 msgstr "Verbatim"
 
-#: src/pyams_content/component/paragraph/zmi/verbatim.py:69
+#: src/pyams_content/component/paragraph/zmi/verbatim.py:67
 msgid "Add new verbatim paragraph"
 msgstr "Ajout d'un verbatim"
 
-#: src/pyams_content/component/paragraph/zmi/verbatim.py:101
+#: src/pyams_content/component/paragraph/zmi/verbatim.py:99
 msgid "Edit verbatim paragraph properties"
 msgstr "Propriétés du verbatim"
 
-#: src/pyams_content/component/paragraph/zmi/html.py:77
+#: src/pyams_content/component/paragraph/zmi/html.py:76
 msgid "Raw HTML..."
 msgstr "Code HTML"
 
-#: src/pyams_content/component/paragraph/zmi/html.py:88
+#: src/pyams_content/component/paragraph/zmi/html.py:87
 msgid "Add new raw HTML paragraph"
 msgstr "Ajout d'un bloc de code HTML"
 
-#: src/pyams_content/component/paragraph/zmi/html.py:123
+#: src/pyams_content/component/paragraph/zmi/html.py:122
 msgid "Edit raw HTML paragraph properties"
 msgstr "Propriétés du code HTML"
 
-#: src/pyams_content/component/paragraph/zmi/html.py:194
+#: src/pyams_content/component/paragraph/zmi/html.py:174
 msgid "Rich text..."
 msgstr "Texte enrichi"
 
-#: src/pyams_content/component/paragraph/zmi/html.py:205
+#: src/pyams_content/component/paragraph/zmi/html.py:185
 msgid "Add new rich text paragraph"
 msgstr "Ajout d'un bloc de texte enrichi"
 
-#: src/pyams_content/component/paragraph/zmi/html.py:240
+#: src/pyams_content/component/paragraph/zmi/html.py:220
 msgid "Edit rich text paragraph properties"
 msgstr "Propriétés du texte enrichi"
 
@@ -906,137 +934,142 @@
 msgid "Edit contact card properties"
 msgstr "Propriétés de la fiche contact"
 
-#: src/pyams_content/component/paragraph/zmi/header.py:52
+#: src/pyams_content/component/paragraph/zmi/header.py:50
 msgid "Header..."
 msgstr "Chapô"
 
-#: src/pyams_content/component/paragraph/zmi/header.py:63
+#: src/pyams_content/component/paragraph/zmi/header.py:61
 msgid "Add new header paragraph"
 msgstr "Ajout d'un chapô"
 
-#: src/pyams_content/component/paragraph/zmi/header.py:95
+#: src/pyams_content/component/paragraph/zmi/header.py:93
 msgid "Edit header paragraph properties"
 msgstr "Propriétés du chapô"
 
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:41
-#: src/pyams_content/component/paragraph/interfaces/__init__.py:43
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:42
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:41
-#: src/pyams_content/component/association/interfaces/__init__.py:43
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:40
+#: src/pyams_content/component/paragraph/interfaces/__init__.py:44
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:41
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:40
+#: src/pyams_content/component/association/interfaces/__init__.py:42
 #: src/pyams_content/shared/form/interfaces/__init__.py:86
 #: src/pyams_content/shared/site/interfaces/__init__.py:107
 #: src/pyams_content/features/alert/interfaces.py:54
 msgid "Visible?"
 msgstr "Visible ?"
 
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:42
+#: 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"
 
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:47
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:46
 msgid "Milestone title"
 msgstr "Libellé associé au jalon"
 
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:51
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:50
 msgid "The way this label will be rendered depends on presentation template"
 msgstr ""
 "La présentation de cette information peut varier en fonction du mode de "
 "rendu choisi"
 
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:55
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:54
 msgid "Paragraph to which this milestone should lead"
 msgstr "Bloc de contenu vers lequel ce jalon doit conduire"
 
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:83
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:82
 msgid "Milestones template"
 msgstr "Mode de rendu"
 
-#: src/pyams_content/component/paragraph/interfaces/milestone.py:84
+#: src/pyams_content/component/paragraph/interfaces/milestone.py:83
 msgid "Presentation template used for milestones"
 msgstr "Modèle de présentation utilisé par ce bloc de contenu"
 
-#: src/pyams_content/component/paragraph/interfaces/keypoint.py:41
+#: src/pyams_content/component/paragraph/interfaces/keypoint.py:40
 msgid "Enter one key point by line, without hyphen or prefix"
 msgstr ""
 "Indiquez un point clé par ligne, sans tiret. Passez à la ligne entre chaque "
 "point clé, la mise en forme sera effectuée automatiquement."
 
-#: src/pyams_content/component/paragraph/interfaces/keypoint.py:44
+#: src/pyams_content/component/paragraph/interfaces/keypoint.py:43
 msgid "Presentation template"
 msgstr "Mode de rendu"
 
-#: src/pyams_content/component/paragraph/interfaces/keypoint.py:45
-#: src/pyams_content/component/paragraph/interfaces/frame.py:44
-#: src/pyams_content/component/paragraph/interfaces/verbatim.py:53
-#: src/pyams_content/shared/logo/interfaces/__init__.py:76
+#: src/pyams_content/component/paragraph/interfaces/keypoint.py:44
+#: src/pyams_content/component/paragraph/interfaces/frame.py:43
+#: src/pyams_content/component/paragraph/interfaces/verbatim.py:52
+#: src/pyams_content/component/paragraph/interfaces/html.py:45
+#: src/pyams_content/component/paragraph/interfaces/html.py:65
+#: src/pyams_content/shared/imagemap/interfaces/__init__.py:99
+#: src/pyams_content/shared/logo/interfaces/__init__.py:75
 msgid "Presentation template used for this paragraph"
 msgstr "Mode de rendu utilisé par ce bloc de contenu"
 
-#: src/pyams_content/component/paragraph/interfaces/__init__.py:44
+#: src/pyams_content/component/paragraph/interfaces/__init__.py:45
 msgid "Is this paragraph visible in front-office?"
 msgstr "Si 'non', ce bloc de contenu ne sera pas présenté aux internautes"
 
-#: src/pyams_content/component/paragraph/interfaces/__init__.py:48
+#: src/pyams_content/component/paragraph/interfaces/__init__.py:49
 msgid "§ Title"
 msgstr "Titre §"
 
-#: src/pyams_content/component/paragraph/interfaces/__init__.py:79
+#: src/pyams_content/component/paragraph/interfaces/__init__.py:80
 msgid "Allowed paragraphs"
 msgstr "Types de blocs autorisés"
 
-#: src/pyams_content/component/paragraph/interfaces/__init__.py:80
+#: src/pyams_content/component/paragraph/interfaces/__init__.py:81
 msgid "List of paragraphs allowed for this content type"
 msgstr "Liste des types de blocs de contenu autorisés pour ce gabarit."
 
-#: src/pyams_content/component/paragraph/interfaces/__init__.py:84
+#: src/pyams_content/component/paragraph/interfaces/__init__.py:85
 #: src/pyams_content/shared/common/zmi/types.py:167
 #: src/pyams_content/shared/common/zmi/types.py:395
 msgid "Default paragraphs"
 msgstr "Types de blocs par défaut"
 
-#: src/pyams_content/component/paragraph/interfaces/__init__.py:85
+#: src/pyams_content/component/paragraph/interfaces/__init__.py:86
 msgid "List of paragraphs automatically added to a new content"
 msgstr "Liste des types de blocs ajoutés automatiquement aux nouveaux contenus"
 
-#: src/pyams_content/component/paragraph/interfaces/video.py:41
-#: src/pyams_content/component/paragraph/interfaces/html.py:53
-#: src/pyams_content/component/video/interfaces/__init__.py:73
+#: src/pyams_content/component/paragraph/interfaces/video.py:40
+#: src/pyams_content/component/paragraph/interfaces/html.py:61
+#: src/pyams_content/component/video/interfaces/__init__.py:74
 msgid "Body"
 msgstr "Contenu HTML"
 
-#: src/pyams_content/component/paragraph/interfaces/video.py:53
+#: src/pyams_content/component/paragraph/interfaces/video.py:52
 msgid "Video file content"
 msgstr ""
 "Cliquez sur le bouton 'Parcourir...' pour sélectionner un nouveau contenu"
 
-#: src/pyams_content/component/paragraph/interfaces/video.py:56
+#: src/pyams_content/component/paragraph/interfaces/video.py:55
+#: src/pyams_content/component/video/interfaces/__init__.py:77
 msgid "Video template"
 msgstr "Mode de rendu"
 
-#: src/pyams_content/component/paragraph/interfaces/video.py:57
+#: src/pyams_content/component/paragraph/interfaces/video.py:56
+#: src/pyams_content/component/video/interfaces/__init__.py:78
 msgid "Presentation template used for this video"
 msgstr "Mode de rendu utilisé par cette vidéo"
 
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:43
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:42
 msgid "Is this pictogram visible in front-office?"
 msgstr "Si 'non', ce pictogramme ne sera pas présenté aux internautes"
 
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:47
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:46
 #: src/pyams_content/shared/common/interfaces/types.py:67
 #: src/pyams_content/features/alert/interfaces.py:79
 msgid "Pictogram"
 msgstr "Pictogramme"
 
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:48
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:47
 #: src/pyams_content/features/alert/interfaces.py:80
 msgid "Name of the pictogram to select"
 msgstr "Sélection du pictogramme à afficher"
 
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:54
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:53
 msgid "Alternate header"
 msgstr "En-tête de substitution"
 
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:55
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:54
 msgid ""
 "Alternate pictogram label; if not specified, the pictogram header will be "
 "used"
@@ -1044,84 +1077,84 @@
 "EN-tête de substitution utilisé par le pictogramme; si rien n'est spécifié, "
 "l'en-tête du pictogramme sélectionné sera utilisé."
 
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:60
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:59
 msgid "Additional text associated to this pictogram"
 msgstr "Texte complémentaire associé à ce pictogramme"
 
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:86
+msgid "Pictograms template"
+msgstr "Mode de rendu"
+
 #: src/pyams_content/component/paragraph/interfaces/pictogram.py:87
-msgid "Pictograms template"
-msgstr "Mode de rendu"
-
-#: src/pyams_content/component/paragraph/interfaces/pictogram.py:88
 msgid "Presentation template used for pictograms"
 msgstr "Modèle de présentation utilisé par ce bloc de contenu"
 
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:42
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:41
 msgid "Is this key number visible in front-office?"
 msgstr "Si 'non', ce chiffre-clé ne sera pas présenté aux internautes"
 
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:47
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:46
 msgid "Key number value"
 msgstr "Chiffre"
 
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:51
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:50
 msgid ""
 "Small text to be displayed above number (according to selected renderer)"
 msgstr ""
 "Texte court affiché au-dessus du chiffre (selon le mode de rendu sélectionné)"
 
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:56
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:55
 msgid "The way this text will be rendered depends on presentation template"
 msgstr ""
 "La présentation de cette information peut varier en fonction du mode de "
 "rendu choisi"
 
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:83
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:82
 msgid "Key numbers template"
 msgstr "Mode de rendu"
 
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:84
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:83
 msgid "Presentation template used for key numbers"
 msgstr "Modèle de présentation utilisé par ce bloc de contenu"
 
-#: src/pyams_content/component/paragraph/interfaces/frame.py:40
+#: src/pyams_content/component/paragraph/interfaces/frame.py:39
 msgid "Frame body"
 msgstr "Contenu"
 
-#: src/pyams_content/component/paragraph/interfaces/frame.py:43
+#: src/pyams_content/component/paragraph/interfaces/frame.py:42
 msgid "Text template"
 msgstr "Mode de rendu"
 
+#: src/pyams_content/component/paragraph/interfaces/verbatim.py:39
+msgid "Quoted text"
+msgstr "Citation"
+
 #: src/pyams_content/component/paragraph/interfaces/verbatim.py:40
-msgid "Quoted text"
-msgstr "Citation"
-
-#: src/pyams_content/component/paragraph/interfaces/verbatim.py:41
 msgid "Quotation marks will be added automatically by presentation template"
 msgstr "Les guillemets seront ajoutés automatiquement par le mode de rendu..."
 
-#: src/pyams_content/component/paragraph/interfaces/verbatim.py:45
+#: src/pyams_content/component/paragraph/interfaces/verbatim.py:44
 msgid "Name of the quote author"
 msgstr "Nom de l'auteur de la citation"
 
-#: src/pyams_content/component/paragraph/interfaces/verbatim.py:48
-#: src/pyams_content/component/paragraph/interfaces/contact.py:54
+#: src/pyams_content/component/paragraph/interfaces/verbatim.py:47
+#: src/pyams_content/component/paragraph/interfaces/contact.py:53
 msgid "In charge of"
 msgstr "Fonction"
 
-#: src/pyams_content/component/paragraph/interfaces/verbatim.py:49
+#: src/pyams_content/component/paragraph/interfaces/verbatim.py:48
 msgid "Label of author function"
 msgstr "Fonction de l'auteur"
 
-#: src/pyams_content/component/paragraph/interfaces/verbatim.py:52
+#: src/pyams_content/component/paragraph/interfaces/verbatim.py:51
 msgid "Verbatim template"
 msgstr "Mode de rendu"
 
-#: src/pyams_content/component/paragraph/interfaces/html.py:37
+#: src/pyams_content/component/paragraph/interfaces/html.py:39
 msgid "Raw HTML code"
 msgstr "Code HTML"
 
-#: src/pyams_content/component/paragraph/interfaces/html.py:38
+#: src/pyams_content/component/paragraph/interfaces/html.py:40
 msgid ""
 "This HTML code will be used 'as is', without any transformation. Use with "
 "care!!"
@@ -1129,68 +1162,76 @@
 "Ce code HTML sera utilisé en l'état et intégré dans les pages sans "
 "modification. À utiliser avec précaution !!!"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:50
+#: src/pyams_content/component/paragraph/interfaces/html.py:44
+msgid "Raw HTML code template"
+msgstr "Mode de rendu"
+
+#: src/pyams_content/component/paragraph/interfaces/html.py:64
+msgid "Body template"
+msgstr "Mode de rendu"
+
+#: src/pyams_content/component/paragraph/interfaces/contact.py:49
 msgid "Contact identity"
 msgstr "Nom du contact"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:51
+#: src/pyams_content/component/paragraph/interfaces/contact.py:50
 msgid "Name of the contact"
 msgstr "Nom complet du contact"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:55
+#: src/pyams_content/component/paragraph/interfaces/contact.py:54
 msgid "Label of contact function"
 msgstr "Fonction du contact"
 
+#: src/pyams_content/component/paragraph/interfaces/contact.py:57
+msgid "Photo"
+msgstr "Photo"
+
 #: src/pyams_content/component/paragraph/interfaces/contact.py:58
-msgid "Photo"
-msgstr "Photo"
-
-#: src/pyams_content/component/paragraph/interfaces/contact.py:59
 msgid "Use 'browse' button to select contact picture"
 msgstr "Utilisez le bouton 'Parcourir' pour sélectionner la photo du contact"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:67
+#: src/pyams_content/component/paragraph/interfaces/contact.py:66
 msgid "Address"
 msgstr "Adresse"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:70
+#: src/pyams_content/component/paragraph/interfaces/contact.py:69
 msgid "Email address"
 msgstr "Adresse de messagerie"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:71
+#: src/pyams_content/component/paragraph/interfaces/contact.py:70
 msgid "Contact email address"
 msgstr "Adresse de messagerie \"stricte\", soit uniquement \"xxx@yyy.com\""
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:74
+#: src/pyams_content/component/paragraph/interfaces/contact.py:73
 msgid "Contact form"
 msgstr "Formulaire de contact"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:75
+#: src/pyams_content/component/paragraph/interfaces/contact.py:74
 msgid "Reference of contact form"
 msgstr "Référence d'un formulaire de contact"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:79
+#: src/pyams_content/component/paragraph/interfaces/contact.py:78
 msgid "Contact template"
 msgstr "Mode de rendu"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:80
+#: src/pyams_content/component/paragraph/interfaces/contact.py:79
 msgid "Presentation template used for this contact"
 msgstr "Modèle de présentation utilisé pour ce contact"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:63
+#: src/pyams_content/component/paragraph/interfaces/contact.py:62
 msgid "GPS location"
 msgstr "Position GPS"
 
-#: src/pyams_content/component/paragraph/interfaces/contact.py:64
+#: src/pyams_content/component/paragraph/interfaces/contact.py:63
 msgid "GPS coordinates used to locate contact"
 msgstr "Coordonnées GPS de situation du contact"
 
-#: src/pyams_content/component/paragraph/interfaces/header.py:43
+#: src/pyams_content/component/paragraph/interfaces/header.py:42
 #: src/pyams_content/features/header/interfaces/__init__.py:39
 msgid "Header template"
 msgstr "Mode de rendu"
 
-#: src/pyams_content/component/paragraph/interfaces/header.py:44
+#: src/pyams_content/component/paragraph/interfaces/header.py:43
 #: src/pyams_content/features/header/interfaces/__init__.py:40
 msgid "Presentation template used for this header"
 msgstr "Mode de rendu utilisé par ce chapô"
@@ -1222,43 +1263,43 @@
 msgid "Selected themes"
 msgstr "Thèmes sélectionnés"
 
-#: src/pyams_content/component/association/paragraph.py:48
-#: src/pyams_content/component/association/paragraph.py:57
+#: src/pyams_content/component/association/paragraph.py:46
+#: src/pyams_content/component/association/paragraph.py:55
 msgid "Associations paragraph"
 msgstr "Liens et pièces jointes"
 
 #: src/pyams_content/component/association/container.py:88
-#: src/pyams_content/component/association/zmi/__init__.py:288
+#: src/pyams_content/component/association/zmi/__init__.py:296
 msgid "Associations"
 msgstr "Liens et pièces jointes"
 
-#: src/pyams_content/component/association/zmi/paragraph.py:56
+#: src/pyams_content/component/association/zmi/paragraph.py:54
 #: src/pyams_content/component/association/zmi/__init__.py:95
 msgid "Associations..."
 msgstr "Liens et pièces jointes"
 
-#: src/pyams_content/component/association/zmi/paragraph.py:67
+#: src/pyams_content/component/association/zmi/paragraph.py:65
 msgid "Add new association paragraph"
 msgstr "Ajout d'un bloc  « liens et pièces jointes »"
 
-#: src/pyams_content/component/association/zmi/paragraph.py:99
+#: src/pyams_content/component/association/zmi/paragraph.py:97
 msgid "Edit association paragraph properties"
 msgstr "Propriétés du bloc « liens et pièces jointes »"
 
-#: src/pyams_content/component/association/zmi/__init__.py:193
+#: src/pyams_content/component/association/zmi/__init__.py:198
 msgid "Public title"
 msgstr "Libellé public"
 
-#: src/pyams_content/component/association/zmi/__init__.py:210
+#: src/pyams_content/component/association/zmi/__init__.py:216
 msgid "Inner title"
 msgstr "Contenu interne"
 
-#: src/pyams_content/component/association/zmi/__init__.py:225
+#: src/pyams_content/component/association/zmi/__init__.py:232
 msgid "Size"
 msgstr "Taille"
 
-#: src/pyams_content/component/association/zmi/__init__.py:265
-#: src/pyams_content/component/association/zmi/__init__.py:275
+#: src/pyams_content/component/association/zmi/__init__.py:273
+#: src/pyams_content/component/association/zmi/__init__.py:283
 msgid "Associations list"
 msgstr "Liste des liens et pièces jointes"
 
@@ -1266,15 +1307,15 @@
 msgid "Association was correctly added."
 msgstr "L'association a été ajoutée."
 
-#: src/pyams_content/component/association/interfaces/__init__.py:44
+#: src/pyams_content/component/association/interfaces/__init__.py:43
 msgid "Is this item visible in front-office?"
 msgstr "Si 'non', ce lien ne sera pas présenté aux internautes"
 
+#: src/pyams_content/component/association/interfaces/__init__.py:92
+msgid "Associations template"
+msgstr "Mode de rendu"
+
 #: src/pyams_content/component/association/interfaces/__init__.py:93
-msgid "Associations template"
-msgstr "Mode de rendu"
-
-#: src/pyams_content/component/association/interfaces/__init__.py:94
 msgid "Presentation template used for associations"
 msgstr "Modèle de présentation utilisé par ce bloc de contenu"
 
@@ -1367,12 +1408,12 @@
 msgstr "Description du lien, présentée aux internautes"
 
 #: src/pyams_content/component/links/interfaces/__init__.py:55
-#: src/pyams_content/shared/logo/interfaces/__init__.py:51
+#: src/pyams_content/shared/logo/interfaces/__init__.py:50
 msgid "Target URL"
 msgstr "URL cible"
 
 #: src/pyams_content/component/links/interfaces/__init__.py:56
-#: src/pyams_content/shared/logo/interfaces/__init__.py:52
+#: src/pyams_content/shared/logo/interfaces/__init__.py:51
 msgid "URL used to access external resource"
 msgstr ""
 "URL utilisée pour accéder à cette ressource externe. Doit comprendre le "
@@ -1402,8 +1443,8 @@
 "Nom de la boîte aux lettres, tel qu'il sera affiché dans l'application de "
 "messagerie."
 
-#: src/pyams_content/component/video/paragraph.py:42
-#: src/pyams_content/component/video/paragraph.py:51
+#: src/pyams_content/component/video/paragraph.py:45
+#: src/pyams_content/component/video/paragraph.py:55
 #: src/pyams_content/component/video/__init__.py:80
 msgid "External video"
 msgstr "Vidéo externe"
@@ -1666,24 +1707,24 @@
 msgid "Youtube settings"
 msgstr "Paramétres Youtube"
 
-#: src/pyams_content/component/video/zmi/paragraph.py:60
+#: src/pyams_content/component/video/zmi/paragraph.py:61
 msgid "External video..."
 msgstr "Vidéo externe"
 
-#: src/pyams_content/component/video/zmi/paragraph.py:71
+#: src/pyams_content/component/video/zmi/paragraph.py:72
 msgid "Add new external video..."
 msgstr "Ajout d'une vidéo externe"
 
-#: src/pyams_content/component/video/zmi/paragraph.py:144
+#: src/pyams_content/component/video/zmi/paragraph.py:145
 msgid "Video provider is required"
 msgstr "Le nom du fournisseur est obligatoire"
 
-#: src/pyams_content/component/video/zmi/paragraph.py:193
-#: src/pyams_content/component/video/zmi/paragraph.py:257
+#: src/pyams_content/component/video/zmi/paragraph.py:194
+#: src/pyams_content/component/video/zmi/paragraph.py:259
 msgid "Video provider settings"
 msgstr "Paramètres liés au fournisseur"
 
-#: src/pyams_content/component/video/zmi/paragraph.py:173
+#: src/pyams_content/component/video/zmi/paragraph.py:174
 msgid "Other settings"
 msgstr "Autres paramètres"
 
@@ -1834,24 +1875,6 @@
 msgid "Click to see subtypes"
 msgstr "Montrer ou caher les sous-types"
 
-#: src/pyams_content/shared/common/zmi/workflow.py:115
-#: src/pyams_content/shared/common/zmi/workflow.py:207
-#: src/pyams_content/shared/common/zmi/workflow.py:252
-#: src/pyams_content/shared/common/zmi/workflow.py:311
-#: src/pyams_content/shared/common/zmi/workflow.py:405
-#: src/pyams_content/shared/common/zmi/workflow.py:466
-#: src/pyams_content/shared/common/zmi/workflow.py:511
-#: src/pyams_content/shared/common/zmi/workflow.py:557
-#: src/pyams_content/shared/common/zmi/workflow.py:605
-#: src/pyams_content/shared/common/zmi/workflow.py:650
-#: src/pyams_content/shared/common/zmi/workflow.py:696
-#: src/pyams_content/shared/common/zmi/workflow.py:752
-#: src/pyams_content/shared/common/zmi/__init__.py:276
-#: src/pyams_content/shared/common/zmi/owner.py:74
-#: src/pyams_content/features/review/zmi/__init__.py:90
-msgid "Cancel"
-msgstr "Annuler"
-
 #: src/pyams_content/shared/common/zmi/workflow.py:116
 msgid "Request publication"
 msgstr "Demander la publication"
@@ -3320,14 +3343,10 @@
 "ATTENTION : les résultats affichés dans cet aperçu ne tiennent pas compte du "
 "contexte pouvant être paramétré dans la vue !!!"
 
-#: src/pyams_content/shared/view/portlet/__init__.py:60
+#: src/pyams_content/shared/view/portlet/__init__.py:56
 msgid "View items"
 msgstr "Contenu d'une vue"
 
-#: src/pyams_content/shared/view/portlet/__init__.py:73
-msgid "Simple list view"
-msgstr "Vue simple d'une liste d'éléments"
-
 #: src/pyams_content/shared/view/portlet/interfaces.py:31
 msgid "Selected view"
 msgstr "Vue sélectionnée"
@@ -3434,22 +3453,22 @@
 msgid "Other terms"
 msgstr "Autres thèmes"
 
-#: src/pyams_content/shared/imagemap/paragraph.py:42
-#: src/pyams_content/shared/imagemap/paragraph.py:54
+#: src/pyams_content/shared/imagemap/paragraph.py:45
+#: src/pyams_content/shared/imagemap/paragraph.py:58
 #: src/pyams_content/shared/imagemap/interfaces/__init__.py:35
 msgid "Image map"
 msgstr "Image cliquable"
 
-#: src/pyams_content/shared/imagemap/paragraph.py:85
+#: src/pyams_content/shared/imagemap/paragraph.py:89
 msgid "no selected image map"
 msgstr "aucune image cliquable sélectionnée"
 
-#: src/pyams_content/shared/imagemap/paragraph.py:91
+#: src/pyams_content/shared/imagemap/paragraph.py:95
 #, python-format
 msgid "image map '{0}' can't be found"
 msgstr "l'image cliquable '{0}' est introuvable"
 
-#: src/pyams_content/shared/imagemap/paragraph.py:99
+#: src/pyams_content/shared/imagemap/paragraph.py:103
 #, python-format
 msgid "image map '{0}' is not published"
 msgstr "l'image cliquable '{0}' n'est pas publiée"
@@ -3458,16 +3477,16 @@
 msgid "no area defined"
 msgstr "aucune zone définie"
 
-#: src/pyams_content/shared/imagemap/zmi/paragraph.py:55
+#: src/pyams_content/shared/imagemap/zmi/paragraph.py:54
 msgid "Image map..."
 msgstr "Image cliquable"
 
-#: src/pyams_content/shared/imagemap/zmi/paragraph.py:66
+#: src/pyams_content/shared/imagemap/zmi/paragraph.py:65
 msgid "Add new image map"
 msgstr "Ajout d'une image cliquable"
 
-#: src/pyams_content/shared/imagemap/zmi/paragraph.py:98
-#: src/pyams_content/shared/logo/zmi/paragraph.py:98
+#: src/pyams_content/shared/imagemap/zmi/paragraph.py:97
+#: src/pyams_content/shared/logo/zmi/paragraph.py:96
 msgid "Edit paragraph properties"
 msgstr "Propriétés de l'image cliquable"
 
@@ -3562,17 +3581,21 @@
 msgid "List of defined map areas"
 msgstr "Liste des zones cliquables définies sur l'image"
 
-#: src/pyams_content/shared/imagemap/interfaces/__init__.py:93
+#: src/pyams_content/shared/imagemap/interfaces/__init__.py:94
 #: src/pyams_content/features/alert/interfaces.py:73
 msgid "Internal reference"
 msgstr "Référence interne"
 
-#: src/pyams_content/shared/imagemap/interfaces/__init__.py:94
+#: src/pyams_content/shared/imagemap/interfaces/__init__.py:95
 msgid "Reference to image map object"
 msgstr ""
 "Référence interne de l'image cliquable. Vous pouvez la rechercher par des "
 "mots de son titre, ou par son numéro interne (précédé d'un '+')."
 
+#: src/pyams_content/shared/imagemap/interfaces/__init__.py:98
+msgid "Image map template"
+msgstr "Mode de rendu"
+
 #: src/pyams_content/shared/site/zmi/folder.py:55
 msgid "Add site folder..."
 msgstr "Ajouter une rubrique"
@@ -3737,11 +3760,11 @@
 msgid "no URL defined"
 msgstr "aucune URL définie"
 
-#: src/pyams_content/shared/logo/zmi/paragraph.py:55
+#: src/pyams_content/shared/logo/zmi/paragraph.py:53
 msgid "Logos..."
 msgstr "Logos"
 
-#: src/pyams_content/shared/logo/zmi/paragraph.py:66
+#: src/pyams_content/shared/logo/zmi/paragraph.py:64
 msgid "Add new logos paragraph"
 msgstr "Ajout d'une sélection de logos"
 
@@ -3763,19 +3786,19 @@
 msgid "Logo « {title} »"
 msgstr "Logo « {title} »"
 
-#: src/pyams_content/shared/logo/interfaces/__init__.py:33
+#: src/pyams_content/shared/logo/interfaces/__init__.py:32
 msgid "Logo"
 msgstr "Logo"
 
-#: src/pyams_content/shared/logo/interfaces/__init__.py:71
+#: src/pyams_content/shared/logo/interfaces/__init__.py:70
 msgid "Logos references"
 msgstr "Logos sélectionnés"
 
-#: src/pyams_content/shared/logo/interfaces/__init__.py:72
+#: src/pyams_content/shared/logo/interfaces/__init__.py:71
 msgid "List of internal logos references"
 msgstr "Liste de références internes vers les logos à afficher"
 
-#: src/pyams_content/shared/logo/interfaces/__init__.py:75
+#: src/pyams_content/shared/logo/interfaces/__init__.py:74
 msgid "Logos template"
 msgstr "Mode de rendu"
 
@@ -4358,10 +4381,6 @@
 msgid "{0}:"
 msgstr "{0} :"
 
-#: src/pyams_content/features/preview/zmi/__init__.py:45
-msgid "Preview"
-msgstr "Aperçu"
-
 #: src/pyams_content/features/preview/zmi/__init__.py:62
 msgid "Content preview"
 msgstr "Aperçu du contenu"
@@ -4726,6 +4745,9 @@
 msgid "Hidden header"
 msgstr "Ne pas afficher d'en-tête de pages"
 
+#~ msgid "Simple list view"
+#~ msgstr "Vue simple d'une liste d'éléments"
+
 #~ msgid "Paragraphs types..."
 #~ msgstr "Types de paragraphes"
 
@@ -5066,9 +5088,6 @@
 #~ msgid "Reset"
 #~ msgstr "Annuler"
 
-#~ msgid "Submit"
-#~ msgstr "Enregistrer"
-
 #~ msgid "Illustration properties"
 #~ msgstr "Propriétés d'une illustration"
 
--- a/src/pyams_content/locales/pyams_content.pot	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/locales/pyams_content.pot	Fri May 25 17:07:21 2018 +0200
@@ -6,7 +6,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-05-15 16:31+0200\n"
+"POT-Creation-Date: 2018-05-24 09:43+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"
@@ -82,13 +82,13 @@
 msgid "Medias gallery"
 msgstr ""
 
-#: ./src/pyams_content/component/gallery/__init__.py:161
+#: ./src/pyams_content/component/gallery/__init__.py:159
 msgid "Gallery"
 msgstr ""
 
 #: ./src/pyams_content/component/gallery/zmi/file.py:58
 #: ./src/pyams_content/component/gallery/zmi/file.py:69
-#: ./src/pyams_content/component/gallery/zmi/paragraph.py:176
+#: ./src/pyams_content/component/gallery/zmi/paragraph.py:174
 msgid "Add media(s)"
 msgstr ""
 
@@ -108,15 +108,15 @@
 msgid "Audio content"
 msgstr ""
 
-#: ./src/pyams_content/component/gallery/zmi/paragraph.py:58
+#: ./src/pyams_content/component/gallery/zmi/paragraph.py:56
 msgid "Medias gallery..."
 msgstr ""
 
-#: ./src/pyams_content/component/gallery/zmi/paragraph.py:69
+#: ./src/pyams_content/component/gallery/zmi/paragraph.py:67
 msgid "Add new gallery"
 msgstr ""
 
-#: ./src/pyams_content/component/gallery/zmi/paragraph.py:101
+#: ./src/pyams_content/component/gallery/zmi/paragraph.py:99
 msgid "Edit gallery properties"
 msgstr ""
 
@@ -132,8 +132,8 @@
 #: ./src/pyams_content/component/gallery/interfaces/__init__.py:61
 #: ./src/pyams_content/component/extfile/interfaces/__init__.py:44
 #: ./src/pyams_content/component/illustration/interfaces/__init__.py:56
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:48
-#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:44
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:47
+#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:43
 #: ./src/pyams_content/component/video/interfaces/__init__.py:52
 msgid "Author"
 msgstr ""
@@ -141,7 +141,7 @@
 #: ./src/pyams_content/component/gallery/zmi/interfaces.py:37
 #: ./src/pyams_content/component/gallery/interfaces/__init__.py:62
 #: ./src/pyams_content/component/extfile/interfaces/__init__.py:45
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:49
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:48
 #: ./src/pyams_content/component/video/interfaces/__init__.py:53
 msgid "Name of document's author"
 msgstr ""
@@ -208,7 +208,7 @@
 #: ./src/pyams_content/component/gallery/interfaces/__init__.py:98
 #: ./src/pyams_content/component/extfile/interfaces/__init__.py:40
 #: ./src/pyams_content/component/illustration/interfaces/__init__.py:52
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:44
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:43
 #: ./src/pyams_content/component/links/interfaces/__init__.py:37
 #: ./src/pyams_content/component/video/interfaces/__init__.py:48
 #: ./src/pyams_content/shared/common/interfaces/__init__.py:145
@@ -263,9 +263,9 @@
 
 #: ./src/pyams_content/component/gallery/interfaces/__init__.py:94
 #: ./src/pyams_content/component/extfile/interfaces/__init__.py:36
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:257
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:246
 #: ./src/pyams_content/component/paragraph/zmi/container.py:224
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:46
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:45
 #: ./src/pyams_content/component/links/zmi/reverse.py:71
 #: ./src/pyams_content/shared/common/zmi/dashboard.py:109
 #: ./src/pyams_content/shared/common/zmi/templates/advanced-search.pt:188
@@ -301,15 +301,15 @@
 #: ./src/pyams_content/component/extfile/__init__.py:223
 #: ./src/pyams_content/component/extfile/__init__.py:240
 #: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:66
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:47
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:46
 #: ./src/pyams_content/reference/pictograms/interfaces/__init__.py:44
 msgid "Image"
 msgstr ""
 
 #: ./src/pyams_content/component/extfile/__init__.py:255
 #: ./src/pyams_content/component/extfile/__init__.py:260
-#: ./src/pyams_content/component/paragraph/video.py:51
-#: ./src/pyams_content/component/paragraph/video.py:64
+#: ./src/pyams_content/component/paragraph/video.py:49
+#: ./src/pyams_content/component/paragraph/video.py:62
 msgid "Video"
 msgstr ""
 
@@ -391,7 +391,7 @@
 msgstr ""
 
 #: ./src/pyams_content/component/extfile/interfaces/__init__.py:41
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:45
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:44
 #: ./src/pyams_content/component/video/interfaces/__init__.py:49
 msgid "File description displayed by front-office template"
 msgstr ""
@@ -432,7 +432,7 @@
 msgstr ""
 
 #: ./src/pyams_content/component/extfile/interfaces/__init__.py:81
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:48
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:47
 msgid "Image data"
 msgstr ""
 
@@ -441,7 +441,7 @@
 msgstr ""
 
 #: ./src/pyams_content/component/extfile/interfaces/__init__.py:89
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:52
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:51
 msgid "Video data"
 msgstr ""
 
@@ -455,21 +455,21 @@
 
 #: ./src/pyams_content/component/illustration/paragraph.py:40
 #: ./src/pyams_content/component/illustration/paragraph.py:47
-#: ./src/pyams_content/component/illustration/__init__.py:135
+#: ./src/pyams_content/component/illustration/__init__.py:134
 #: ./src/pyams_content/component/illustration/zmi/__init__.py:54
 #: ./src/pyams_content/component/illustration/zmi/__init__.py:81
 msgid "Illustration"
 msgstr ""
 
-#: ./src/pyams_content/component/illustration/zmi/paragraph.py:59
+#: ./src/pyams_content/component/illustration/zmi/paragraph.py:57
 msgid "Illustration..."
 msgstr ""
 
-#: ./src/pyams_content/component/illustration/zmi/paragraph.py:70
+#: ./src/pyams_content/component/illustration/zmi/paragraph.py:68
 msgid "Add new illustration"
 msgstr ""
 
-#: ./src/pyams_content/component/illustration/zmi/paragraph.py:104
+#: ./src/pyams_content/component/illustration/zmi/paragraph.py:102
 msgid "Edit illustration properties"
 msgstr ""
 
@@ -489,172 +489,172 @@
 msgid "Presentation template used for illustration"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/milestone.py:206
-#: ./src/pyams_content/component/paragraph/milestone.py:228
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:308
+#: ./src/pyams_content/component/paragraph/milestone.py:205
+#: ./src/pyams_content/component/paragraph/milestone.py:227
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:297
 msgid "Milestones"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/milestone.py:237
+#: ./src/pyams_content/component/paragraph/milestone.py:236
 msgid "Milestones paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/milestone.py:141
+#: ./src/pyams_content/component/paragraph/milestone.py:140
 msgid "Selected paragraph is missing"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/milestone.py:144
+#: ./src/pyams_content/component/paragraph/milestone.py:143
 msgid "Selected paragraph is not visible"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/keypoint.py:47
-#: ./src/pyams_content/component/paragraph/interfaces/keypoint.py:40
+#: ./src/pyams_content/component/paragraph/keypoint.py:44
+#: ./src/pyams_content/component/paragraph/interfaces/keypoint.py:39
 msgid "Key points"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/keypoint.py:62
+#: ./src/pyams_content/component/paragraph/keypoint.py:59
 msgid "Key points paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/container.py:82
+#: ./src/pyams_content/component/paragraph/container.py:73
 msgid "Paragraphs"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/container.py:104
+#: ./src/pyams_content/component/paragraph/container.py:95
 msgid "no visible paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/pictogram.py:197
-#: ./src/pyams_content/component/paragraph/pictogram.py:219
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:312
+#: ./src/pyams_content/component/paragraph/pictogram.py:195
+#: ./src/pyams_content/component/paragraph/pictogram.py:217
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:301
 msgid "Pictograms"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/pictogram.py:228
+#: ./src/pyams_content/component/paragraph/pictogram.py:226
 msgid "Pictograms paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/pictogram.py:136
+#: ./src/pyams_content/component/paragraph/pictogram.py:134
 msgid "Selected pictogram is missing"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/keynumber.py:190
-#: ./src/pyams_content/component/paragraph/keynumber.py:213
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:287
+#: ./src/pyams_content/component/paragraph/keynumber.py:189
+#: ./src/pyams_content/component/paragraph/keynumber.py:212
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:276
 msgid "Key numbers"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/keynumber.py:222
+#: ./src/pyams_content/component/paragraph/keynumber.py:221
 msgid "Key numbers paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/frame.py:52
+#: ./src/pyams_content/component/paragraph/frame.py:50
 msgid "Framed text"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/frame.py:62
+#: ./src/pyams_content/component/paragraph/frame.py:60
 msgid "Framed text paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/verbatim.py:50
+#: ./src/pyams_content/component/paragraph/verbatim.py:48
 msgid "Verbatim"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/verbatim.py:62
+#: ./src/pyams_content/component/paragraph/verbatim.py:60
 msgid "Verbatim paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/html.py:59
+#: ./src/pyams_content/component/paragraph/html.py:61
 msgid "Raw HTML "
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/html.py:68
+#: ./src/pyams_content/component/paragraph/html.py:71
 msgid "Raw HTML paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/html.py:106
+#: ./src/pyams_content/component/paragraph/html.py:117
 msgid "Rich text"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/html.py:115
+#: ./src/pyams_content/component/paragraph/html.py:127
 msgid "Rich text paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/contact.py:47
-#: ./src/pyams_content/component/paragraph/contact.py:76
+#: ./src/pyams_content/component/paragraph/contact.py:45
+#: ./src/pyams_content/component/paragraph/contact.py:74
 msgid "Contact card"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/header.py:47
-#: ./src/pyams_content/component/paragraph/interfaces/header.py:40
+#: ./src/pyams_content/component/paragraph/header.py:44
+#: ./src/pyams_content/component/paragraph/interfaces/header.py:39
 #: ./src/pyams_content/features/alert/interfaces.py:65
 #: ./src/pyams_content/features/alert/zmi/container.py:158
 msgid "Header"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/header.py:62
+#: ./src/pyams_content/component/paragraph/header.py:59
 msgid "Header paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:79
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:77
 msgid "Milestones..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:90
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:88
 msgid "Add new milestone paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:122
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:120
 msgid "Edit milestone paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:266
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:50
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:255
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:49
 msgid "Associated label"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:275
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:54
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:264
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:53
 msgid "Anchor"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:312
+msgid "Add milestone"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/zmi/milestone.py:323
-msgid "Add milestone"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:334
 msgid "Add new milestone"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:367
-msgid "Edit milestone properties"
-msgstr ""
-
 #: ./src/pyams_content/component/paragraph/zmi/milestone.py:356
+msgid "Edit milestone properties"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:345
 msgid "Milestone was correctly added"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:52
+#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:50
 msgid "Key points..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:63
+#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:61
 msgid "Add new key points paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:95
+#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:93
 msgid "Edit key points paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:63
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:66
 msgid "Content block types..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:76
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:79
 msgid "Content block types"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:93
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:96
 msgid ""
 "You can define which types of paragraphs are allowed in this container.\n"
 "\n"
@@ -663,27 +663,55 @@
 "NOTICE: removing types from allowed types list will have no effect on already created contents!"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:197
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:208
+#: ./src/pyams_content/features/preview/zmi/__init__.py:45
+msgid "Preview"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:213
+#: ./src/pyams_content/shared/common/zmi/workflow.py:115
+#: ./src/pyams_content/shared/common/zmi/workflow.py:207
+#: ./src/pyams_content/shared/common/zmi/workflow.py:252
+#: ./src/pyams_content/shared/common/zmi/workflow.py:311
+#: ./src/pyams_content/shared/common/zmi/workflow.py:405
+#: ./src/pyams_content/shared/common/zmi/workflow.py:466
+#: ./src/pyams_content/shared/common/zmi/workflow.py:511
+#: ./src/pyams_content/shared/common/zmi/workflow.py:557
+#: ./src/pyams_content/shared/common/zmi/workflow.py:605
+#: ./src/pyams_content/shared/common/zmi/workflow.py:650
+#: ./src/pyams_content/shared/common/zmi/workflow.py:696
+#: ./src/pyams_content/shared/common/zmi/workflow.py:752
+#: ./src/pyams_content/shared/common/zmi/__init__.py:276
+#: ./src/pyams_content/shared/common/zmi/owner.py:74
+#: ./src/pyams_content/features/review/zmi/__init__.py:90
+msgid "Cancel"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:215
+msgid "Submit"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:200
 msgid "Paragraph was correctly added."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/video.py:57
+#: ./src/pyams_content/component/paragraph/zmi/video.py:55
 msgid "Video paragraph..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/video.py:68
+#: ./src/pyams_content/component/paragraph/zmi/video.py:66
 msgid "Add new video paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/video.py:115
-#: ./src/pyams_content/component/video/zmi/paragraph.py:208
+#: ./src/pyams_content/component/paragraph/zmi/video.py:113
+#: ./src/pyams_content/component/video/zmi/paragraph.py:209
 msgid "Edit video properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/video.py:86
-#: ./src/pyams_content/component/paragraph/zmi/video.py:136
-#: ./src/pyams_content/component/video/zmi/paragraph.py:102
-#: ./src/pyams_content/component/video/zmi/paragraph.py:236
+#: ./src/pyams_content/component/paragraph/zmi/video.py:84
+#: ./src/pyams_content/component/paragraph/zmi/video.py:134
+#: ./src/pyams_content/component/video/zmi/paragraph.py:103
+#: ./src/pyams_content/component/video/zmi/paragraph.py:238
 msgid "HTML content"
 msgstr ""
 
@@ -725,133 +753,133 @@
 msgid "Check allowed paragraph types to be able to create new paragraphs."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:81
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:79
 msgid "Pictograms..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:92
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:90
 msgid "Add new pictogram paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:124
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:122
 msgid "Edit pictogram paragraph properties"
 msgstr ""
 
 #. Default: Header
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:275
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:264
 msgid "pictogram-item-header"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:290
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:271
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:59
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:55
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:279
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:260
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:58
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:54
 msgid "Associated text"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:316
+#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:59
+msgid "Add pictogram"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/zmi/pictogram.py:327
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:59
-msgid "Add pictogram"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:338
 #: ./src/pyams_content/reference/pictograms/zmi/__init__.py:70
 msgid "Add new pictogram"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:376
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:100
-msgid "Edit pictogram properties"
-msgstr ""
-
 #: ./src/pyams_content/component/paragraph/zmi/pictogram.py:365
+#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:100
+msgid "Edit pictogram properties"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:354
 msgid "Pictogram was correctly added"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:78
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:76
 msgid "Key numbers..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:89
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:87
 msgid "Add new key number paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:121
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:119
 msgid "Edit key number paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:253
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:46
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:242
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:45
 msgid "Number"
 msgstr ""
 
 #. Default: Header
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:262
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:50
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:251
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:49
 msgid "key-number-label"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:291
+msgid "Add keynumber"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/zmi/keynumber.py:302
-msgid "Add keynumber"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:313
 msgid "Add new keynumber"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:346
-msgid "Edit keynumber properties"
-msgstr ""
-
 #: ./src/pyams_content/component/paragraph/zmi/keynumber.py:335
+msgid "Edit keynumber properties"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:324
 msgid "Key number was correctly added"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/frame.py:85
+#: ./src/pyams_content/component/paragraph/zmi/frame.py:84
 msgid "Framed text..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/frame.py:97
+#: ./src/pyams_content/component/paragraph/zmi/frame.py:96
 msgid "Add new framed text paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/frame.py:133
+#: ./src/pyams_content/component/paragraph/zmi/frame.py:132
 msgid "Edit framed text paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:58
+#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:56
 msgid "Verbatim..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:69
+#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:67
 msgid "Add new verbatim paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:101
+#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:99
 msgid "Edit verbatim paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/html.py:77
+#: ./src/pyams_content/component/paragraph/zmi/html.py:76
 msgid "Raw HTML..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/html.py:88
+#: ./src/pyams_content/component/paragraph/zmi/html.py:87
 msgid "Add new raw HTML paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/html.py:123
+#: ./src/pyams_content/component/paragraph/zmi/html.py:122
 msgid "Edit raw HTML paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/html.py:194
+#: ./src/pyams_content/component/paragraph/zmi/html.py:174
 msgid "Rich text..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/html.py:205
+#: ./src/pyams_content/component/paragraph/zmi/html.py:185
 msgid "Add new rich text paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/html.py:240
+#: ./src/pyams_content/component/paragraph/zmi/html.py:220
 msgid "Edit rich text paragraph properties"
 msgstr ""
 
@@ -867,279 +895,292 @@
 msgid "Edit contact card properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/header.py:52
+#: ./src/pyams_content/component/paragraph/zmi/header.py:50
 msgid "Header..."
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/header.py:63
+#: ./src/pyams_content/component/paragraph/zmi/header.py:61
 msgid "Add new header paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/zmi/header.py:95
+#: ./src/pyams_content/component/paragraph/zmi/header.py:93
 msgid "Edit header paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:41
-#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:43
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:42
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:41
-#: ./src/pyams_content/component/association/interfaces/__init__.py:43
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:40
+#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:44
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:41
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:40
+#: ./src/pyams_content/component/association/interfaces/__init__.py:42
 #: ./src/pyams_content/shared/form/interfaces/__init__.py:86
 #: ./src/pyams_content/shared/site/interfaces/__init__.py:107
 #: ./src/pyams_content/features/alert/interfaces.py:54
 msgid "Visible?"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:42
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:41
 msgid "Is this milestone visible in front-office?"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:47
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:46
 msgid "Milestone title"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:51
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:50
 msgid "The way this label will be rendered depends on presentation template"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:55
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:54
 msgid "Paragraph to which this milestone should lead"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:82
+msgid "Milestones template"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/milestone.py:83
-msgid "Milestones template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:84
 msgid "Presentation template used for milestones"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/keypoint.py:41
+#: ./src/pyams_content/component/paragraph/interfaces/keypoint.py:40
 msgid "Enter one key point by line, without hyphen or prefix"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/keypoint.py:43
+msgid "Presentation template"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/keypoint.py:44
-msgid "Presentation template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/keypoint.py:45
-#: ./src/pyams_content/component/paragraph/interfaces/frame.py:44
-#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:53
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:76
+#: ./src/pyams_content/component/paragraph/interfaces/frame.py:43
+#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:52
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:45
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:65
+#: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:99
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:75
 msgid "Presentation template used for this paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:44
+#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:45
 msgid "Is this paragraph visible in front-office?"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:48
+#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:49
 msgid "§ Title"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:79
-msgid "Allowed paragraphs"
-msgstr ""
-
 #: ./src/pyams_content/component/paragraph/interfaces/__init__.py:80
+msgid "Allowed paragraphs"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:81
 msgid "List of paragraphs allowed for this content type"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:84
-#: ./src/pyams_content/shared/common/zmi/types.py:167
-#: ./src/pyams_content/shared/common/zmi/types.py:395
-msgid "Default paragraphs"
-msgstr ""
-
 #: ./src/pyams_content/component/paragraph/interfaces/__init__.py:85
+#: ./src/pyams_content/shared/common/zmi/types.py:167
+#: ./src/pyams_content/shared/common/zmi/types.py:395
+msgid "Default paragraphs"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/interfaces/__init__.py:86
 msgid "List of paragraphs automatically added to a new content"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:41
-#: ./src/pyams_content/component/paragraph/interfaces/html.py:53
-#: ./src/pyams_content/component/video/interfaces/__init__.py:73
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:40
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:61
+#: ./src/pyams_content/component/video/interfaces/__init__.py:74
 msgid "Body"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:53
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:52
 msgid "Video file content"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:55
+#: ./src/pyams_content/component/video/interfaces/__init__.py:77
+msgid "Video template"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/video.py:56
-msgid "Video template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:57
+#: ./src/pyams_content/component/video/interfaces/__init__.py:78
 msgid "Presentation template used for this video"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:43
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:42
 msgid "Is this pictogram visible in front-office?"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:47
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:46
 #: ./src/pyams_content/shared/common/interfaces/types.py:67
 #: ./src/pyams_content/features/alert/interfaces.py:79
 msgid "Pictogram"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:48
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:47
 #: ./src/pyams_content/features/alert/interfaces.py:80
 msgid "Name of the pictogram to select"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:53
+msgid "Alternate header"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:54
-msgid "Alternate header"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:55
 msgid ""
 "Alternate pictogram label; if not specified, the pictogram header will be "
 "used"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:60
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:59
 msgid "Additional text associated to this pictogram"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:86
+msgid "Pictograms template"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:87
-msgid "Pictograms template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:88
 msgid "Presentation template used for pictograms"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:42
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:41
 msgid "Is this key number visible in front-office?"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:47
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:46
 msgid "Key number value"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:51
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:50
 msgid ""
 "Small text to be displayed above number (according to selected renderer)"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:56
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:55
 msgid "The way this text will be rendered depends on presentation template"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:82
+msgid "Key numbers template"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:83
-msgid "Key numbers template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:84
 msgid "Presentation template used for key numbers"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/frame.py:40
+#: ./src/pyams_content/component/paragraph/interfaces/frame.py:39
 msgid "Frame body"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/frame.py:43
+#: ./src/pyams_content/component/paragraph/interfaces/frame.py:42
 msgid "Text template"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:39
+msgid "Quoted text"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:40
-msgid "Quoted text"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:41
 msgid "Quotation marks will be added automatically by presentation template"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:45
+#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:44
 msgid "Name of the quote author"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:47
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:53
+msgid "In charge of"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:48
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:54
-msgid "In charge of"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:49
 msgid "Label of author function"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:52
+#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:51
 msgid "Verbatim template"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/html.py:37
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:39
 msgid "Raw HTML code"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/html.py:38
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:40
 msgid ""
 "This HTML code will be used 'as is', without any transformation. Use with "
 "care!!"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:50
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:44
+msgid "raw HTML code template"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:64
+msgid "Body template"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:49
 msgid "Contact identity"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:51
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:50
 msgid "Name of the contact"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:55
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:54
 msgid "Label of contact function"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:57
+msgid "Photo"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/contact.py:58
-msgid "Photo"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:59
 msgid "Use 'browse' button to select contact picture"
 msgstr ""
 
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:67
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:66
 msgid "Address"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:69
+msgid "Email address"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/contact.py:70
-msgid "Email address"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:71
 msgid "Contact email address"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:73
+msgid "Contact form"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/contact.py:74
-msgid "Contact form"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:75
 msgid "Reference of contact form"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:78
+msgid "Contact template"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/contact.py:79
-msgid "Contact template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:80
 msgid "Presentation template used for this contact"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/contact.py:62
+msgid "GPS location"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/contact.py:63
-msgid "GPS location"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/contact.py:64
 msgid "GPS coordinates used to locate contact"
 msgstr ""
 
+#: ./src/pyams_content/component/paragraph/interfaces/header.py:42
+#: ./src/pyams_content/features/header/interfaces/__init__.py:39
+msgid "Header template"
+msgstr ""
+
 #: ./src/pyams_content/component/paragraph/interfaces/header.py:43
-#: ./src/pyams_content/features/header/interfaces/__init__.py:39
-msgid "Header template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/header.py:44
 #: ./src/pyams_content/features/header/interfaces/__init__.py:40
 msgid "Presentation template used for this header"
 msgstr ""
@@ -1171,43 +1212,43 @@
 msgid "Selected themes"
 msgstr ""
 
-#: ./src/pyams_content/component/association/paragraph.py:48
-#: ./src/pyams_content/component/association/paragraph.py:57
+#: ./src/pyams_content/component/association/paragraph.py:46
+#: ./src/pyams_content/component/association/paragraph.py:55
 msgid "Associations paragraph"
 msgstr ""
 
 #: ./src/pyams_content/component/association/container.py:88
-#: ./src/pyams_content/component/association/zmi/__init__.py:288
+#: ./src/pyams_content/component/association/zmi/__init__.py:296
 msgid "Associations"
 msgstr ""
 
-#: ./src/pyams_content/component/association/zmi/paragraph.py:56
+#: ./src/pyams_content/component/association/zmi/paragraph.py:54
 #: ./src/pyams_content/component/association/zmi/__init__.py:95
 msgid "Associations..."
 msgstr ""
 
-#: ./src/pyams_content/component/association/zmi/paragraph.py:67
+#: ./src/pyams_content/component/association/zmi/paragraph.py:65
 msgid "Add new association paragraph"
 msgstr ""
 
-#: ./src/pyams_content/component/association/zmi/paragraph.py:99
+#: ./src/pyams_content/component/association/zmi/paragraph.py:97
 msgid "Edit association paragraph properties"
 msgstr ""
 
-#: ./src/pyams_content/component/association/zmi/__init__.py:193
+#: ./src/pyams_content/component/association/zmi/__init__.py:198
 msgid "Public title"
 msgstr ""
 
-#: ./src/pyams_content/component/association/zmi/__init__.py:210
+#: ./src/pyams_content/component/association/zmi/__init__.py:216
 msgid "Inner title"
 msgstr ""
 
-#: ./src/pyams_content/component/association/zmi/__init__.py:225
+#: ./src/pyams_content/component/association/zmi/__init__.py:232
 msgid "Size"
 msgstr ""
 
-#: ./src/pyams_content/component/association/zmi/__init__.py:265
-#: ./src/pyams_content/component/association/zmi/__init__.py:275
+#: ./src/pyams_content/component/association/zmi/__init__.py:273
+#: ./src/pyams_content/component/association/zmi/__init__.py:283
 msgid "Associations list"
 msgstr ""
 
@@ -1215,15 +1256,15 @@
 msgid "Association was correctly added."
 msgstr ""
 
-#: ./src/pyams_content/component/association/interfaces/__init__.py:44
+#: ./src/pyams_content/component/association/interfaces/__init__.py:43
 msgid "Is this item visible in front-office?"
 msgstr ""
 
+#: ./src/pyams_content/component/association/interfaces/__init__.py:92
+msgid "Associations template"
+msgstr ""
+
 #: ./src/pyams_content/component/association/interfaces/__init__.py:93
-msgid "Associations template"
-msgstr ""
-
-#: ./src/pyams_content/component/association/interfaces/__init__.py:94
 msgid "Presentation template used for associations"
 msgstr ""
 
@@ -1314,12 +1355,12 @@
 msgstr ""
 
 #: ./src/pyams_content/component/links/interfaces/__init__.py:55
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:51
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:50
 msgid "Target URL"
 msgstr ""
 
 #: ./src/pyams_content/component/links/interfaces/__init__.py:56
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:52
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:51
 msgid "URL used to access external resource"
 msgstr ""
 
@@ -1343,8 +1384,8 @@
 msgid "Address as displayed in address book"
 msgstr ""
 
-#: ./src/pyams_content/component/video/paragraph.py:42
-#: ./src/pyams_content/component/video/paragraph.py:51
+#: ./src/pyams_content/component/video/paragraph.py:45
+#: ./src/pyams_content/component/video/paragraph.py:55
 #: ./src/pyams_content/component/video/__init__.py:80
 msgid "External video"
 msgstr ""
@@ -1585,24 +1626,24 @@
 msgid "Youtube settings"
 msgstr ""
 
-#: ./src/pyams_content/component/video/zmi/paragraph.py:60
+#: ./src/pyams_content/component/video/zmi/paragraph.py:61
 msgid "External video..."
 msgstr ""
 
-#: ./src/pyams_content/component/video/zmi/paragraph.py:71
+#: ./src/pyams_content/component/video/zmi/paragraph.py:72
 msgid "Add new external video..."
 msgstr ""
 
-#: ./src/pyams_content/component/video/zmi/paragraph.py:144
+#: ./src/pyams_content/component/video/zmi/paragraph.py:145
 msgid "Video provider is required"
 msgstr ""
 
-#: ./src/pyams_content/component/video/zmi/paragraph.py:193
-#: ./src/pyams_content/component/video/zmi/paragraph.py:257
+#: ./src/pyams_content/component/video/zmi/paragraph.py:194
+#: ./src/pyams_content/component/video/zmi/paragraph.py:259
 msgid "Video provider settings"
 msgstr ""
 
-#: ./src/pyams_content/component/video/zmi/paragraph.py:173
+#: ./src/pyams_content/component/video/zmi/paragraph.py:174
 msgid "Other settings"
 msgstr ""
 
@@ -1752,24 +1793,6 @@
 msgid "Click to see subtypes"
 msgstr ""
 
-#: ./src/pyams_content/shared/common/zmi/workflow.py:115
-#: ./src/pyams_content/shared/common/zmi/workflow.py:207
-#: ./src/pyams_content/shared/common/zmi/workflow.py:252
-#: ./src/pyams_content/shared/common/zmi/workflow.py:311
-#: ./src/pyams_content/shared/common/zmi/workflow.py:405
-#: ./src/pyams_content/shared/common/zmi/workflow.py:466
-#: ./src/pyams_content/shared/common/zmi/workflow.py:511
-#: ./src/pyams_content/shared/common/zmi/workflow.py:557
-#: ./src/pyams_content/shared/common/zmi/workflow.py:605
-#: ./src/pyams_content/shared/common/zmi/workflow.py:650
-#: ./src/pyams_content/shared/common/zmi/workflow.py:696
-#: ./src/pyams_content/shared/common/zmi/workflow.py:752
-#: ./src/pyams_content/shared/common/zmi/__init__.py:276
-#: ./src/pyams_content/shared/common/zmi/owner.py:74
-#: ./src/pyams_content/features/review/zmi/__init__.py:90
-msgid "Cancel"
-msgstr ""
-
 #: ./src/pyams_content/shared/common/zmi/workflow.py:116
 msgid "Request publication"
 msgstr ""
@@ -3123,14 +3146,10 @@
 msgid "WARNING: items displayed in this preview are out of context!!"
 msgstr ""
 
-#: ./src/pyams_content/shared/view/portlet/__init__.py:60
+#: ./src/pyams_content/shared/view/portlet/__init__.py:56
 msgid "View items"
 msgstr ""
 
-#: ./src/pyams_content/shared/view/portlet/__init__.py:73
-msgid "Simple list view"
-msgstr ""
-
 #: ./src/pyams_content/shared/view/portlet/interfaces.py:31
 msgid "Selected view"
 msgstr ""
@@ -3229,22 +3248,22 @@
 msgid "Other terms"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/paragraph.py:42
-#: ./src/pyams_content/shared/imagemap/paragraph.py:54
+#: ./src/pyams_content/shared/imagemap/paragraph.py:45
+#: ./src/pyams_content/shared/imagemap/paragraph.py:58
 #: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:35
 msgid "Image map"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/paragraph.py:85
+#: ./src/pyams_content/shared/imagemap/paragraph.py:89
 msgid "no selected image map"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/paragraph.py:91
+#: ./src/pyams_content/shared/imagemap/paragraph.py:95
 #, python-format
 msgid "image map '{0}' can't be found"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/paragraph.py:99
+#: ./src/pyams_content/shared/imagemap/paragraph.py:103
 #, python-format
 msgid "image map '{0}' is not published"
 msgstr ""
@@ -3253,16 +3272,16 @@
 msgid "no area defined"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:55
+#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:54
 msgid "Image map..."
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:66
+#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:65
 msgid "Add new image map"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:98
-#: ./src/pyams_content/shared/logo/zmi/paragraph.py:98
+#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:97
+#: ./src/pyams_content/shared/logo/zmi/paragraph.py:96
 msgid "Edit paragraph properties"
 msgstr ""
 
@@ -3357,15 +3376,19 @@
 msgid "List of defined map areas"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:93
+#: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:94
 #: ./src/pyams_content/features/alert/interfaces.py:73
 msgid "Internal reference"
 msgstr ""
 
-#: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:94
+#: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:95
 msgid "Reference to image map object"
 msgstr ""
 
+#: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:98
+msgid "Image map template"
+msgstr ""
+
 #: ./src/pyams_content/shared/site/zmi/folder.py:55
 msgid "Add site folder..."
 msgstr ""
@@ -3526,11 +3549,11 @@
 msgid "no URL defined"
 msgstr ""
 
-#: ./src/pyams_content/shared/logo/zmi/paragraph.py:55
+#: ./src/pyams_content/shared/logo/zmi/paragraph.py:53
 msgid "Logos..."
 msgstr ""
 
-#: ./src/pyams_content/shared/logo/zmi/paragraph.py:66
+#: ./src/pyams_content/shared/logo/zmi/paragraph.py:64
 msgid "Add new logos paragraph"
 msgstr ""
 
@@ -3552,19 +3575,19 @@
 msgid "Logo « {title} »"
 msgstr ""
 
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:33
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:32
 msgid "Logo"
 msgstr ""
 
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:70
+msgid "Logos references"
+msgstr ""
+
 #: ./src/pyams_content/shared/logo/interfaces/__init__.py:71
-msgid "Logos references"
-msgstr ""
-
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:72
 msgid "List of internal logos references"
 msgstr ""
 
-#: ./src/pyams_content/shared/logo/interfaces/__init__.py:75
+#: ./src/pyams_content/shared/logo/interfaces/__init__.py:74
 msgid "Logos template"
 msgstr ""
 
@@ -4142,10 +4165,6 @@
 msgid "{0}:"
 msgstr ""
 
-#: ./src/pyams_content/features/preview/zmi/__init__.py:45
-msgid "Preview"
-msgstr ""
-
 #: ./src/pyams_content/features/preview/zmi/__init__.py:62
 msgid "Content preview"
 msgstr ""
--- a/src/pyams_content/profile/admin.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/profile/admin.py	Fri May 25 17:07:21 2018 +0200
@@ -19,20 +19,17 @@
 from pyams_content.profile.interfaces import IAdminProfile, ADMIN_PROFILE_KEY
 from pyams_security.interfaces import IPrincipalInfo
 from pyams_utils.interfaces import PUBLIC_PERMISSION
-from zope.annotation.interfaces import IAnnotations, IAttributeAnnotatable
 
 # import packages
 from persistent import Persistent
-from pyams_utils.adapter import adapter_config
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
 from pyams_utils.request import check_request, query_request
 from pyramid.security import Allow, ALL_PERMISSIONS, Everyone
-from pyramid.threadlocal import get_current_registry
-from zope.lifecycleevent import ObjectCreatedEvent
 from zope.interface import implementer, Interface
 from zope.schema.fieldproperty import FieldProperty
 
 
-@implementer(IAdminProfile, IAttributeAnnotatable)
+@implementer(IAdminProfile)
 class AdminProfile(Persistent):
     """Admin profile persistent class"""
 
@@ -57,9 +54,4 @@
 @adapter_config(context=IPrincipalInfo, provides=IAdminProfile)
 def principal_admin_profile_factory(principal):
     """Principal admin profile factory adapter"""
-    annotations = IAnnotations(principal)
-    profile = annotations.get(ADMIN_PROFILE_KEY)
-    if profile is None:
-        profile = annotations[ADMIN_PROFILE_KEY] = AdminProfile()
-        get_current_registry().notify(ObjectCreatedEvent(profile))
-    return profile
+    return get_annotation_adapter(principal, ADMIN_PROFILE_KEY, AdminProfile)
--- a/src/pyams_content/profile/interfaces/__init__.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/profile/interfaces/__init__.py	Fri May 25 17:07:21 2018 +0200
@@ -16,9 +16,9 @@
 # import standard library
 
 # import interfaces
+from zope.annotation.interfaces import IAttributeAnnotatable
 
 # import packages
-from zope.interface import Interface
 from zope.schema import Choice, List, TextLine
 
 from pyams_content import _
@@ -27,7 +27,7 @@
 ADMIN_PROFILE_KEY = 'pyams_content.admin_profile'
 
 
-class IAdminProfile(Interface):
+class IAdminProfile(IAttributeAnnotatable):
     """User admin profile preferences"""
 
     favorites = List(title=_("User favorites"),
--- a/src/pyams_content/reference/pictograms/manager.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/reference/pictograms/manager.py	Fri May 25 17:07:21 2018 +0200
@@ -20,18 +20,15 @@
 from pyams_i18n.interfaces import II18n
 from pyams_content.reference.pictograms.interfaces import IPictogramTable, IPictogramManager, IPictogramManagerTarget, \
     PICTOGRAM_MANAGER_KEY, SELECTED_PICTOGRAM_VOCABULARY
-from zope.annotation import IAnnotations
 
 # import packages
-from pyams_utils.adapter import adapter_config
-from pyams_utils.registry import get_current_registry, query_utility
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
+from pyams_utils.registry import query_utility
 from pyams_utils.request import check_request
 from pyams_utils.traversing import get_parent
 from pyams_utils.vocabulary import vocabulary_config
 from zope.container.contained import Contained
 from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
 
@@ -46,13 +43,7 @@
 @adapter_config(context=IPictogramManagerTarget, provides=IPictogramManager)
 def pictogram_manager_factory(target):
     """Pictogram manager factory"""
-    annotations = IAnnotations(target)
-    manager = annotations.get(PICTOGRAM_MANAGER_KEY)
-    if manager is None:
-        manager = annotations[PICTOGRAM_MANAGER_KEY] = PictogramManager()
-        get_current_registry().notify(ObjectCreatedEvent(manager))
-        locate(manager, target)
-    return manager
+    return get_annotation_adapter(target, PICTOGRAM_MANAGER_KEY, PictogramManager)
 
 
 @vocabulary_config(name=SELECTED_PICTOGRAM_VOCABULARY)
--- a/src/pyams_content/root/__init__.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/root/__init__.py	Fri May 25 17:07:21 2018 +0200
@@ -30,7 +30,6 @@
 from pyams_security.interfaces import IDefaultProtectionPolicy, IGrantedRoleEvent, ISecurityManager
 from pyams_utils.interfaces import MANAGE_SYSTEM_PERMISSION
 from pyams_utils.interfaces.site import IConfigurationFactory, IBackOfficeConfigurationFactory, ISiteRootFactory
-from zope.annotation.interfaces import IAnnotations
 
 # import packages
 from persistent import Persistent
@@ -38,7 +37,7 @@
 from pyams_security.security import ProtectedObject
 from pyams_skin.configuration import Configuration, BackOfficeConfiguration
 from pyams_skin.skin import UserSkinnableContent
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.registry import get_utility, utility_config
 from pyams_utils.site import BaseSiteRoot
 from pyams_utils.traversing import get_parent
@@ -136,14 +135,11 @@
     logos_tool_name = None
     news_tool_name = None
 
+
 SITEROOT_TOOLS_CONFIGURATION_KEY = 'pyams_config.tools.configuration'
 
 
 @adapter_config(context=ISiteRoot, provides=ISiteRootToolsConfiguration)
 def site_root_tools_configuration_factory(context):
     """Site root tools configuration factory"""
-    annotations = IAnnotations(context)
-    config = annotations.get(SITEROOT_TOOLS_CONFIGURATION_KEY)
-    if config is None:
-        config = annotations[SITEROOT_TOOLS_CONFIGURATION_KEY] = SiteRootToolsConfiguration()
-    return config
+    return get_annotation_adapter(context, SITEROOT_TOOLS_CONFIGURATION_KEY, SiteRootToolsConfiguration)
--- a/src/pyams_content/shared/common/security.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/shared/common/security.py	Fri May 25 17:07:21 2018 +0200
@@ -23,14 +23,12 @@
 # import packages
 from persistent import Persistent
 from pyams_security.interfaces import IPrincipalInfo, IRevokedRoleEvent, IGrantedRoleEvent
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.request import check_request
 from pyams_utils.traversing import get_parent
 from pyramid.events import subscriber
-from zope.annotation.interfaces import IAnnotations
 from zope.container.folder import Folder
 from zope.interface import implementer
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 
 
@@ -64,28 +62,19 @@
     """Shared tool manager restrictions"""
 
     def get_restrictions(self, principal):
-        annotations = IAnnotations(self.context)
-        restrictions_folder = annotations.get(MANAGER_RESTRICTIONS_KEY)
-        if restrictions_folder is None:
-            restrictions_folder = annotations[MANAGER_RESTRICTIONS_KEY] = Folder()
-            locate(restrictions_folder, self.context)
+        restrictions_folder = get_annotation_adapter(self.context, MANAGER_RESTRICTIONS_KEY, Folder)
         if IPrincipalInfo.providedBy(principal):
             principal = principal.id
         return restrictions_folder.get(principal)
 
     def set_restrictions(self, principal, restrictions):
-        annotations = IAnnotations(self.context)
-        restrictions_folder = annotations.get(MANAGER_RESTRICTIONS_KEY)
-        if restrictions_folder is None:
-            restrictions_folder = annotations[MANAGER_RESTRICTIONS_KEY] = Folder()
-            locate(restrictions_folder, self.context)
+        restrictions_folder = get_annotation_adapter(self.context, MANAGER_RESTRICTIONS_KEY, Folder)
         if IPrincipalInfo.providedBy(principal):
             principal = principal.id
         restrictions_folder[principal] = restrictions
 
     def drop_restrictions(self, principal):
-        annotations = IAnnotations(self.context)
-        restrictions_folder = annotations.get(MANAGER_RESTRICTIONS_KEY)
+        restrictions_folder = get_annotation_adapter(self.context, MANAGER_RESTRICTIONS_KEY)
         if restrictions_folder is None:
             return
         if IPrincipalInfo.providedBy(principal):
--- a/src/pyams_content/shared/common/types.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/shared/common/types.py	Fri May 25 17:07:21 2018 +0200
@@ -30,17 +30,13 @@
 from persistent import Persistent
 from pyams_content.shared.common.manager import SharedTool
 from pyams_i18n.property import I18nFileProperty
-from pyams_utils.adapter import adapter_config, ContextAdapter
-from pyams_utils.registry import get_global_registry
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.request import check_request
 from pyams_utils.traversing import get_parent
 from pyams_utils.vocabulary import vocabulary_config
-from zope.annotation.interfaces import IAnnotations
 from zope.container.contained import Contained
 from zope.container.ordered import OrderedContainer
 from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.location import locate
 from zope.schema import getFieldsInOrder
 from zope.schema.fieldproperty import FieldProperty
 from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
@@ -93,14 +89,7 @@
 @adapter_config(context=ITypedSharedTool, provides=ITypedDataManager)
 def typed_shared_tool_data_manager_factory(context):
     """Types shared tool data manager factory"""
-    annotations = IAnnotations(context)
-    manager = annotations.get(DATA_MANAGER_ANNOTATION_KEY)
-    if manager is None:
-        manager = annotations[DATA_MANAGER_ANNOTATION_KEY] = TypedDataManager()
-        registry = get_global_registry()
-        registry.notify(ObjectCreatedEvent(manager))
-        locate(manager, context, '++types++')
-    return manager
+    return get_annotation_adapter(context, DATA_MANAGER_ANNOTATION_KEY, TypedDataManager, name='++types++')
 
 
 @adapter_config(name='types', context=ITypedSharedTool, provides=ITraversable)
--- a/src/pyams_content/shared/form/field.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/shared/form/field.py	Fri May 25 17:07:21 2018 +0200
@@ -20,23 +20,19 @@
 from pyams_content.shared.form.interfaces import IFormFieldFactory, IFormField, IFormFieldContainer, \
     IFormFieldContainerTarget, FORM_FIELD_CONTAINER_KEY
 from pyams_i18n.interfaces import II18n
-from zope.annotation.interfaces import IAnnotations
 from zope.location.interfaces import ISublocations
 from zope.traversing.interfaces import ITraversable
 
 # import packages
 from persistent import Persistent
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.registry import utility_config, get_global_registry
 from pyams_utils.request import check_request
 from pyams_utils.schema import MailAddressField
 from pyams_utils.vocabulary import vocabulary_config
-from pyramid.threadlocal import get_current_registry
 from zope.container.contained import Contained
 from zope.container.ordered import OrderedContainer
 from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.location import locate
 from zope.schema import TextLine, Text, Bool, Int, Decimal, URI, Date, Choice, List
 from zope.schema.fieldproperty import FieldProperty
 from zope.componentvocabulary.vocabulary import UtilityVocabulary, UtilityTerm
@@ -77,13 +73,7 @@
 @adapter_config(context=IFormFieldContainerTarget, provides=IFormFieldContainer)
 def form_field_container_factory(context):
     """Form fields container factory"""
-    annotations = IAnnotations(context)
-    container = annotations.get(FORM_FIELD_CONTAINER_KEY)
-    if container is None:
-        container = annotations[FORM_FIELD_CONTAINER_KEY] = FormFieldContainer()
-        get_current_registry().notify(ObjectCreatedEvent(container))
-        locate(container, context, '++fields++')
-    return container
+    return get_annotation_adapter(context, FORM_FIELD_CONTAINER_KEY, FormFieldContainer, name='++fields++')
 
 
 @adapter_config(name='fields', context=IFormFieldContainerTarget, provides=ITraversable)
--- a/src/pyams_content/shared/form/handler.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/shared/form/handler.py	Fri May 25 17:07:21 2018 +0200
@@ -17,11 +17,10 @@
 
 # import interfaces
 from pyams_content.shared.form.interfaces import IFormHandler, IMailtoHandlerTarget, IMailtoHandlerInfo
-from zope.annotation.interfaces import IAnnotations
 
 # import packages
 from persistent import Persistent
-from pyams_utils.adapter import adapter_config
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
 from pyams_utils.registry import utility_config
 from pyams_utils.request import check_request
 from pyams_utils.vocabulary import vocabulary_config
@@ -71,11 +70,7 @@
 @adapter_config(context=IMailtoHandlerTarget, provides=IMailtoHandlerInfo)
 def mailto_form_handler_factory(context):
     """Mailto form handler factory"""
-    annotations = IAnnotations(context)
-    info = annotations.get(MAILTO_HANDLER_ANNOTATIONS_KEY)
-    if info is None:
-        info = annotations[MAILTO_HANDLER_ANNOTATIONS_KEY] = MailtoFormHandlerInfo()
-    return info
+    return get_annotation_adapter(context, MAILTO_HANDLER_ANNOTATIONS_KEY, MailtoFormHandlerInfo)
 
 
 @utility_config(name='mailto', provides=IFormHandler)
--- a/src/pyams_content/shared/view/reference.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/shared/view/reference.py	Fri May 25 17:07:21 2018 +0200
@@ -20,20 +20,16 @@
 from hypatia.interfaces import ICatalog
 from pyams_content.shared.view.interfaces import IWfView, IViewSettings, IViewInternalReferencesSettings, \
     IViewQueryFilterExtension, VIEW_REFERENCES_SETTINGS_KEY, ALWAYS_REFERENCE_MODE
-from zope.annotation.interfaces import IAnnotations
 
 # import packages
 from hypatia.catalog import CatalogQuery
 from hypatia.query import Any
 from pyams_catalog.query import CatalogResultSet
 from pyams_content.workflow import VISIBLE_STATES
-from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
 from pyams_utils.registry import get_utility
-from pyramid.threadlocal import get_current_registry
 from zope.container.contained import Contained
 from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 
 
@@ -53,13 +49,8 @@
 @adapter_config(name='references', context=IWfView, provides=IViewSettings)
 def view_internal_references_settings_factory(view):
     """View internal references settings factory"""
-    annotations = IAnnotations(view)
-    settings = annotations.get(VIEW_REFERENCES_SETTINGS_KEY)
-    if settings is None:
-        settings = annotations[VIEW_REFERENCES_SETTINGS_KEY] = ViewInternalReferencesSettings()
-        get_current_registry().notify(ObjectCreatedEvent(settings))
-        locate(settings, view, '++view:references++')
-    return settings
+    return get_annotation_adapter(view, VIEW_REFERENCES_SETTINGS_KEY, ViewInternalReferencesSettings,
+                                  name='++view:references++')
 
 
 @adapter_config(name='references', context=IWfView, provides=IViewQueryFilterExtension)
--- a/src/pyams_content/shared/view/theme.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/shared/view/theme.py	Fri May 25 17:07:21 2018 +0200
@@ -18,16 +18,12 @@
 # import interfaces
 from pyams_content.component.theme.interfaces import IThemesInfo
 from pyams_content.shared.view.interfaces import IWfView, IViewSettings, IViewThemesSettings, VIEW_THEMES_SETTINGS_KEY
-from zope.annotation.interfaces import IAnnotations
 
 # import packages
 from persistent import Persistent
-from pyams_utils.adapter import adapter_config
-from pyramid.threadlocal import get_current_registry
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
 from zope.container.contained import Contained
 from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.location import locate
 from zope.schema.fieldproperty import FieldProperty
 
 
@@ -60,10 +56,5 @@
 @adapter_config(name='themes', context=IWfView, provides=IViewSettings)
 def view_themes_settings_factory(view):
     """View themes settings factory"""
-    annotations = IAnnotations(view)
-    settings = annotations.get(VIEW_THEMES_SETTINGS_KEY)
-    if settings is None:
-        settings = annotations[VIEW_THEMES_SETTINGS_KEY] = ViewThemesSettings()
-        get_current_registry().notify(ObjectCreatedEvent(settings))
-        locate(settings, view, '++view:themes++')
-    return settings
+    return get_annotation_adapter(view, VIEW_THEMES_SETTINGS_KEY, ViewThemesSettings,
+                                  name='++view:themes++')
--- a/src/pyams_content/skin/zmi/viewlet/toplinks/__init__.py	Fri May 25 11:28:17 2018 +0200
+++ b/src/pyams_content/skin/zmi/viewlet/toplinks/__init__.py	Fri May 25 17:07:21 2018 +0200
@@ -30,10 +30,9 @@
 from pyams_skin.viewlet.toplinks import TopLinksViewlet, TopLinksMenu
 from pyams_template.template import template_config
 from pyams_utils.list import unique
-from pyams_utils.registry import get_local_registry, get_utility
+from pyams_utils.registry import get_utility, get_all_utilities_registered_for
 from pyams_utils.url import absolute_url
 from pyams_viewlet.viewlet import viewlet_config
-from pyramid.threadlocal import get_current_registry
 
 from pyams_content import _
 
@@ -48,12 +47,14 @@
 
     def update(self):
         super(SharedSitesMenu, self).update()
-        registry = get_local_registry()
-        for site in sorted(registry.getAllUtilitiesRegisteredFor(ISharedSite),
-                           key=lambda x: II18n(x).query_attribute('title', request=self.request) or ''):
-            menu = TopLinksMenu(self.context, self.request, self.__parent__, self)
-            menu.label = II18n(site).query_attribute('title', request=self.request) or site.__name__
-            menu.url = absolute_url(site, self.request, 'admin#dashboard.html')
+        context = self.context
+        request = self.request
+        parent = self.__parent__
+        for site in sorted(get_all_utilities_registered_for(ISharedSite),
+                           key=lambda x: II18n(x).query_attribute('title', request=request) or ''):
+            menu = TopLinksMenu(context, request, parent, self)
+            menu.label = II18n(site).query_attribute('title', request=request) or site.__name__
+            menu.url = absolute_url(site, request, 'admin#dashboard.html')
             self.viewlets.append(menu)
 
 
@@ -67,14 +68,16 @@
 
     def update(self):
         super(SharedContentsMenu, self).update()
-        registry = get_local_registry()
-        for tool in sorted(registry.getAllUtilitiesRegisteredFor(IBaseSharedTool),
-                           key=lambda x: II18n(x).query_attribute('title', request=self.request) or ''):
+        context = self.context
+        request = self.request
+        parent = self.__parent__
+        for tool in sorted(get_all_utilities_registered_for(IBaseSharedTool),
+                           key=lambda x: II18n(x).query_attribute('title', request=request) or ''):
             if ISharedSite.providedBy(tool) or (not tool.shared_content_menu):
                 continue
-            menu = TopLinksMenu(self.context, self.request, self.__parent__, self)
-            menu.label = II18n(tool).query_attribute('title', request=self.request) or tool.__name__
-            menu.url = absolute_url(tool, self.request, 'admin#dashboard.html')
+            menu = TopLinksMenu(context, request, parent, self)
+            menu.label = II18n(tool).query_attribute('title', request=request) or tool.__name__
+            menu.url = absolute_url(tool, request, 'admin#dashboard.html')
             self.viewlets.append(menu)
 
 
@@ -88,14 +91,16 @@
 
     def update(self):
         super(SharedToolsMenu, self).update()
-        registry = get_local_registry()
-        for tool in sorted(registry.getAllUtilitiesRegisteredFor(IBaseSharedTool),
-                           key=lambda x: II18n(x).query_attribute('title', request=self.request) or ''):
+        context = self.context
+        request = self.request
+        parent = self.__parent__
+        for tool in sorted(get_all_utilities_registered_for(IBaseSharedTool),
+                           key=lambda x: II18n(x).query_attribute('title', request=request) or ''):
             if ISharedSite.providedBy(tool) or tool.shared_content_menu:
                 continue
-            menu = TopLinksMenu(self.context, self.request, self.__parent__, self)
-            menu.label = II18n(tool).query_attribute('title', request=self.request) or tool.__name__
-            menu.url = absolute_url(tool, self.request, 'admin#dashboard.html')
+            menu = TopLinksMenu(context, request, parent, self)
+            menu.label = II18n(tool).query_attribute('title', request=request) or tool.__name__
+            menu.url = absolute_url(tool, request, 'admin#dashboard.html')
             self.viewlets.append(menu)
 
 
@@ -110,15 +115,18 @@
     def update(self):
         super(UserRolesMenu, self).update()
         catalog = get_utility(ICatalog)
-        params = And(Or(Any(catalog['role:contributor'], {self.request.principal.id}),
-                        Any(catalog['role:manager'], {self.request.principal.id}),
-                        Any(catalog['role:pilot'], {self.request.principal.id})),
+        context = self.context
+        request = self.request
+        parent = self.__parent__
+        params = And(Or(Any(catalog['role:contributor'], {request.principal.id}),
+                        Any(catalog['role:manager'], {request.principal.id}),
+                        Any(catalog['role:pilot'], {request.principal.id})),
                      NotEq(catalog['content_type'], None))
         for tool in sorted(unique(CatalogResultSet(CatalogQuery(catalog).query(params))),
-                           key=lambda x: II18n(x).query_attribute('title', request=self.request) or ''):
-            menu = TopLinksMenu(self.context, self.request, self.__parent__, self)
-            menu.label = II18n(tool).query_attribute('title', request=self.request) or tool.__name__
-            menu.url = absolute_url(tool, self.request, 'admin#dashboard.html')
+                           key=lambda x: II18n(x).query_attribute('title', request=request) or ''):
+            menu = TopLinksMenu(context, request, parent, self)
+            menu.label = II18n(tool).query_attribute('title', request=request) or tool.__name__
+            menu.url = absolute_url(tool, request, 'admin#dashboard.html')
             self.viewlets.append(menu)
 
 
@@ -134,17 +142,23 @@
     def update(self):
         super(UserAddingsMenu, self).update()
         catalog = get_utility(ICatalog)
-        registry = get_current_registry()
-        params = And(Any(catalog['role:contributor'], {self.request.principal.id}),
+        context = self.context
+        request = self.request
+        parent = self.__parent__
+        registry = request.registry
+        params = And(Any(catalog['role:contributor'], {request.principal.id}),
                      NotEq(catalog['content_type'], None))
         for tool in sorted(unique(CatalogResultSet(CatalogQuery(catalog).query(params))),
-                           key=lambda x: II18n(x).query_attribute('title', request=self.request) or ''):
-            menu = TopLinksMenu(self.context, self.request, self.__parent__, self)
-            adapter = registry.queryMultiAdapter((tool, self.request), IUserAddingsMenuLabel)
+                           key=lambda x: II18n(x).query_attribute('title', request=request) or ''):
+            content_class = tool.shared_content_factory.content_class
+            if content_class is None:
+                continue
+            menu = TopLinksMenu(context, request, parent, self)
+            adapter = registry.queryMultiAdapter((tool, request), IUserAddingsMenuLabel)
             if adapter is None:
-                menu.label = self.request.localizer.translate(tool.shared_content_factory.content_class.content_name)
+                menu.label = request.localizer.translate(content_class.content_name)
             else:
                 menu.label = adapter.label
-            menu.url = absolute_url(tool, self.request, 'add-shared-content.html')
+            menu.url = absolute_url(tool, request, 'add-shared-content.html')
             menu.data = {'data-toggle': 'modal'}
             self.viewlets.append(menu)