--- a/.hgtags Wed Jun 27 16:34:12 2018 +0200
+++ b/.hgtags Wed Jun 27 16:42:01 2018 +0200
@@ -15,3 +15,6 @@
d73905f6a2eb2949b3979671bf261965473bb7b9 0.1.11
5d94baef6923642af27a9f30f377d45f67f04bbf 0.1.12
cf2d19055dd754ce3ed30be24f83dae351b3ae5c 0.1.13
+95026785904d443509d93895ddf761b7967d9d46 0.1.14
+95026785904d443509d93895ddf761b7967d9d46 0.1.14
+1978e4dad1d8f950411807ed2df23fd030a39b60 0.1.14
--- a/buildout.cfg Wed Jun 27 16:34:12 2018 +0200
+++ b/buildout.cfg Wed Jun 27 16:42:01 2018 +0200
@@ -7,12 +7,6 @@
show-picked-versions = true
newest = false
-allow-hosts =
- bitbucket.org
- *.python.org
- *.sourceforge.net
- github.com
-
versions = versions
newest = false
#allow-picked-versions = false
@@ -92,4 +86,4 @@
eggs = pyams_content [test]
[versions]
-pyams_content = 0.1.14
+pyams_content = 0.1.15
--- a/docs/HISTORY.txt Wed Jun 27 16:34:12 2018 +0200
+++ b/docs/HISTORY.txt Wed Jun 27 16:42:01 2018 +0200
@@ -1,6 +1,24 @@
History
=======
+0.1.15
+------
+ - added "basic" and "navigation" illustration components
+ - added pictogram selection widget
+ - added optional pictogram to links
+ - added generic menu feature
+ - added key numbers portlet
+ - added site container "rename" view to change object URL
+ - include quick search results table in main dashboard view
+
+0.1.14
+------
+ - added header and footer management features
+ - added renderer for each kind of paragraphs
+ - added preview for a each paragraph one by one
+ - added optional checks before publishing content
+ - updated groups management in forms
+
0.1.13
------
- renamed factories to use snake_case on functions
--- a/setup.py Wed Jun 27 16:34:12 2018 +0200
+++ b/setup.py Wed Jun 27 16:42:01 2018 +0200
@@ -22,7 +22,7 @@
README = os.path.join(DOCS, 'README.txt')
HISTORY = os.path.join(DOCS, 'HISTORY.txt')
-version = '0.1.14'
+version = '0.1.15'
long_description = open(README).read() + '\n\n' + open(HISTORY).read()
tests_require = []
--- a/src/pyams_content.egg-info/PKG-INFO Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content.egg-info/PKG-INFO Wed Jun 27 16:42:01 2018 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: pyams-content
-Version: 0.1.13
+Version: 0.1.15
Summary: PyAMS base content interfaces and classes
Home-page: http://hg.ztfy.org/pyams/pyams_content
Author: Thierry Florac
@@ -73,6 +73,21 @@
History
=======
+ 0.1.15
+ ------
+ - added "basic" illustration component
+ - added pictogram selection widget
+ - added optional pictogram to links
+ - added generic menu feature
+
+ 0.1.14
+ ------
+ - added header and footer management features
+ - added renderer for each kind of paragraphs
+ - added preview for a each paragraph one by one
+ - added optional checks before publishing content
+ - updated groups management in forms
+
0.1.13
------
- renamed factories to use snake_case on functions
--- a/src/pyams_content.egg-info/SOURCES.txt Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content.egg-info/SOURCES.txt Wed Jun 27 16:42:01 2018 +0200
@@ -43,6 +43,13 @@
src/pyams_content/component/illustration/zmi/paragraph.py
src/pyams_content/component/illustration/zmi/templates/illustration-thumbnail.pt
src/pyams_content/component/illustration/zmi/templates/paragraph-illustration-icon.pt
+src/pyams_content/component/keynumber/__init__.py
+src/pyams_content/component/keynumber/interfaces/__init__.py
+src/pyams_content/component/keynumber/portlet/__init__.py
+src/pyams_content/component/keynumber/portlet/interfaces/__init__.py
+src/pyams_content/component/keynumber/portlet/zmi/__init__.py
+src/pyams_content/component/keynumber/portlet/zmi/templates/keynumber-preview.pt
+src/pyams_content/component/keynumber/zmi/__init__.py
src/pyams_content/component/links/__init__.py
src/pyams_content/component/links/interfaces/__init__.py
src/pyams_content/component/links/zmi/__init__.py
@@ -50,6 +57,7 @@
src/pyams_content/component/links/zmi/reverse.py
src/pyams_content/component/media/__init__.py
src/pyams_content/component/paragraph/__init__.py
+src/pyams_content/component/paragraph/audio.py
src/pyams_content/component/paragraph/contact.py
src/pyams_content/component/paragraph/container.py
src/pyams_content/component/paragraph/frame.py
@@ -62,6 +70,7 @@
src/pyams_content/component/paragraph/verbatim.py
src/pyams_content/component/paragraph/video.py
src/pyams_content/component/paragraph/interfaces/__init__.py
+src/pyams_content/component/paragraph/interfaces/audio.py
src/pyams_content/component/paragraph/interfaces/contact.py
src/pyams_content/component/paragraph/interfaces/frame.py
src/pyams_content/component/paragraph/interfaces/header.py
@@ -73,6 +82,7 @@
src/pyams_content/component/paragraph/interfaces/verbatim.py
src/pyams_content/component/paragraph/interfaces/video.py
src/pyams_content/component/paragraph/zmi/__init__.py
+src/pyams_content/component/paragraph/zmi/audio.py
src/pyams_content/component/paragraph/zmi/contact.py
src/pyams_content/component/paragraph/zmi/container.py
src/pyams_content/component/paragraph/zmi/frame.py
@@ -87,10 +97,8 @@
src/pyams_content/component/paragraph/zmi/verbatim.py
src/pyams_content/component/paragraph/zmi/video.py
src/pyams_content/component/paragraph/zmi/templates/associations.pt
-src/pyams_content/component/paragraph/zmi/templates/html-render.pt
src/pyams_content/component/paragraph/zmi/templates/paragraph-title-icon.pt
src/pyams_content/component/paragraph/zmi/templates/paragraph-title-toolbar.pt
-src/pyams_content/component/paragraph/zmi/templates/raw-render.pt
src/pyams_content/component/theme/__init__.py
src/pyams_content/component/theme/portlet.py
src/pyams_content/component/theme/interfaces/__init__.py
@@ -113,7 +121,6 @@
src/pyams_content/component/video/provider/zmi/templates/youtube-render.pt
src/pyams_content/component/video/zmi/__init__.py
src/pyams_content/component/video/zmi/paragraph.py
-src/pyams_content/component/video/zmi/templates/video-render.pt
src/pyams_content/component/video/zmi/templates/video-settings.pt
src/pyams_content/doctests/README.txt
src/pyams_content/features/__init__.py
@@ -125,6 +132,33 @@
src/pyams_content/features/checker/__init__.py
src/pyams_content/features/checker/interfaces.py
src/pyams_content/features/checker/zmi/__init__.py
+src/pyams_content/features/footer/__init__.py
+src/pyams_content/features/footer/interfaces/__init__.py
+src/pyams_content/features/footer/skin/__init__.py
+src/pyams_content/features/footer/zmi/__init__.py
+src/pyams_content/features/footer/zmi/__init__.py.orig
+src/pyams_content/features/footer/zmi/templates/renderer-settings.pt
+src/pyams_content/features/header/__init__.py
+src/pyams_content/features/header/interfaces/__init__.py
+src/pyams_content/features/header/skin/__init__.py
+src/pyams_content/features/header/zmi/__init__.py
+src/pyams_content/features/header/zmi/templates/renderer-settings.pt
+src/pyams_content/features/menu/__init__.py
+src/pyams_content/features/menu/interfaces/__init__.py
+src/pyams_content/features/menu/portlet/__init__.py
+src/pyams_content/features/menu/portlet/navigation/__init__.py
+src/pyams_content/features/menu/portlet/navigation/double.py
+src/pyams_content/features/menu/portlet/navigation/simple.py
+src/pyams_content/features/menu/portlet/navigation/interfaces/__init__.py
+src/pyams_content/features/menu/portlet/navigation/interfaces/double.py
+src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py
+src/pyams_content/features/menu/portlet/navigation/zmi/__init__.py
+src/pyams_content/features/menu/portlet/navigation/zmi/double.py
+src/pyams_content/features/menu/portlet/navigation/zmi/simple.py
+src/pyams_content/features/menu/portlet/navigation/zmi/templates/double-preview.pt
+src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt
+src/pyams_content/features/menu/zmi/__init__.py
+src/pyams_content/features/menu/zmi/templates/menu-name-cell.pt
src/pyams_content/features/preview/__init__.py
src/pyams_content/features/preview/interfaces.py
src/pyams_content/features/preview/zmi/__init__.py
@@ -132,6 +166,7 @@
src/pyams_content/features/preview/zmi/templates/preview.pt
src/pyams_content/features/renderer/__init__.py
src/pyams_content/features/renderer/interfaces/__init__.py
+src/pyams_content/features/renderer/skin/__init__.py
src/pyams_content/features/renderer/zmi/__init__.py
src/pyams_content/features/renderer/zmi/widget.py
src/pyams_content/features/renderer/zmi/templates/renderer-input.pt
@@ -159,7 +194,9 @@
src/pyams_content/reference/pictograms/interfaces/__init__.py
src/pyams_content/reference/pictograms/zmi/__init__.py
src/pyams_content/reference/pictograms/zmi/manager.py
+src/pyams_content/reference/pictograms/zmi/widget.py
src/pyams_content/reference/pictograms/zmi/templates/manager-selection.pt
+src/pyams_content/reference/pictograms/zmi/templates/pictogram-header.pt
src/pyams_content/reference/zmi/__init__.py
src/pyams_content/reference/zmi/table.py
src/pyams_content/root/__init__.py
@@ -179,17 +216,25 @@
src/pyams_content/shared/blog/zmi/manager.py
src/pyams_content/shared/common/__init__.py
src/pyams_content/shared/common/manager.py
+src/pyams_content/shared/common/portal.py
src/pyams_content/shared/common/security.py
src/pyams_content/shared/common/types.py
src/pyams_content/shared/common/interfaces/__init__.py
src/pyams_content/shared/common/interfaces/types.py
src/pyams_content/shared/common/interfaces/zmi.py
+src/pyams_content/shared/common/portlet/__init__.py
+src/pyams_content/shared/common/portlet/content/__init__.py
+src/pyams_content/shared/common/portlet/content/interfaces/__init__.py
+src/pyams_content/shared/common/portlet/content/skin/__init__.py
+src/pyams_content/shared/common/portlet/content/zmi/__init__.py
+src/pyams_content/shared/common/portlet/content/zmi/preview.pt
src/pyams_content/shared/common/zmi/__init__.py
src/pyams_content/shared/common/zmi/dashboard.py
src/pyams_content/shared/common/zmi/header.py
src/pyams_content/shared/common/zmi/i18n.py
src/pyams_content/shared/common/zmi/manager.py
src/pyams_content/shared/common/zmi/owner.py
+src/pyams_content/shared/common/zmi/portal.py
src/pyams_content/shared/common/zmi/properties.py
src/pyams_content/shared/common/zmi/search.py
src/pyams_content/shared/common/zmi/security.py
@@ -198,8 +243,10 @@
src/pyams_content/shared/common/zmi/types.py
src/pyams_content/shared/common/zmi/workflow.py
src/pyams_content/shared/common/zmi/templates/advanced-search.pt
+src/pyams_content/shared/common/zmi/templates/check-input.pt
src/pyams_content/shared/common/zmi/templates/dashboard.pt
src/pyams_content/shared/common/zmi/templates/header.pt
+src/pyams_content/shared/common/zmi/templates/preview-input.pt
src/pyams_content/shared/common/zmi/templates/wf-archive-message.pt
src/pyams_content/shared/common/zmi/templates/wf-archiving-message.pt
src/pyams_content/shared/common/zmi/templates/wf-cancel-archiving-message.pt
@@ -236,12 +283,9 @@
src/pyams_content/shared/imagemap/zmi/container.py
src/pyams_content/shared/imagemap/zmi/paragraph.py
src/pyams_content/shared/imagemap/zmi/properties.py
-src/pyams_content/shared/imagemap/zmi/render.py
src/pyams_content/shared/imagemap/zmi/widget.py
src/pyams_content/shared/imagemap/zmi/templates/container.pt
src/pyams_content/shared/imagemap/zmi/templates/imagemap-preview.pt
-src/pyams_content/shared/imagemap/zmi/templates/paragraph-render.pt
-src/pyams_content/shared/imagemap/zmi/templates/render.pt
src/pyams_content/shared/imagemap/zmi/templates/widget-input.pt
src/pyams_content/shared/logo/__init__.py
src/pyams_content/shared/logo/manager.py
@@ -275,16 +319,12 @@
src/pyams_content/shared/view/interfaces/__init__.py
src/pyams_content/shared/view/portlet/__init__.py
src/pyams_content/shared/view/portlet/interfaces.py
-src/pyams_content/shared/view/portlet/templates/view-items-list.pt
-src/pyams_content/shared/view/portlet/templates/view-with-images-list.pt
src/pyams_content/shared/view/portlet/zmi/__init__.py
src/pyams_content/shared/view/portlet/zmi/templates/view-items-list-preview.pt
src/pyams_content/shared/view/zmi/__init__.py
src/pyams_content/shared/view/zmi/properties.py
src/pyams_content/shared/view/zmi/reference.py
-src/pyams_content/shared/view/zmi/render.py
src/pyams_content/shared/view/zmi/theme.py
-src/pyams_content/shared/view/zmi/templates/render.pt
src/pyams_content/skin/__init__.py
src/pyams_content/skin/routes.py
src/pyams_content/skin/resources/css/pyams_content.css
--- a/src/pyams_content.egg-info/requires.txt Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content.egg-info/requires.txt Wed Jun 27 16:42:01 2018 +0200
@@ -4,7 +4,7 @@
persistent
pyams_catalog
pyams_file
-pyams_form
+pyams_form>=0.1.13
pyams_i18n
pyams_mail
pyams_pagelet
@@ -14,7 +14,7 @@
pyams_skin
pyams_template
pyams_thesaurus
-pyams_utils
+pyams_utils>=0.1.15
pyams_viewlet
pyams_workflow
pyams_zmi
--- a/src/pyams_content/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -27,7 +27,7 @@
CREATE_CONTENT_PERMISSION, MANAGE_CONTENT_PERMISSION, COMMENT_CONTENT_PERMISSION, PUBLISH_CONTENT_PERMISSION
from pyams_content.interfaces import WEBMASTER_ROLE, PILOT_ROLE, MANAGER_ROLE, OWNER_ROLE, CONTRIBUTOR_ROLE, \
READER_ROLE, OPERATOR_ROLE, GUEST_ROLE
- from pyams_security.interfaces import ADMIN_USER_ID
+ from pyams_security.interfaces import ADMIN_USER_ID, SYSTEM_ADMIN_ROLE
from pyams_thesaurus.interfaces import CREATE_THESAURUS_PERMISSION, ADMIN_THESAURUS_PERMISSION
from pyams_utils.interfaces import PUBLIC_PERMISSION, VIEW_PERMISSION, MANAGE_PERMISSION, \
VIEW_SYSTEM_PERMISSION, MANAGE_ROLES_PERMISSION, MANAGE_SKIN_PERMISSION
@@ -57,7 +57,9 @@
MANAGE_SITE_ROOT_PERMISSION, MANAGE_SITE_PERMISSION, MANAGE_TOOL_PERMISSION,
CREATE_CONTENT_PERMISSION, MANAGE_CONTENT_PERMISSION, MANAGE_SKIN_PERMISSION,
COMMENT_CONTENT_PERMISSION, PUBLISH_CONTENT_PERMISSION},
- 'managers': {ADMIN_USER_ID, 'role:system.Manager', 'role:pyams.Webmaster'}})
+ 'managers': {ADMIN_USER_ID,
+ 'role:{0}'.format(SYSTEM_ADMIN_ROLE),
+ 'role:{0}'.format(WEBMASTER_ROLE)}})
config.register_role({'id': PILOT_ROLE,
'title': _("Pilot (role)"),
'permissions': {PUBLIC_PERMISSION, VIEW_PERMISSION, MANAGE_PERMISSION,
@@ -65,13 +67,17 @@
MANAGE_SITE_PERMISSION, MANAGE_TOOL_PERMISSION,
MANAGE_CONTENT_PERMISSION, COMMENT_CONTENT_PERMISSION,
PUBLISH_CONTENT_PERMISSION},
- 'managers': {ADMIN_USER_ID, 'role:system.Manager', 'role:pyams.Webmaster'}})
+ 'managers': {ADMIN_USER_ID,
+ 'role:{0}'.format(SYSTEM_ADMIN_ROLE),
+ 'role:{0}'.format(WEBMASTER_ROLE)}})
config.register_role({'id': MANAGER_ROLE,
'title': _("Manager (role)"),
'permissions': {PUBLIC_PERMISSION, VIEW_PERMISSION, MANAGE_PERMISSION,
VIEW_SYSTEM_PERMISSION, MANAGE_CONTENT_PERMISSION,
COMMENT_CONTENT_PERMISSION, PUBLISH_CONTENT_PERMISSION},
- 'managers': {ADMIN_USER_ID, 'role:system.Manager', 'role:pyams.Webmaster',
+ 'managers': {ADMIN_USER_ID,
+ 'role:{0}'.format(SYSTEM_ADMIN_ROLE),
+ 'role:{0}'.format(WEBMASTER_ROLE),
'role:pyams.Pilot'}})
config.register_role({'id': OWNER_ROLE,
'title': _("Owner (role)"),
@@ -84,20 +90,32 @@
VIEW_SYSTEM_PERMISSION,
CREATE_CONTENT_PERMISSION, MANAGE_CONTENT_PERMISSION,
COMMENT_CONTENT_PERMISSION},
- 'managers': {ADMIN_USER_ID, 'role:system.Manager', 'role:pyams.Webmaster',
- 'role:pyams.Pilot', 'role:pyams.Owner'}})
+ 'managers': {ADMIN_USER_ID,
+ 'role:{0}'.format(SYSTEM_ADMIN_ROLE),
+ 'role:{0}'.format(WEBMASTER_ROLE),
+ 'role:pyams.Pilot',
+ 'role:pyams.Owner'}})
config.register_role({'id': READER_ROLE,
'title': _("Reader (role)"),
'permissions': {PUBLIC_PERMISSION, VIEW_PERMISSION, MANAGE_PERMISSION,
VIEW_SYSTEM_PERMISSION, COMMENT_CONTENT_PERMISSION},
- 'managers': {ADMIN_USER_ID, 'role:system.Manager', 'role:pyams.Webmaster',
- 'role:pyams.Pilot', 'role:pyams.Manager', 'role:pyams.Contributor'}})
+ 'managers': {ADMIN_USER_ID,
+ 'role:{0}'.format(SYSTEM_ADMIN_ROLE),
+ 'role:{0}'.format(WEBMASTER_ROLE),
+ 'role:pyams.Pilot',
+ 'role:pyams.Manager',
+ 'role:pyams.Contributor'}})
config.register_role({'id': OPERATOR_ROLE,
'title': _("Operator (role)"),
'permissions': {PUBLIC_PERMISSION, VIEW_PERMISSION, VIEW_SYSTEM_PERMISSION},
- 'managers': {ADMIN_USER_ID, 'role:system.Manager'}})
+ 'managers': {ADMIN_USER_ID,
+ 'role:{0}'.format(SYSTEM_ADMIN_ROLE)}})
config.register_role({'id': GUEST_ROLE,
'title': _("Guest user (role)"),
'permissions': {PUBLIC_PERMISSION, VIEW_PERMISSION},
- 'managers': {ADMIN_USER_ID, 'role:system.Manager', 'role:pyams.Webmaster',
- 'role:pyams.Pilot', 'role:pyams.Manager', 'role:pyams.Contributor'}})
+ 'managers': {ADMIN_USER_ID,
+ 'role:{0}'.format(SYSTEM_ADMIN_ROLE),
+ 'role:{0}'.format(WEBMASTER_ROLE),
+ 'role:pyams.Pilot',
+ 'role:pyams.Manager',
+ 'role:pyams.Contributor'}})
--- a/src/pyams_content/component/association/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/association/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationItem, IAssociationTarget
+from pyams_content.component.association.interfaces import IAssociationItem, IAssociationContainerTarget
from pyams_form.interfaces.form import IFormContextPermissionChecker
from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent
@@ -52,14 +52,14 @@
@property
def edit_permission(self):
- content = get_parent(self.context, IAssociationTarget)
+ content = get_parent(self.context, IAssociationContainerTarget)
return IFormContextPermissionChecker(content).edit_permission
@subscriber(IObjectAddedEvent, context_selector=IAssociationItem)
def handle_added_association(event):
"""Handle added association item"""
- content = get_parent(event.object, IAssociationTarget)
+ content = get_parent(event.object, IAssociationContainerTarget)
if content is not None:
get_current_registry().notify(ObjectModifiedEvent(content))
@@ -67,7 +67,7 @@
@subscriber(IObjectModifiedEvent, context_selector=IAssociationItem)
def handle_modified_association(event):
"""Handle modified association item"""
- content = get_parent(event.object, IAssociationTarget)
+ content = get_parent(event.object, IAssociationContainerTarget)
if content is not None:
get_current_registry().notify(ObjectModifiedEvent(content))
@@ -75,6 +75,6 @@
@subscriber(IObjectRemovedEvent, context_selector=IAssociationItem)
def handle_removed_association(event):
"""Handle removed association item"""
- content = get_parent(event.object, IAssociationTarget)
+ content = get_parent(event.object, IAssociationContainerTarget)
if content is not None:
get_current_registry().notify(ObjectModifiedEvent(content))
--- a/src/pyams_content/component/association/container.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/association/container.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationTarget, \
+from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationContainerTarget, \
ASSOCIATION_CONTAINER_KEY, IAssociationItem, IAssociationInfo
from pyams_content.features.checker.interfaces import IContentChecker
from zope.location.interfaces import ISublocations
@@ -58,13 +58,13 @@
return filter(lambda x: IAssociationItem(x).visible, self.values())
-@adapter_config(context=IAssociationTarget, provides=IAssociationContainer)
+@adapter_config(context=IAssociationContainerTarget, provides=IAssociationContainer)
def association_container_factory(target):
"""Associations container factory"""
return get_annotation_adapter(target, ASSOCIATION_CONTAINER_KEY, AssociationContainer, name='++ass++')
-@adapter_config(name='ass', context=IAssociationTarget, provides=ITraversable)
+@adapter_config(name='ass', context=IAssociationContainerTarget, provides=ITraversable)
class AssociationContainerNamespace(ContextAdapter):
"""Associations container ++ass++ namespace"""
@@ -73,7 +73,7 @@
return registry.queryAdapter(self.context, IAssociationContainer, name=name or '')
-@adapter_config(name='associations', context=IAssociationTarget, provides=ISublocations)
+@adapter_config(name='associations', context=IAssociationContainerTarget, provides=ISublocations)
class AssociationContainerSublocations(ContextAdapter):
"""Associations container sub-locations adapter"""
@@ -81,7 +81,7 @@
return IAssociationContainer(self.context).values()
-@adapter_config(name='associations', context=IAssociationTarget, provides=IContentChecker)
+@adapter_config(name='associations', context=IAssociationContainerTarget, provides=IContentChecker)
class AssociationsContentChecker(BaseContentChecker):
"""Associations content checker"""
@@ -110,7 +110,7 @@
def __init__(self, context=None):
terms = []
- target = get_parent(context, IAssociationTarget)
+ target = get_parent(context, IAssociationContainerTarget)
if target is not None:
terms = [SimpleTerm(link.__name__, title=IAssociationInfo(link).inner_title)
for link in IAssociationContainer(target).values()]
--- a/src/pyams_content/component/association/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/association/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -74,7 +74,7 @@
"""Get list of visible items"""
-class IAssociationTarget(IAttributeAnnotatable):
+class IAssociationContainerTarget(IAttributeAnnotatable):
"""Associations container target interface"""
@@ -82,6 +82,10 @@
"""Association renderer adapter interface"""
+#
+# Associations paragraph
+#
+
ASSOCIATION_PARAGRAPH_TYPE = 'Associations'
ASSOCIATION_PARAGRAPH_NAME = _("Associations")
ASSOCIATION_PARAGRAPH_RENDERERS = 'PyAMS.associations.renderers'
--- a/src/pyams_content/component/association/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/association/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -17,7 +17,8 @@
import json
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationTarget, IAssociationContainer, IAssociationInfo
+from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationContainer, \
+ IAssociationInfo
from pyams_content.component.association.zmi.interfaces import IAssociationsParentForm, IAssociationsView
from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
from pyams_form.interfaces.form import IInnerSubForm
@@ -73,7 +74,7 @@
"""Association item properties edit form, JSON renderer"""
def get_associations_table(self):
- target = get_parent(self.context, IAssociationTarget)
+ target = get_parent(self.context, IAssociationContainerTarget)
return {
'status': 'success',
'message': self.request.localizer.translate(self.successMessage),
@@ -87,7 +88,7 @@
# Content associations view
#
-@viewlet_config(name='associations.menu', context=IAssociationTarget, layer=IPyAMSLayer,
+@viewlet_config(name='associations.menu', context=IAssociationContainerTarget, layer=IPyAMSLayer,
manager=IPropertiesMenu, permission=VIEW_SYSTEM_PERMISSION, weight=60)
class AssociationsMenu(MenuItem):
"""Associations menu"""
@@ -117,16 +118,15 @@
@property
def data_attributes(self):
registry = get_current_registry()
- target = get_parent(self.context, IAssociationTarget)
+ target = get_parent(self.context, IAssociationContainerTarget)
container = registry.getAdapter(target, IAssociationContainer, name=self.associations_name)
attributes = super(AssociationsTable, self).data_attributes
- attributes['table'] = {
- 'id': self.id,
+ attributes.setdefault('table', {}).update({
'data-ams-location': absolute_url(container, self.request),
'data-ams-tablednd-drag-handle': 'td.sorter',
'data-ams-tablednd-drop-target': 'set-associations-order.json',
'data-ams-visibility-switcher': 'switch-association-visibility.json'
- }
+ })
return attributes
@reify
@@ -134,7 +134,7 @@
return list(super(AssociationsTable, self).values)
-@adapter_config(context=(IAssociationTarget, IPyAMSLayer, AssociationsTable), provides=IValues)
+@adapter_config(context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable), provides=IValues)
class AssociationsTableValuesAdapter(ContextRequestViewAdapter):
"""Associations table values adapter"""
@@ -144,7 +144,7 @@
return registry.getAdapter(self.context, IAssociationContainer, name=self.view.associations_name).values()
-@adapter_config(name='sorter', context=(IAssociationTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
+@adapter_config(name='sorter', context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
@adapter_config(name='sorter', context=(IAssociationContainer, IPyAMSLayer, AssociationsTable), provides=IColumn)
class AssociationsTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
"""Associations table sorter column"""
@@ -159,7 +159,7 @@
return {'status': 'success'}
-@adapter_config(name='show-hide', context=(IAssociationTarget, IPyAMSLayer, AssociationsTable),
+@adapter_config(name='show-hide', context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable),
provides=IColumn)
@adapter_config(name='show-hide', context=(IAssociationContainer, IPyAMSLayer, AssociationsTable),
provides=IColumn)
@@ -174,7 +174,7 @@
return switch_element_visibility(request, IAssociationContainer)
-@adapter_config(name='pictogram', context=(IAssociationTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
+@adapter_config(name='pictogram', context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
@adapter_config(name='pictogram', context=(IAssociationContainer, IPyAMSLayer, AssociationsTable), provides=IColumn)
class AssociationsTablePictogramColumn(ImageColumn):
"""Associations table pictogram column"""
@@ -190,7 +190,7 @@
return self.request.localizer.translate(item.icon_hint)
-@adapter_config(name='name', context=(IAssociationTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
+@adapter_config(name='name', context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
@adapter_config(name='name', context=(IAssociationContainer, IPyAMSLayer, AssociationsTable), provides=IColumn)
class AssociationsTablePublicNameColumn(NameColumn):
"""Associations table name column"""
@@ -208,7 +208,7 @@
return title
-@adapter_config(name='inner_name', context=(IAssociationTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
+@adapter_config(name='inner_name', context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
@adapter_config(name='inner_name', context=(IAssociationContainer, IPyAMSLayer, AssociationsTable), provides=IColumn)
class AssociationsTableInnerNameColumn(I18nColumn, GetAttrColumn):
"""Associations table inner name column"""
@@ -224,7 +224,7 @@
return '--'
-@adapter_config(name='size', context=(IAssociationTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
+@adapter_config(name='size', context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
@adapter_config(name='size', context=(IAssociationContainer, IPyAMSLayer, AssociationsTable), provides=IColumn)
class AssociationsTableSizeColumn(I18nColumn, GetAttrColumn):
"""Associations table size column"""
@@ -240,7 +240,7 @@
return '--'
-@adapter_config(name='trash', context=(IAssociationTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
+@adapter_config(name='trash', context=(IAssociationContainerTarget, IPyAMSLayer, AssociationsTable), provides=IColumn)
@adapter_config(name='trash', context=(IAssociationContainer, IPyAMSLayer, AssociationsTable), provides=IColumn)
class AssociationsTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
"""Associations table trash column"""
@@ -253,7 +253,7 @@
output = delete_container_element(request)
if output.get('status') == 'success':
from pyams_content.component.paragraph.zmi import get_json_paragraph_toolbar_refresh_event
- parent = get_parent(request.context, IAssociationTarget)
+ parent = get_parent(request.context, IAssociationContainerTarget)
output.update({
'handle_json': True,
'events': [
@@ -264,7 +264,7 @@
return output
-@pagelet_config(name='associations.html', context=IAssociationTarget, layer=IPyAMSLayer,
+@pagelet_config(name='associations.html', context=IAssociationContainerTarget, layer=IPyAMSLayer,
permission=VIEW_SYSTEM_PERMISSION)
@implementer(IAssociationsView)
class AssociationsContainerView(ContainerAdminView, Pagelet):
@@ -274,7 +274,7 @@
table_class = AssociationsTable
-@pagelet_config(name='associations-dialog.html', context=IAssociationTarget, layer=IPyAMSLayer,
+@pagelet_config(name='associations-dialog.html', context=IAssociationContainerTarget, layer=IPyAMSLayer,
permission=VIEW_SYSTEM_PERMISSION)
@implementer(IAssociationsParentForm)
class AssociationsContainerDialogView(AdminDialogDisplayForm):
@@ -287,7 +287,7 @@
fields = field.Fields(Interface)
-@adapter_config(name='associations', context=(IAssociationTarget, IPyAMSLayer, IAssociationsParentForm),
+@adapter_config(name='associations', context=(IAssociationContainerTarget, IPyAMSLayer, IAssociationsParentForm),
provides=IInnerSubForm)
@implementer(IAssociationsView)
class AssociationsView(InnerTableView):
--- a/src/pyams_content/component/extfile/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/extfile/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationItem, IAssociationTarget
+from pyams_content.component.association.interfaces import IAssociationItem, IAssociationContainerTarget
# import packages
from pyams_i18n.schema import I18nTextLineField, I18nTextField, I18nFileField, I18nThumbnailImageField, \
@@ -91,5 +91,5 @@
required=True)
-class IExtFileContainerTarget(IAssociationTarget):
+class IExtFileContainerTarget(IAssociationContainerTarget):
"""External files container marker interface"""
--- a/src/pyams_content/component/extfile/zmi/container.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/extfile/zmi/container.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,8 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationTarget, IAssociationContainer, IAssociationInfo
+from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationContainer, \
+ IAssociationInfo
from pyams_content.component.extfile.interfaces import IExtFile, IExtImage
from pyams_i18n.interfaces import II18n
from pyams_skin.layer import IPyAMSLayer
@@ -37,7 +38,7 @@
def get_files_list(request):
"""Get container files in JSON format for TinyMCE editor"""
result = []
- target = get_parent(request.context, IAssociationTarget)
+ target = get_parent(request.context, IAssociationContainerTarget)
if target is not None:
container = IAssociationContainer(target)
result.extend([{'title': IAssociationInfo(item).user_title,
@@ -52,7 +53,7 @@
def get_images_list(request):
"""Get container images in JSON format for TinyMCE editor"""
result = []
- target = get_parent(request.context, IAssociationTarget)
+ target = get_parent(request.context, IAssociationContainerTarget)
if target is not None:
container = IAssociationContainer(target)
result.extend([{'title': IAssociationInfo(item).user_title,
--- a/src/pyams_content/component/gallery/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/gallery/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -93,7 +93,7 @@
title = I18nTextLineField(title=_("Title"),
description=_("Gallery title, as shown in front-office"),
- required=True)
+ required=False)
description = I18nTextField(title=_("Description"),
description=_("Gallery description displayed by front-office template"),
--- a/src/pyams_content/component/illustration/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/illustration/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -17,7 +17,8 @@
# import interfaces
from pyams_content.component.illustration.interfaces import IIllustration, IIllustrationTarget, \
- ILLUSTRATION_KEY, ILLUSTRATION_RENDERERS
+ ILLUSTRATION_KEY, ILLUSTRATION_RENDERERS, IBasicIllustration, IBasicIllustrationTarget, BASIC_ILLUSTRATION_KEY, \
+ ILinkIllustrationTarget, LINK_ILLUSTRATION_KEY, ILinkIllustration
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
@@ -46,17 +47,14 @@
from pyams_content import _
-@implementer(IIllustration)
-@factory_config(provided=IIllustration)
-class Illustration(RenderedContentMixin, Persistent, Contained):
+@implementer(IBasicIllustration)
+@factory_config(provided=IBasicIllustration)
+class BasicIllustration(Persistent, Contained):
"""Illustration persistent class"""
_data = I18nFileProperty(IIllustration['data'])
title = FieldProperty(IIllustration['title'])
alt_title = FieldProperty(IIllustration['alt_title'])
- description = FieldProperty(IIllustration['description'])
- author = FieldProperty(IIllustration['author'])
- renderer = FieldProperty(IIllustration['renderer'])
@property
def data(self):
@@ -69,6 +67,36 @@
if IImage.providedBy(data):
alsoProvides(data, IResponsiveImage)
+ def has_data(self):
+ if not self._data:
+ return False
+ for data in self._data.values():
+ if bool(data):
+ return True
+ return False
+
+
+@adapter_config(context=IBasicIllustrationTarget, provides=IIllustration)
+def basic_illustration_factory(context):
+ """Basic illustration factory"""
+
+ def illustration_callback(illustration):
+ get_current_registry().notify(ObjectAddedEvent(illustration, context, illustration.__name__))
+
+ return get_annotation_adapter(context, BASIC_ILLUSTRATION_KEY, BasicIllustration,
+ name='++illustration++',
+ callback=illustration_callback)
+
+
+@implementer(IIllustration)
+@factory_config(provided=IIllustration)
+class Illustration(RenderedContentMixin, BasicIllustration):
+ """Illustration persistent class"""
+
+ description = FieldProperty(IIllustration['description'])
+ author = FieldProperty(IIllustration['author'])
+ renderer = FieldProperty(IIllustration['renderer'])
+
@adapter_config(context=IIllustrationTarget, provides=IIllustration)
def illustration_factory(context):
@@ -82,6 +110,20 @@
callback=illustration_callback)
+@adapter_config(context=ILinkIllustrationTarget, provides=ILinkIllustration)
+@adapter_config(name='link', context=ILinkIllustrationTarget, provides=IIllustration)
+def link_illustration_factory(context):
+ """Link illustration factory"""
+
+ def illustration_callback(illustration):
+ get_current_registry().notify(ObjectAddedEvent(illustration, context, illustration.__name__))
+
+ return get_annotation_adapter(context, LINK_ILLUSTRATION_KEY, BasicIllustration,
+ markers=ILinkIllustration,
+ name='++illustration++link',
+ callback=illustration_callback)
+
+
def update_illustration_properties(illustration):
"""Update missing file properties"""
request = check_request()
@@ -95,21 +137,21 @@
info.description = II18n(illustration).get_attribute('alt_title', lang, request)
-@subscriber(IObjectAddedEvent, context_selector=IIllustration)
+@subscriber(IObjectAddedEvent, context_selector=IBasicIllustration)
def handle_added_illustration(event):
"""Handle added illustration"""
illustration = event.object
update_illustration_properties(illustration)
-@subscriber(IObjectModifiedEvent, context_selector=IIllustration)
+@subscriber(IObjectModifiedEvent, context_selector=IBasicIllustration)
def handle_modified_illustration(event):
"""Handle modified illustration"""
illustration = event.object
update_illustration_properties(illustration)
-@adapter_config(name='illustration', context=IIllustrationTarget, provides=ITraversable)
+@adapter_config(name='illustration', context=IBasicIllustrationTarget, provides=ITraversable)
class IllustrationNamespace(ContextAdapter):
"""++illustration++ namespace adapter"""
@@ -118,12 +160,14 @@
return registry.queryAdapter(self.context, IIllustration, name=name)
-@adapter_config(name='illustration', context=IIllustrationTarget, provides=ISublocations)
+@adapter_config(name='illustration', context=IBasicIllustrationTarget, provides=ISublocations)
class IllustrationSublocations(ContextAdapter):
"""Illustration sub-locations adapter"""
def sublocations(self):
- return IIllustration(self.context),
+ registry = get_global_registry()
+ for name, adapter in registry.getAdapters((self, ), IBasicIllustration):
+ yield adapter
@adapter_config(context=IIllustration, provides=IContentChecker)
--- a/src/pyams_content/component/illustration/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/illustration/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -22,6 +22,7 @@
from zope.annotation.interfaces import IAttributeAnnotatable
# import packages
+from zope.interface import Interface
from zope.schema import Choice, TextLine
from pyams_content import _
@@ -31,17 +32,24 @@
# Illustration
#
+BASIC_ILLUSTRATION_KEY = 'pyams_content.illustration.base'
+
ILLUSTRATION_KEY = 'pyams_content.illustration'
ILLUSTRATION_RENDERERS = 'PyAMS.illustration.renderers'
+LINK_ILLUSTRATION_KEY = '{0}::link'.format(ILLUSTRATION_KEY)
-class IIllustration(IRenderedContent):
- """Illustration paragraph"""
+
+class IBasicIllustration(Interface):
+ """Basic illustration interface"""
data = I18nThumbnailMediaField(title=_("Image or video data"),
description=_("Image or video content"),
required=False)
+ def has_data(self):
+ """Check if data is provided in any language"""
+
title = I18nTextLineField(title=_("Legend"),
required=False)
@@ -49,6 +57,10 @@
description=_("Alternate title used to describe image content"),
required=False)
+
+class IIllustration(IBasicIllustration, IRenderedContent):
+ """Illustration paragraph"""
+
description = I18nTextField(title=_("Description"),
description=_(""),
required=False)
@@ -63,9 +75,25 @@
default='default')
-class IIllustrationTarget(IAttributeAnnotatable):
- """Illustration target marker interface"""
+class ILinkIllustration(IBasicIllustration):
+ """Navigation link illustration interface"""
+
+
+class IBasicIllustrationTarget(IAttributeAnnotatable):
+ """Basic illustration target marker interface"""
+
+class IIllustrationTarget(IBasicIllustrationTarget):
+ """Illustration target interface"""
+
+
+class ILinkIllustrationTarget(IBasicIllustrationTarget):
+ """Link illustration target interface"""
+
+
+#
+# Illustration paragraph
+#
ILLUSTRATION_PARAGRAPH_TYPE = 'Illustration'
ILLUSTRATION_PARAGRAPH_NAME = _("Illustration")
--- a/src/pyams_content/component/illustration/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/illustration/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,16 +16,16 @@
# import standard library
# import interfaces
-from pyams_content.component.illustration.interfaces import IIllustration, IIllustrationTarget
+from pyams_content.component.illustration.interfaces import IBasicIllustration, IBasicIllustrationTarget, \
+ IIllustration, IIllustrationTarget, ILinkIllustrationTarget
from pyams_content.component.paragraph import IBaseParagraph
-from pyams_content.component.paragraph.zmi.interfaces import IParagraphContainerTable, IParagraphTitleToolbar
from pyams_form.interfaces.form import IInnerSubForm, IWidgetsPrefixViewletsManager
from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
from pyams_zmi.interfaces import IPropertiesEditForm
from transaction.interfaces import ITransactionManager
# import packages
+from pyams_content.component.illustration.zmi.paragraph import ParagraphContainerIllustrationMarker
from pyams_content.component.paragraph.zmi import get_json_paragraph_markers_refresh_event
from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
from pyams_skin.event import get_json_form_refresh_event, get_json_widget_refresh_event
@@ -42,38 +42,57 @@
# Illustration properties inner edit form
#
-@viewlet_config(name='illustration', context=IIllustrationTarget, layer=IPyAMSLayer, view=IParagraphContainerTable,
- manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=5)
-@template_config(template='templates/paragraph-illustration-icon.pt', layer=IPyAMSLayer)
-class ParagraphContainerIllustrationMarker(Viewlet):
- """Paragraph container illustration marker column"""
+@adapter_config(name='illustration', context=(IBasicIllustrationTarget, IPyAMSLayer, IPropertiesEditForm),
+ provides=IInnerSubForm)
+class BasicIllustrationPropertiesInnerEditForm(InnerAdminEditForm):
+ """Basic illustration properties inner edit form"""
+
+ prefix = 'basic_illustration_form.'
+
+ css_class = 'form-group'
+ padding_class = ''
+ fieldset_class = 'bordered margin-top-10 padding-y-5'
+
+ legend = _("Illustration")
+ legend_class = 'illustration switcher no-y-padding padding-right-10'
+
+ fields = field.Fields(IBasicIllustration).omit('__parent__', '__name__')
+
+ weight = 10
- weight = 5
- action_class = 'action illustration nowrap width-40'
- icon_class = 'fa fa-fw fa-picture-o'
- icon_hint = _("Illustration")
+ def getContent(self):
+ return IIllustration(self.context)
- marker_type = 'illustration'
+ def check_mode(self):
+ if self.parent_form is not None:
+ self.mode = self.parent_form.mode
- def render(self):
- illustration = IIllustration(self.context, None)
- if illustration and illustration.data:
- for value in illustration.data.values():
- if value:
- return super(ParagraphContainerIllustrationMarker, self).render()
- return ''
+ @property
+ def switcher_state(self):
+ content = self.getContent()
+ if content.has_data():
+ return 'open'
+
+ def get_ajax_output(self, changes):
+ output = super(BasicIllustrationPropertiesInnerEditForm, self).get_ajax_output(changes)
+ updated = changes.get(IBasicIllustration, ())
+ if 'data' in updated:
+ # we have to commit transaction to be able to handle blobs...
+ ITransactionManager(self.context).get().commit()
+ output.setdefault('events', []).append(
+ get_json_form_refresh_event(self.context, self.request, self.__class__))
+ return output
@adapter_config(name='illustration', context=(IIllustrationTarget, IPyAMSLayer, IPropertiesEditForm),
provides=IInnerSubForm)
-class IllustrationPropertiesInnerEditForm(InnerAdminEditForm):
+class IllustrationPropertiesInnerEditForm(BasicIllustrationPropertiesInnerEditForm):
"""Illustration properties inner edit form"""
prefix = 'illustration_form.'
- css_class = 'form-group'
- padding_class = ''
- fieldset_class = 'margin-top-10 padding-y-5'
+ fields = field.Fields(IIllustration).omit('__parent__', '__name__')
+ fields['renderer'].widgetFactory = RendererFieldWidget
@property
def legend(self):
@@ -87,20 +106,21 @@
if IBaseParagraph.providedBy(self.context):
return 'illustration switcher no-y-padding padding-right-10 pull-left width-auto'
else:
- return 'illustration no-y-padding'
+ return 'illustration switcher no-y-padding'
- fields = field.Fields(IIllustration).omit('__parent__', '__name__')
- fields['renderer'].widgetFactory = RendererFieldWidget
+ @property
+ def fieldset_class(self):
+ result = 'margin-top-10 padding-y-5'
+ if not IBaseParagraph.providedBy(self.context):
+ result += ' bordered'
+ return result
hide_widgets_prefix_div = True
- weight = 10
- def getContent(self):
- return IIllustration(self.context)
-
- def check_mode(self):
- if self.parent_form is not None:
- self.mode = self.parent_form.mode
+ @property
+ def switcher_state(self):
+ if not IBaseParagraph.providedBy(self.context):
+ return 'open'
def updateWidgets(self, prefix=None):
super(IllustrationPropertiesInnerEditForm, self).updateWidgets(prefix)
@@ -109,13 +129,8 @@
def get_ajax_output(self, changes):
output = super(IllustrationPropertiesInnerEditForm, self).get_ajax_output(changes)
- updated = changes.get(IIllustration, ())
events = output.setdefault('events', [])
- if 'data' in updated:
- # we have to commit transaction to be able to handle blobs...
- ITransactionManager(self.context).get().commit()
- events.append(get_json_form_refresh_event(self.context, self.request,
- IllustrationPropertiesInnerEditForm))
+ if 'data' in changes.get(IBasicIllustration, ()):
if IBaseParagraph.providedBy(self.context):
if self.getContent().data:
events.append(get_json_paragraph_markers_refresh_event(self.context, self.request, self,
@@ -124,14 +139,31 @@
events.append(get_json_paragraph_markers_refresh_event(self.context, self.request, self,
EmptyViewlet,
ParagraphContainerIllustrationMarker.marker_type))
- elif 'renderer' in updated:
+ elif 'renderer' in changes.get(IIllustration, ()):
events.append(get_json_widget_refresh_event(self.context, self.request,
IllustrationPropertiesInnerEditForm, 'renderer'))
return output
-@viewlet_config(name='illustration-thumbnail', context=IIllustrationTarget, layer=IPyAMSLayer,
- view=IllustrationPropertiesInnerEditForm, manager=IWidgetsPrefixViewletsManager)
+@adapter_config(name='link-illustration', context=(ILinkIllustrationTarget, IPyAMSLayer, IPropertiesEditForm),
+ provides=IInnerSubForm)
+class LinkIllustrationPropertiesInnerEditForm(BasicIllustrationPropertiesInnerEditForm):
+ """Link illustration properties inner edit form"""
+
+ prefix = 'link_illustration_form.'
+
+ legend = _("Navigation link illustration")
+ legend_class = 'illustration switcher no-y-padding'
+
+ weight = 11
+
+ def getContent(self):
+ registry = self.request.registry
+ return registry.getAdapter(self.context, IIllustration, name='link')
+
+
+@viewlet_config(name='illustration-thumbnail', context=IBasicIllustrationTarget, layer=IPyAMSLayer,
+ view=BasicIllustrationPropertiesInnerEditForm, manager=IWidgetsPrefixViewletsManager)
@template_config(template='templates/illustration-thumbnail.pt', layer=IPyAMSLayer)
class IllustrationThumbnail(Viewlet):
"""Paragraph illustration thumbnail"""
--- a/src/pyams_content/component/illustration/zmi/paragraph.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/illustration/zmi/paragraph.py Wed Jun 27 16:42:01 2018 +0200
@@ -18,13 +18,15 @@
# import interfaces
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, \
IParagraphContainer
-from pyams_content.component.illustration.interfaces import IIllustration, IIllustrationParagraph, \
- ILLUSTRATION_PARAGRAPH_TYPE
-from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor, IParagraphContainerView
+from pyams_content.component.illustration.interfaces import IIllustrationTarget, IIllustration, \
+ IIllustrationParagraph, ILLUSTRATION_PARAGRAPH_TYPE
+from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor, IParagraphContainerView, \
+ IParagraphContainerTable, IParagraphTitleToolbar
from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
from pyams_form.interfaces.form import IInnerForm
from pyams_skin.interfaces.viewlet import IToolbarAddingMenu
from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
from transaction.interfaces import ITransactionManager
from z3c.form.interfaces import INPUT_MODE
@@ -36,8 +38,9 @@
from pyams_form.form import ajax_config
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.event import get_json_form_refresh_event
+from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
-from pyams_viewlet.viewlet import viewlet_config
+from pyams_viewlet.viewlet import viewlet_config, Viewlet
from pyams_zmi.form import AdminDialogAddForm
from z3c.form import field, button
from zope.interface import implementer
@@ -147,3 +150,29 @@
output.setdefault('events', []).append(get_json_form_refresh_event(self.context, self.request,
IllustrationInnerEditForm))
return output
+
+
+#
+# Paragraph container illustration marker
+#
+
+@viewlet_config(name='illustration', context=IIllustrationTarget, layer=IPyAMSLayer, view=IParagraphContainerTable,
+ manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=5)
+@template_config(template='templates/paragraph-illustration-icon.pt', layer=IPyAMSLayer)
+class ParagraphContainerIllustrationMarker(Viewlet):
+ """Paragraph container illustration marker column"""
+
+ weight = 5
+ action_class = 'action illustration nowrap width-40'
+ icon_class = 'fa fa-fw fa-picture-o'
+ icon_hint = _("Illustration")
+
+ marker_type = 'illustration'
+
+ def render(self):
+ illustration = IIllustration(self.context, None)
+ if illustration and illustration.data:
+ for value in illustration.data.values():
+ if value:
+ return super(ParagraphContainerIllustrationMarker, self).render()
+ return ''
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,204 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.keynumber.interfaces import IKeyNumber, IKeyNumberContainerTarget, IKeyNumberContainer, \
+ KEYNUMBER_CONTAINER_KEY
+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.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent
+from zope.location.interfaces import ISublocations
+from zope.traversing.interfaces import ITraversable
+
+# import packages
+from pyams_catalog.utils import index_object
+from pyams_content.features.checker import BaseContentChecker
+from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
+from pyams_utils.registry import get_current_registry, get_utility
+from pyams_utils.request import check_request
+from pyams_utils.traversing import get_parent
+from persistent import Persistent
+from pyramid.events import subscriber
+from zope.container.contained import Contained
+from zope.container.ordered import OrderedContainer
+from zope.interface import implementer
+from zope.lifecycleevent import ObjectModifiedEvent
+from zope.location.location import locate
+from zope.schema.fieldproperty import FieldProperty
+
+from pyams_content import _
+
+
+#
+# Key number class and adapters
+#
+
+@implementer(IKeyNumber)
+class KeyNumber(Persistent, Contained):
+ """Key number persistent class"""
+
+ visible = FieldProperty(IKeyNumber['visible'])
+ label = FieldProperty(IKeyNumber['label'])
+ number = FieldProperty(IKeyNumber['number'])
+ unit = FieldProperty(IKeyNumber['unit'])
+ text = FieldProperty(IKeyNumber['text'])
+
+
+@adapter_config(context=IKeyNumber, provides=IFormContextPermissionChecker)
+class KeyNumberPermissionChecker(ContextAdapter):
+ """Key number permission checker"""
+
+ @property
+ def edit_permission(self):
+ content = get_parent(self.context, IKeyNumberContainerTarget)
+ return IFormContextPermissionChecker(content).edit_permission
+
+
+@subscriber(IObjectAddedEvent, context_selector=IKeyNumber)
+def handle_added_keynumber(event):
+ """Handle added key number"""
+ content = get_parent(event.object, IKeyNumberContainerTarget)
+ if content is not None:
+ get_current_registry().notify(ObjectModifiedEvent(content))
+
+
+@subscriber(IObjectModifiedEvent, context_selector=IKeyNumber)
+def handle_modified_keynumber(event):
+ """Handle modified key number"""
+ content = get_parent(event.object, IKeyNumberContainerTarget)
+ if content is not None:
+ get_current_registry().notify(ObjectModifiedEvent(content))
+
+
+@subscriber(IObjectRemovedEvent, context_selector=IKeyNumber)
+def handle_removed_keynumber(event):
+ """Handle removed key number"""
+ content = get_parent(event.object, IKeyNumberContainerTarget)
+ if content is not None:
+ get_current_registry().notify(ObjectModifiedEvent(content))
+
+
+@adapter_config(context=IKeyNumber, provides=IContentChecker)
+class KeyNumberContentChecker(BaseContentChecker):
+ """Key number content checker"""
+
+ @property
+ def label(self):
+ request = check_request()
+ return II18n(self.context).query_attribute('title', request=request)
+
+ def inner_check(self, request):
+ output = []
+ translate = request.localizer.translate
+ manager = get_parent(self.context, II18nManager)
+ if manager is not None:
+ langs = manager.get_languages()
+ else:
+ negotiator = get_utility(INegotiator)
+ langs = (negotiator.server_language, )
+ i18n = II18n(self.context)
+ for lang in langs:
+ for attr in ('label', 'text'):
+ value = i18n.get_attribute(attr, lang, request)
+ if not value:
+ field_title = translate(IKeyNumber[attr].title)
+ if len(langs) == 1:
+ output.append(translate(MISSING_VALUE).format(field=field_title))
+ else:
+ output.append(translate(MISSING_LANG_VALUE).format(field=field_title, lang=lang))
+ return output
+
+
+#
+# Key numbers container classes and adapters
+#
+
+@implementer(IKeyNumberContainer)
+class KeyNumberContainer(OrderedContainer):
+ """Key numbers container"""
+
+ last_id = 1
+
+ def append(self, value, notify=True):
+ key = str(self.last_id)
+ if not notify:
+ # pre-locate key number item to avoid multiple notifications
+ locate(value, self, key)
+ self[key] = value
+ self.last_id += 1
+ if not notify:
+ # make sure that key number item is correctly indexed
+ index_object(value)
+
+ def get_visible_items(self):
+ return filter(lambda x: IKeyNumber(x).visible, self.values())
+
+
+@adapter_config(context=IKeyNumberContainerTarget, provides=IKeyNumberContainer)
+def keynumber_container_factory(target):
+ """Key number container factory"""
+ return get_annotation_adapter(target, KEYNUMBER_CONTAINER_KEY, KeyNumberContainer,
+ name='++keynumbers++')
+
+
+@adapter_config(context=IKeyNumberContainer, provides=IFormContextPermissionChecker)
+class KeyNumberContainerPermissionChecker(ContextAdapter):
+ """Key number container permission checker"""
+
+ @property
+ def edit_permission(self):
+ content = get_parent(self.context, IKeyNumberContainerTarget)
+ return IFormContextPermissionChecker(content).edit_permission
+
+
+@adapter_config(name='keynumbers', context=IKeyNumberContainerTarget, provides=ITraversable)
+class KeyNumberContainerNamespace(ContextAdapter):
+ """Key numbers container ++keynumbers++ namespace"""
+
+ def traverse(self, name, furtherpaath=None):
+ return IKeyNumberContainer(self.context)
+
+
+@adapter_config(name='keynumbers', context=IKeyNumberContainerTarget, provides=ISublocations)
+class KeyNumberContainerSublocations(ContextAdapter):
+ """Key numbers container sub-locations adapter"""
+
+ def sublocations(self):
+ return IKeyNumberContainer(self.context).values()
+
+
+@adapter_config(name='keynumbers', context=IKeyNumberContainerTarget, provides=IContentChecker)
+class KeyNumberContainerContentChecker(BaseContentChecker):
+ """Key numbers container content checker"""
+
+ label = _("Key numbers")
+ sep = '\n'
+ weight = 200
+
+ def inner_check(self, request):
+ output = []
+ registry = request.registry
+ for keynumber in IKeyNumberContainer(self.context).values():
+ if not keynumber.visible:
+ continue
+ for name, checker in sorted(registry.getAdapters((keynumber, ), IContentChecker),
+ key=lambda x: x[1].weight):
+ output.append('- {0} ({1}):'.format(keynumber.number,
+ II18n(keynumber).query_attribute('label', request=request) or '--'))
+ output.append(checker.get_check_output(request))
+ return output
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.interfaces.container import IOrderedContainer
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField
+from zope.container.constraints import containers, contains
+from zope.interface import Interface
+from zope.schema import Bool, TextLine
+
+from pyams_content import _
+
+
+KEYNUMBER_CONTAINER_KEY = 'pyams_content.keynumbers'
+
+
+class IKeyNumber(IAttributeAnnotatable):
+ """Base key number interface"""
+
+ containers('.IKeyNumberContainer')
+
+ visible = Bool(title=_("Visible?"),
+ description=_("Is this key number visible in front-office?"),
+ required=True,
+ default=True)
+
+ label = I18nTextLineField(title=_('key-number-label', default="Header"),
+ description=_("Small text to be displayed above number (according to selected "
+ "renderer)"),
+ required=False)
+
+ number = TextLine(title=_("Number"),
+ description=_("Key number value"),
+ required=True)
+
+ unit = I18nTextLineField(title=_('key-number-unit', default="Unit"),
+ description=_("Displayed unit"),
+ required=False)
+
+ text = I18nTextLineField(title=_("Associated text"),
+ description=_("The way this text will be rendered depends on presentation template"),
+ required=False)
+
+
+class IKeyNumberContainer(IOrderedContainer):
+ """Key numbers container interface"""
+
+ contains(IKeyNumber)
+
+ def append(self, value, notify=True):
+ """Append given key number to container"""
+
+ def get_visible_items(self):
+ """Get list of visible key numbers"""
+
+
+class IKeyNumberContainerTarget(Interface):
+ """Key numbers container target interface"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/portlet/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,76 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
+from pyams_content.component.keynumber.interfaces import IKeyNumberContainerTarget, IKeyNumberContainer
+from pyams_content.component.keynumber.portlet.interfaces import IKeyNumberPortletSettings, IKeyNumberPortletMenu
+from pyams_content.features.menu.interfaces import IMenuLinksContainerTarget, IMenuLinksContainer
+from pyams_utils.interfaces import VIEW_PERMISSION
+
+# import packages
+from pyams_content.features.menu import Menu
+from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
+from pyams_utils.adapter import get_annotation_adapter, adapter_config
+from pyams_utils.factory import factory_config
+from zope.interface import implementer
+from zope.schema.fieldproperty import FieldProperty
+
+from pyams_content import _
+
+
+KEYNUMBER_PORTLET_NAME = "pyams_portal.portlet.keynumber"
+
+KEYNUMBER_PORTLET_LINKS_NAME = 'links'
+KEYNUMBER_PORTLET_LINKS_KEY = '{0}::{1}'.format(ASSOCIATION_CONTAINER_KEY, KEYNUMBER_PORTLET_LINKS_NAME)
+
+
+@implementer(IKeyNumberPortletSettings, IKeyNumberContainerTarget, IMenuLinksContainerTarget)
+@factory_config(provided=IKeyNumberPortletSettings)
+class KeyNumberPortletSettings(PortletSettings):
+ """Key Number portlet settings"""
+
+ title = FieldProperty(IKeyNumberPortletSettings['title'])
+ teaser = FieldProperty(IKeyNumberPortletSettings['teaser'])
+
+ @property
+ def keynumbers(self):
+ return IKeyNumberContainer(self)
+
+ @property
+ def links(self):
+ return get_annotation_adapter(self, KEYNUMBER_PORTLET_LINKS_KEY, Menu,
+ markers=IKeyNumberPortletMenu,
+ name='++ass++' + KEYNUMBER_PORTLET_LINKS_NAME)
+
+
+@adapter_config(name=KEYNUMBER_PORTLET_LINKS_NAME, context=IKeyNumberPortletSettings, provides=IMenuLinksContainer)
+def keynumber_links_adapter(context):
+ """Key number settings links factory"""
+ return context.links
+
+
+@portlet_config(permission=VIEW_PERMISSION)
+class KeyNumberPortlet(Portlet):
+ """Key number portlet"""
+
+ name = KEYNUMBER_PORTLET_NAME
+ label = _("Key Numbers")
+
+ toolbar_image = None
+ toolbar_css_class = 'fa fa-fw fa-2x fa-dashboard'
+
+ settings_factory = IKeyNumberPortletSettings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/portlet/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_portal.interfaces import IPortletSettings
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField, I18nTextField
+from zope.interface import Attribute, Interface
+
+from pyams_content import _
+
+
+class IKeyNumberPortletSettings(IPortletSettings):
+ """Key numbers portlet settings interface"""
+
+ title = I18nTextLineField(title=_("Title"),
+ description=_("Portlet title"),
+ required=False)
+
+ teaser = I18nTextField(title=_("Teaser"),
+ description=_("Short text displayed above key numbers"),
+ required=False)
+
+ links = Attribute("Navigation links")
+
+
+class IKeyNumberPortletMenu(Interface):
+ """Key numbers portlet menu marker interface"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/portlet/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,126 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.association.interfaces import IAssociationInfo
+from pyams_content.component.keynumber.portlet.interfaces import IKeyNumberPortletSettings, IKeyNumberPortletMenu
+from pyams_content.features.menu.zmi import IMenuLinksView
+from pyams_content.component.links.interfaces import IInternalLink
+from pyams_portal.interfaces import IPortletPreviewer
+from pyams_form.interfaces.form import IInnerSubForm, IInnerTabForm
+from pyams_pagelet.interfaces import IPagelet
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_workflow.interfaces import IWorkflowPublicationInfo
+
+# import packages
+from pyams_content.component.keynumber.portlet import KEYNUMBER_PORTLET_LINKS_NAME
+from pyams_content.component.keynumber.zmi import KeyNumbersView
+from pyams_content.features.menu.zmi import MenuLinksView, LinksTable
+from pyams_form.form import AJAXEditForm
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_portal.portlet import PortletPreviewer
+from pyams_portal.zmi.portlet import PortletSettingsEditor, PortletSettingsPropertiesEditor
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+from zope.interface import Interface
+
+from pyams_content import _
+
+
+@pagelet_config(name='properties.html', context=IKeyNumberPortletSettings, layer=IPyAMSLayer,
+ permission=VIEW_SYSTEM_PERMISSION)
+class KeyNumberPortletEditor(PortletSettingsEditor):
+ """Key number portlet settings editor"""
+
+ settings = IKeyNumberPortletSettings
+
+
+@adapter_config(name='properties', context=(Interface, IPyAMSLayer, KeyNumberPortletEditor), provides=IInnerTabForm)
+class KeyNumberPortletSettingsPropertiesEditor(PortletSettingsPropertiesEditor):
+ """Key number portlet settings properties editor"""
+
+ def updateWidgets(self, prefix=None):
+ super().updateWidgets(prefix)
+ if 'teaser' in self.widgets:
+ self.widgets['teaser'].widget_css_class = 'textarea'
+
+
+@adapter_config(name='properties.json', context=(IKeyNumberPortletSettings, IPyAMSLayer), provides=IPagelet)
+class KeyNumberPortletAJAXEditor(AJAXEditForm, KeyNumberPortletEditor):
+ """Key number portlet settings editor, JSON renderer"""
+
+
+#
+# Key numbers portlet numbers view
+#
+
+@adapter_config(name='keynumber-portlet-numbers',
+ context=(IKeyNumberPortletSettings, IPyAMSLayer, PortletSettingsPropertiesEditor),
+ provides=IInnerSubForm)
+class KeyNumberPortletNumbersView(KeyNumbersView):
+ """Key number portlet numbers view"""
+
+ title = _("Key numbers")
+ weight = 10
+
+
+#
+# Key numbers portlet links view
+#
+
+class KeyNumberPortletLinksTable(LinksTable):
+ """Key Numbers links associations table"""
+
+ associations_name = KEYNUMBER_PORTLET_LINKS_NAME
+
+
+@adapter_config(name='keynumber-portlet-links',
+ context=(IKeyNumberPortletSettings, IPyAMSLayer, PortletSettingsPropertiesEditor),
+ provides=IInnerSubForm)
+@adapter_config(name='++ass++{0}'.format(KEYNUMBER_PORTLET_LINKS_NAME),
+ context=(IKeyNumberPortletMenu, IPyAMSLayer),
+ provides=IMenuLinksView)
+class KeyNumberPortletLinksView(MenuLinksView):
+ """Key numbers portlet links view"""
+
+ title = _("Associated links")
+ weight = 20
+
+ table_class = KeyNumberPortletLinksTable
+
+
+#
+# Key numbers portlet previewer
+#
+
+@adapter_config(context=(Interface, IPyAMSLayer, Interface, IKeyNumberPortletSettings), provides=IPortletPreviewer)
+@template_config(template='templates/keynumber-preview.pt', layer=IPyAMSLayer)
+class KeyNumberPortletPreviewer(PortletPreviewer):
+ """Key number portlet previewer"""
+
+ @classmethod
+ def get_link_info(cls, link):
+ return IAssociationInfo(link)
+
+ @classmethod
+ def get_link_status(cls, link):
+ if not IInternalLink.providedBy(link):
+ return True
+ target = link.get_target()
+ return (target is not None) and IWorkflowPublicationInfo(target).is_published()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/portlet/zmi/templates/keynumber-preview.pt Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,35 @@
+<div tal:define="settings view.settings" i18n:domain="pyams_content">
+ <strong tal:define="title i18n:settings.title"
+ tal:condition="title">
+ <tal:var content="title"/><br /></strong>
+ <div tal:define="teaser i18n:settings.teaser"
+ tal:content="structure extension:html(teaser)">Teaser</div>
+ <ul>
+ <li tal:repeat="number settings.keynumbers.get_visible_items()">
+ <span tal:define="label i18n:number.label"
+ tal:condition="label">
+ <tal:var content="label" /> : </span>
+ <span class="badge"
+ tal:content="i18n:number.number">Number</span>
+ <span tal:define="unit i18n:number.unit"
+ tal:condition="unit"
+ tal:content="unit">Unit</span>
+ <span tal:content="i18n:number.text">text</span>
+ </li>
+ </ul>
+ <div tal:define="visible_links list(settings.links.get_visible_items())"
+ tal:condition="visible_links">
+ <u><i18n:var translate="" >Associated links</i18n:var> :</u>
+ <ul>
+ <li tal:repeat="link visible_links">
+ <i class="fa fa-fw fa-eye-slash text-danger hint opaque align-base"
+ tal:condition="not:view.get_link_status(link)"
+ title="Link target is not published!" i18n:attributes="title"></i>
+ <tal:var define="info view.get_link_info(link)">
+ <span tal:content="info.user_title">User title</span>
+ <span tal:content="info.inner_title">Inner title</span>
+ </tal:var>
+ </li>
+ </ul>
+ </div>
+</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/keynumber/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,271 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import json
+
+# import interfaces
+from pyams_content.component.keynumber.interfaces import IKeyNumberContainer, IKeyNumberContainerTarget, IKeyNumber
+from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
+from pyams_form.interfaces.form import IInnerSubForm
+from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager
+from pyams_skin.layer import IPyAMSLayer
+from z3c.table.interfaces import IValues, IColumn
+
+# import packages
+from pyams_content.component.keynumber import KeyNumber
+from pyams_form.form import ajax_config, AJAXAddForm
+from pyams_form.security import ProtectedFormObjectMixin
+from pyams_i18n.column import I18nAttrColumn
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.container import switch_element_visibility
+from pyams_skin.event import get_json_table_row_refresh_event, get_json_switched_table_refresh_event
+from pyams_skin.table import BaseTable, SorterColumn, VisibilitySwitcherColumn, I18nColumn, TrashColumn
+from pyams_skin.viewlet.toolbar import ToolbarAction
+from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
+from pyams_utils.traversing import get_parent
+from pyams_utils.url import absolute_url
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
+from pyams_zmi.zmi.table import InnerTableView
+from pyramid.decorator import reify
+from pyramid.view import view_config
+from z3c.form import field
+from z3c.table.column import GetAttrColumn
+from zope.interface import implementer, Interface
+
+from pyams_content import _
+
+
+#
+# Views marker interfaces
+#
+
+class IKeyNumbersView(Interface):
+ """Key numbers view marker interface"""
+
+
+class IKeyNumbersParentForm(Interface):
+ """Key numbers parent form marker interface"""
+
+
+#
+# Key number items table view
+#
+
+class KeyNumbersTable(ProtectedFormObjectMixin, BaseTable):
+ """Key numbers view inner table"""
+
+ prefix = 'keynumbers'
+
+ hide_header = True
+ hide_body_toolbar = True
+ sortOn = None
+
+ @classmethod
+ def get_context(cls, context):
+ return IKeyNumberContainer(context)
+
+ @reify
+ def cssClasses(self):
+ classes = ['table', 'table-bordered', 'table-striped', 'table-hover', 'table-tight']
+ permission = self.permission
+ if (not permission) or self.request.has_permission(permission, self.context):
+ classes.append('table-dnd')
+ return {'table': ' '.join(classes)}
+
+ @reify
+ def data_attributes(self):
+ container = IKeyNumberContainer(self.context)
+ attributes = super(KeyNumbersTable, self).data_attributes
+ attributes.setdefault('table', {}).update({
+ 'data-ams-location': absolute_url(container, self.request),
+ 'data-ams-tablednd-drag-handle': 'td.sorter',
+ 'data-ams-tablednd-drop-target': 'set-keynumbers-order.json',
+ 'data-ams-visibility-switcher': 'switch-keynumber-visibility.json'
+ })
+ return attributes
+
+ @reify
+ def values(self):
+ return list(super(KeyNumbersTable, self).values)
+
+
+@adapter_config(context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable), provides=IValues)
+class KeyNumbersTableValuesAdapter(ContextRequestViewAdapter):
+ """Key numbers table values adapter"""
+
+ @property
+ def values(self):
+ return IKeyNumberContainer(self.context).values()
+
+
+@adapter_config(name='sorter', context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
+class KeyNumbersTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
+ """Key numbers table sorter column"""
+
+
+@view_config(name='set-keynumbers-order.json', context=IKeyNumberContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
+def set_keynumbers_order(request):
+ """Update key numbers order"""
+ order = list(map(str, json.loads(request.params.get('names'))))
+ request.context.updateOrder(order)
+ return {'status': 'success'}
+
+
+@adapter_config(name='show-hide', context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable),
+ provides=IColumn)
+class KeyNumbersTableShowHideColumn(ProtectedFormObjectMixin, VisibilitySwitcherColumn):
+ """Key numbers container visibility switcher column"""
+
+
+@view_config(name='switch-keynumber-visibility.json', context=IKeyNumberContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
+def switch_keynumber_visibility(request):
+ """Switch key number visibility"""
+ return switch_element_visibility(request, IKeyNumberContainer)
+
+
+@adapter_config(name='label', context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
+class KeyNumbersTableLabelColumn(I18nColumn, I18nAttrColumn):
+ """Key numbers table label column"""
+
+ _header = _('key-number-label', default="Header")
+ attrName = 'label'
+ weight = 10
+
+ def getValue(self, obj):
+ return super(KeyNumbersTableLabelColumn, self).getValue(obj) or '--'
+
+
+@adapter_config(name='name', context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
+class KeyNumbersTableNameColumn(I18nColumn, GetAttrColumn):
+ """Key numbers table number column"""
+
+ _header = _("Number")
+ attrName = 'number'
+ weight = 20
+
+
+@adapter_config(name='unit', context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
+class KeyNumbersTableUnitColumn(I18nColumn, I18nAttrColumn):
+ """Key numbers table unit column"""
+
+ _header = _('key-number-unit', default="Unit")
+ attrName = 'unit'
+ weight = 30
+
+ def getValue(self, obj):
+ return super(KeyNumbersTableUnitColumn, self).getValue(obj) or '--'
+
+
+@adapter_config(name='text', context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
+class KeyNumbersTableTextColumn(I18nColumn, I18nAttrColumn):
+ """Key numbers table text column"""
+
+ _header = _("Associated text")
+ attrName = 'text'
+ weight = 40
+
+ def getValue(self, obj):
+ return super(KeyNumbersTableTextColumn, self).getValue(obj) or '--'
+
+
+@adapter_config(name='trash', context=(IKeyNumberContainer, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
+class KeyNumbersTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
+ """Key numbers table trash column"""
+
+
+@adapter_config(name='keynumbers', context=(IKeyNumberContainerTarget, IPyAMSLayer, IKeyNumbersParentForm),
+ provides=IInnerSubForm)
+@implementer(IKeyNumbersView)
+class KeyNumbersView(InnerTableView):
+ """Key numbers view"""
+
+ title = _("Key numbers")
+
+ table_class = KeyNumbersTable
+ weight = 110
+
+ @property
+ def actions_context(self): # define context for internal actions
+ return IKeyNumberContainer(self.context)
+
+
+#
+# Key numbers forms
+#
+
+@viewlet_config(name='add-keynumber.action', context=IKeyNumberContainerTarget, layer=IPyAMSLayer, view=IKeyNumbersView,
+ manager=IWidgetTitleViewletManager, weight=1)
+class KeyNumberAddAction(ProtectedFormObjectMixin, ToolbarAction):
+ """Key number add action"""
+
+ label = _("Add keynumber")
+ label_css_class = 'fa fa-fw fa-plus'
+ url = 'add-keynumber.html'
+ modal_target = True
+
+
+@pagelet_config(name='add-keynumber.html', context=IKeyNumberContainer, layer=IPyAMSLayer)
+@ajax_config(name='add-keynumber.json', context=IKeyNumberContainer, layer=IPyAMSLayer,
+ base=AJAXAddForm)
+class KeyNumberAddForm(AdminDialogAddForm):
+ """Key number add form"""
+
+ legend = _("Add new keynumber")
+ icon_css_class = 'fa fa-fw fa-dashboard'
+
+ fields = field.Fields(IKeyNumber).omit('__parent__', '__name__', 'visible')
+ edit_permission = None # use context permission checker
+
+ def create(self, data):
+ return KeyNumber()
+
+ def add(self, object):
+ IKeyNumberContainer(self.context).append(object)
+
+ def get_ajax_output(self, changes):
+ return {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(_("Key number was correctly added")),
+ 'events': [
+ get_json_switched_table_refresh_event(self.context, self.request, KeyNumbersTable)
+ ]
+ }
+
+
+@pagelet_config(name='properties.html', context=IKeyNumber, layer=IPyAMSLayer)
+@ajax_config(name='properties.json', context=IKeyNumber, layer=IPyAMSLayer)
+class KeyNumberPropertiesEditForm(AdminDialogEditForm):
+ """Key number properties edit form"""
+
+ prefix = 'keynumber_properties.'
+
+ legend = _("Edit keynumber properties")
+ icon_css_class = 'fa fa-fw fa-dashboard'
+
+ fields = field.Fields(IKeyNumber).omit('__parent__', '__name__', 'visible')
+ edit_permission = None # use context permission checker
+
+ def get_ajax_output(self, changes):
+ output = super(self.__class__, self).get_ajax_output(changes)
+ updated = changes.get(IKeyNumber, ())
+ if updated:
+ target = get_parent(self.context, IKeyNumberContainerTarget)
+ output.setdefault('events', []).append(
+ get_json_table_row_refresh_event(target, self.request, KeyNumbersTable, self.context))
+ return output
--- a/src/pyams_content/component/links/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/links/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -9,6 +9,7 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
+from pyams_skin.layer import IPyAMSUserLayer
__docformat__ = 'restructuredtext'
@@ -16,10 +17,11 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationInfo, IAssociationTarget, IAssociationContainer
+from pyams_content.component.association.interfaces import IAssociationInfo, IAssociationContainerTarget, IAssociationContainer
from pyams_content.component.links.interfaces import IBaseLink, IInternalLink, IExternalLink, IMailtoLink
from pyams_content.features.checker.interfaces import IContentChecker, ERROR_VALUE
from pyams_content.interfaces import IBaseContent, MANAGE_CONTENT_PERMISSION
+from pyams_content.reference.pictograms.interfaces import IPictogramTable
from pyams_form.interfaces.form import IFormContextPermissionChecker
from pyams_i18n.interfaces import II18n
from pyams_sequence.interfaces import ISequentialIdInfo
@@ -31,10 +33,12 @@
from pyams_content.workflow import VISIBLE_STATES
from pyams_sequence.utility import get_reference_target
from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.registry import query_utility
from pyams_utils.request import check_request
from pyams_utils.traversing import get_parent
-from pyams_utils.url import absolute_url
+from pyams_utils.url import absolute_url, relative_url
from pyams_utils.vocabulary import vocabulary_config
+from pyams_utils.zodb import volatile_property
from zope.interface import implementer
from zope.schema.fieldproperty import FieldProperty
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
@@ -52,7 +56,7 @@
def __init__(self, context=None):
terms = []
- target = get_parent(context, IAssociationTarget)
+ target = get_parent(context, IAssociationContainerTarget)
if target is not None:
terms = [SimpleTerm(link.__name__, title=IAssociationInfo(link).inner_title)
for link in IAssociationContainer(target).values() if IBaseLink.providedBy(link)]
@@ -69,6 +73,23 @@
title = FieldProperty(IBaseLink['title'])
description = FieldProperty(IBaseLink['description'])
+ _pictogram_name = FieldProperty(IBaseLink['pictogram_name'])
+
+ @property
+ def pictogram_name(self):
+ return self._pictogram_name
+
+ @pictogram_name.setter
+ def pictogram_name(self, value):
+ if value != self._pictogram_name:
+ self._pictogram_name = value
+ del self.pictogram
+
+ @volatile_property
+ def pictogram(self):
+ table = query_utility(IPictogramTable)
+ if table is not None:
+ return table.get(self._pictogram_name)
class BaseLinkInfoAdapter(ContextAdapter):
@@ -112,11 +133,11 @@
return 'oid://{0}'.format(self.reference)
def get_url(self, request=None, view_name=None):
- target = self.get_target(state=VISIBLE_STATES)
+ target = self.get_target()
if target is not None:
if request is None:
request = check_request()
- return absolute_url(target, request, view_name)
+ return relative_url(target, request, view_name=view_name)
else:
return ''
--- a/src/pyams_content/component/links/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/links/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,12 +16,14 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationTarget, IAssociationItem
+from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem
+from pyams_content.reference.pictograms.interfaces import SELECTED_PICTOGRAM_VOCABULARY
from pyams_sequence.interfaces import IInternalReference
# import packages
from pyams_i18n.schema import I18nTextLineField, I18nTextField
from pyams_utils.schema import MailAddressField
+from zope.interface import Attribute
from zope.schema import Choice, TextLine, URI
from pyams_content import _
@@ -38,6 +40,13 @@
description=_("Link description displayed by front-office template"),
required=False)
+ pictogram_name = Choice(title=_("Pictogram"),
+ description=_("Name of the pictogram associated with this link"),
+ required=False,
+ vocabulary=SELECTED_PICTOGRAM_VOCABULARY)
+
+ pictogram = Attribute("Selected pictogram object")
+
def get_editor_url(self):
"""Get URL for use in HTML editor"""
@@ -74,5 +83,5 @@
required=True)
-class ILinkContainerTarget(IAssociationTarget):
+class ILinkContainerTarget(IAssociationContainerTarget):
"""Links container marker interface"""
--- a/src/pyams_content/component/links/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/links/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -18,19 +18,21 @@
# import interfaces
from pyams_content.component.association.interfaces import IAssociationContainer
from pyams_content.component.association.zmi.interfaces import IAssociationsView
-from pyams_content.component.links.interfaces import ILinkContainerTarget, IInternalLink, IBaseLink, \
+from pyams_content.component.links.interfaces import ILinkContainerTarget, IBaseLink, IInternalLink, \
IExternalLink, IMailtoLink
from pyams_content.component.paragraph.zmi.interfaces import IParagraphContainerTable, IParagraphTitleToolbar
from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
from pyams_skin.interfaces.viewlet import IToolbarAddingMenu
from pyams_skin.layer import IPyAMSLayer
from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_zmi.interfaces import IPropertiesEditForm
# import packages
from pyams_content.component.association.zmi import AssociationItemAJAXAddForm, AssociationItemAJAXEditForm
from pyams_content.component.links import InternalLink, ExternalLink, MailtoLink
from pyams_content.component.paragraph.zmi import get_json_paragraph_markers_refresh_event
from pyams_content.component.paragraph.zmi.container import ParagraphContainerCounterBase
+from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
from pyams_form.form import ajax_config
from pyams_form.security import ProtectedFormObjectMixin
from pyams_pagelet.pagelet import pagelet_config
@@ -38,6 +40,7 @@
from pyams_viewlet.viewlet import viewlet_config
from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
from z3c.form import field
+from zope.interface import implementer
from pyams_content import _
@@ -86,7 +89,9 @@
legend = _("Add new internal link")
icon_css_class = 'fa fa-fw fa-external-link-square fa-rotate-90'
- fields = field.Fields(IInternalLink).select('reference', 'title', 'description')
+ fields = field.Fields(IInternalLink).select('reference', 'title', 'description', 'pictogram_name')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = MANAGE_CONTENT_PERMISSION
def updateWidgets(self, prefix=None):
@@ -111,6 +116,7 @@
@pagelet_config(name='properties.html', context=IInternalLink, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
@ajax_config(name='properties.json', context=IInternalLink, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION, base=AssociationItemAJAXEditForm)
+@implementer(IPropertiesEditForm)
class InternalLinkPropertiesEditForm(AdminDialogEditForm):
"""Internal link properties edit form"""
@@ -118,8 +124,11 @@
legend = _("Edit internal link properties")
icon_css_class = 'fa fa-fw fa-external-link-square fa-rotate-90'
+ dialog_class = 'modal-large'
- fields = field.Fields(IInternalLink).select('reference', 'title', 'description')
+ fields = field.Fields(IInternalLink).select('reference', 'title', 'description', 'pictogram_name')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = None # defined by IFormContextPermissionChecker adapter
def updateWidgets(self, prefix=None):
@@ -179,7 +188,9 @@
legend = _("Add new external link")
icon_css_class = 'fa fa-fw fa-external-link'
- fields = field.Fields(IExternalLink).select('url', 'title', 'description', 'language')
+ fields = field.Fields(IExternalLink).select('url', 'title', 'description', 'pictogram_name', 'language')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = MANAGE_CONTENT_PERMISSION
def updateWidgets(self, prefix=None):
@@ -204,6 +215,7 @@
@pagelet_config(name='properties.html', context=IExternalLink, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
@ajax_config(name='properties.json', context=IExternalLink, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION, base=AssociationItemAJAXEditForm)
+@implementer(IPropertiesEditForm)
class ExternalLinkPropertiesEditForm(AdminDialogEditForm):
"""External link properties edit form"""
@@ -211,8 +223,11 @@
legend = _("Edit external link properties")
icon_css_class = 'fa fa-fw fa-external-link'
+ dialog_class = 'modal-large'
- fields = field.Fields(IExternalLink).select('url', 'title', 'description', 'language')
+ fields = field.Fields(IExternalLink).select('url', 'title', 'description', 'pictogram_name', 'language')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = None # defined by IFormContextPermissionChecker adapter
def updateWidgets(self, prefix=None):
@@ -272,7 +287,9 @@
legend = _("Add new mailto link")
icon_css_class = 'fa fa-fw fa-envelope-o'
- fields = field.Fields(IMailtoLink).select('address', 'address_name', 'title', 'description')
+ fields = field.Fields(IMailtoLink).select('address', 'address_name', 'title', 'description', 'pictogram_name')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = MANAGE_CONTENT_PERMISSION
def updateWidgets(self, prefix=None):
@@ -297,6 +314,7 @@
@pagelet_config(name='properties.html', context=IMailtoLink, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
@ajax_config(name='properties.json', context=IMailtoLink, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION, base=AssociationItemAJAXEditForm)
+@implementer(IPropertiesEditForm)
class MailtoLinkPropertiesEditForm(AdminDialogEditForm):
"""Mailto link properties edit form"""
@@ -305,7 +323,9 @@
legend = _("Edit mailto link properties")
icon_css_class = 'fa fa-fw fa-envelope-o'
- fields = field.Fields(IMailtoLink).select('address', 'address_name', 'title', 'description')
+ fields = field.Fields(IMailtoLink).select('address', 'address_name', 'title', 'description', 'pictogram_name')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = None # defined by IFormContextPermissionChecker adapter
def updateWidgets(self, prefix=None):
--- a/src/pyams_content/component/links/zmi/container.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/links/zmi/container.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationTarget, IAssociationInfo
+from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationContainerTarget, IAssociationInfo
from pyams_content.component.extfile.interfaces import IBaseExtFile
from pyams_content.component.links.interfaces import IBaseLink
from pyams_i18n.interfaces import II18n
@@ -40,7 +40,7 @@
result = []
key_field_name = request.params.get('keyFieldName', 'title')
value_field_name = request.params.get('valueFieldName', 'value')
- target = get_parent(request.context, IAssociationTarget)
+ target = get_parent(request.context, IAssociationContainerTarget)
if target is not None:
container = IAssociationContainer(target)
result.extend([{key_field_name: item.__name__,
@@ -54,7 +54,7 @@
def get_links_list(request):
"""Get links list in JSON format for TinyMCE editor"""
result = []
- target = get_parent(request.context, IAssociationTarget)
+ target = get_parent(request.context, IAssociationContainerTarget)
if target is not None:
container = IAssociationContainer(target)
for item in container.values():
--- a/src/pyams_content/component/links/zmi/reverse.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/links/zmi/reverse.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,6 +19,8 @@
from hypatia.interfaces import ICatalog
from pyams_content.shared.common.interfaces import IWfSharedContent
from pyams_content.shared.common.interfaces.zmi import ISiteRootDashboardTable
+from pyams_content.shared.site.interfaces import ISiteContainer
+from pyams_portal.interfaces import IPortalTemplate
from pyams_sequence.interfaces import ISequentialIdInfo
from pyams_skin.interfaces import IInnerPage
from pyams_skin.layer import IPyAMSLayer
@@ -77,11 +79,23 @@
@property
def values(self):
+
+ def get_item(result):
+ parent = get_parent(result, IWfSharedContent)
+ if parent is not None:
+ return IWorkflowVersions(parent).get_last_versions(count=1)[0]
+ parent = get_parent(result, IPortalTemplate)
+ if parent is None:
+ parent = get_parent(result, ISiteContainer)
+ if parent is None:
+ parent = self.request.root
+ return parent
+
catalog = get_utility(ICatalog)
oid = ISequentialIdInfo(self.context).hex_oid
params = Or(Eq(catalog['link_reference'], oid),
Eq(catalog['link_references'], oid))
- return unique(map(lambda x: IWorkflowVersions(get_parent(x, IWfSharedContent)).get_last_versions(count=1)[0],
+ return unique(map(get_item,
CatalogResultSet(CatalogQuery(catalog).query(params,
sort_index='modified_date'))))
--- a/src/pyams_content/component/paragraph/audio.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/audio.py Wed Jun 27 16:42:01 2018 +0200
@@ -44,10 +44,9 @@
icon_class = 'fa-volume-up'
icon_hint = AUDIO_PARAGRAPH_NAME
- body = FieldProperty(IAudioParagraph['body'])
+ data = FileProperty(IAudioParagraph['data'])
description = FieldProperty(IAudioParagraph['description'])
author = FieldProperty(IAudioParagraph['author'])
- data = FileProperty(IAudioParagraph['data'])
renderer = FieldProperty(IAudioParagraph['renderer'])
--- a/src/pyams_content/component/paragraph/interfaces/audio.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/interfaces/audio.py Wed Jun 27 16:42:01 2018 +0200
@@ -20,7 +20,7 @@
# import packages
from pyams_file.schema import AudioField
-from pyams_i18n.schema import I18nHTMLField, I18nTextField
+from pyams_i18n.schema import I18nTextField, I18nTextLineField
from zope.schema import TextLine, Choice
from pyams_content import _
@@ -38,8 +38,12 @@
class IAudioParagraph(IBaseParagraph):
"""Audio paragraph"""
- body = I18nHTMLField(title=_("Body"),
- required=False)
+ data = AudioField(title=_("Audio data"),
+ description=_("Audio file content"),
+ required=True)
+
+ title = I18nTextLineField(title=_("Legend"),
+ required=False)
description = I18nTextField(title=_("Description"),
description=_("File description displayed by front-office template"),
@@ -49,10 +53,6 @@
description=_("Name of document's author"),
required=False)
- data = AudioField(title=_("Audio data"),
- description=_("Audio file content"),
- required=True)
-
renderer = Choice(title=_("Audio template"),
description=_("Presentation template used for this audio file"),
vocabulary=AUDIO_PARAGRAPH_RENDERERS,
--- a/src/pyams_content/component/paragraph/interfaces/keynumber.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/interfaces/keynumber.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,62 +16,15 @@
# import standard library
# import interfaces
+from pyams_content.component.keynumber.interfaces import IKeyNumberContainerTarget
from pyams_content.component.paragraph import IBaseParagraph
-from pyams_content.interfaces.container import IOrderedContainer
-from zope.annotation.interfaces import IAttributeAnnotatable
# import packages
-from pyams_i18n.schema import I18nTextLineField
-from zope.container.constraints import containers, contains
-from zope.interface import Interface
from zope.schema import Bool, Choice, TextLine
from pyams_content import _
-KEYNUMBER_CONTAINER_KEY = 'pyams_content.keynumbers'
-
-
-class IKeyNumber(IAttributeAnnotatable):
- """Base key number interface"""
-
- containers('.IKeyNumberContainer')
-
- visible = Bool(title=_("Visible?"),
- description=_("Is this key number visible in front-office?"),
- required=True,
- default=True)
-
- number = TextLine(title=_("Number"),
- description=_("Key number value"),
- required=True)
-
- label = I18nTextLineField(title=_('key-number-label', default="Header"),
- description=_("Small text to be displayed above number (according to selected "
- "renderer)"),
- required=False)
-
- text = I18nTextLineField(title=_("Associated text"),
- description=_("The way this text will be rendered depends on presentation template"),
- required=False)
-
-
-class IKeyNumberContainer(IOrderedContainer):
- """Key numbers container interface"""
-
- contains(IKeyNumber)
-
- def append(self, value, notify=True):
- """Append given key number to container"""
-
- def get_visible_items(self):
- """Get list of visible key numbers"""
-
-
-class IKeyNumberContainerTarget(Interface):
- """Key numbers container target interface"""
-
-
KEYNUMBER_PARAGRAPH_TYPE = 'KeyNumbers'
KEYNUMBER_PARAGRAPH_NAME = _("Key numbers")
KEYNUMBER_PARAGRAPH_RENDERERS = 'PyAMS.keynumbers.renderers'
--- a/src/pyams_content/component/paragraph/interfaces/video.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/interfaces/video.py Wed Jun 27 16:42:01 2018 +0200
@@ -20,7 +20,7 @@
# import packages
from pyams_file.schema import VideoField
-from pyams_i18n.schema import I18nHTMLField, I18nTextField
+from pyams_i18n.schema import I18nTextField, I18nTextLineField
from zope.schema import TextLine, Choice
from pyams_content import _
@@ -38,8 +38,12 @@
class IVideoParagraph(IBaseParagraph):
"""Video paragraph"""
- body = I18nHTMLField(title=_("Body"),
- required=False)
+ data = VideoField(title=_("Video data"),
+ description=_("Video file content"),
+ required=True)
+
+ title = I18nTextLineField(title=_("Legend"),
+ required=False)
description = I18nTextField(title=_("Description"),
description=_("File description displayed by front-office template"),
@@ -49,10 +53,6 @@
description=_("Name of document's author"),
required=False)
- data = VideoField(title=_("Video data"),
- description=_("Video file content"),
- required=True)
-
renderer = Choice(title=_("Video template"),
description=_("Presentation template used for this video"),
vocabulary=VIDEO_PARAGRAPH_RENDERERS,
--- a/src/pyams_content/component/paragraph/keynumber.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/keynumber.py Wed Jun 27 16:42:01 2018 +0200
@@ -14,188 +14,27 @@
# import standard library
-from persistent import Persistent
# import interfaces
from pyams_content.component.paragraph.interfaces import IParagraphFactory
-from pyams_content.component.paragraph.interfaces.keynumber import IKeyNumber, IKeyNumberContainer, \
- IKeyNumberContainerTarget, KEYNUMBER_CONTAINER_KEY, IKeyNumberParagraph, KEYNUMBER_PARAGRAPH_TYPE, \
+from pyams_content.component.paragraph.interfaces.keynumber import IKeyNumberParagraph, KEYNUMBER_PARAGRAPH_TYPE, \
KEYNUMBER_PARAGRAPH_RENDERERS, KEYNUMBER_PARAGRAPH_NAME
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.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent
-from zope.location.interfaces import ISublocations
-from zope.traversing.interfaces import ITraversable
# import packages
-from pyams_catalog.utils import index_object
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, get_annotation_adapter
+from pyams_utils.adapter import adapter_config
from pyams_utils.factory import factory_config
-from pyams_utils.registry import get_current_registry, get_utility, utility_config
+from pyams_utils.registry import get_utility, utility_config
from pyams_utils.request import check_request
from pyams_utils.traversing import get_parent
from pyams_utils.vocabulary import vocabulary_config
-from pyramid.events import subscriber
-from zope.container.contained import Contained
-from zope.container.ordered import OrderedContainer
from zope.interface import implementer
-from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
-from zope.location import locate
from zope.schema.fieldproperty import FieldProperty
-#
-# Key number class and adapters
-#
-
-@implementer(IKeyNumber)
-class KeyNumber(Persistent, Contained):
- """Key number persistent class"""
-
- visible = FieldProperty(IKeyNumber['visible'])
- number = FieldProperty(IKeyNumber['number'])
- label = FieldProperty(IKeyNumber['label'])
- text = FieldProperty(IKeyNumber['text'])
-
-
-@adapter_config(context=IKeyNumber, provides=IFormContextPermissionChecker)
-class KeyNumberPermissionChecker(ContextAdapter):
- """Key number permission checker"""
-
- @property
- def edit_permission(self):
- content = get_parent(self.context, IKeyNumberContainerTarget)
- return IFormContextPermissionChecker(content).edit_permission
-
-
-@subscriber(IObjectAddedEvent, context_selector=IKeyNumber)
-def handle_added_keynumber(event):
- """Handle added key number"""
- content = get_parent(event.object, IKeyNumberContainerTarget)
- if content is not None:
- get_current_registry().notify(ObjectModifiedEvent(content))
-
-
-@subscriber(IObjectModifiedEvent, context_selector=IKeyNumber)
-def handle_modified_keynumber(event):
- """Handle modified key number"""
- content = get_parent(event.object, IKeyNumberContainerTarget)
- if content is not None:
- get_current_registry().notify(ObjectModifiedEvent(content))
-
-
-@subscriber(IObjectRemovedEvent, context_selector=IKeyNumber)
-def handle_removed_keynumber(event):
- """Handle removed key number"""
- content = get_parent(event.object, IKeyNumberContainerTarget)
- if content is not None:
- get_current_registry().notify(ObjectModifiedEvent(content))
-
-
-@adapter_config(context=IKeyNumber, provides=IContentChecker)
-class KeyNumberContentChecker(BaseContentChecker):
- """Key number content checker"""
-
- @property
- def label(self):
- request = check_request()
- return II18n(self.context).query_attribute('title', request=request)
-
- def inner_check(self, request):
- output = []
- translate = request.localizer.translate
- manager = get_parent(self.context, II18nManager)
- if manager is not None:
- langs = manager.get_languages()
- else:
- negotiator = get_utility(INegotiator)
- langs = (negotiator.server_language, )
- i18n = II18n(self.context)
- for lang in langs:
- for attr in ('label', 'text'):
- value = i18n.get_attribute(attr, lang, request)
- if not value:
- field_title = translate(IKeyNumber[attr].title)
- if len(langs) == 1:
- output.append(translate(MISSING_VALUE).format(field=field_title))
- else:
- output.append(translate(MISSING_LANG_VALUE).format(field=field_title, lang=lang))
- return output
-
-
-#
-# Key numbers container classes and adapters
-#
-
-@implementer(IKeyNumberContainer)
-class KeyNumberContainer(OrderedContainer):
- """Key numbers container"""
-
- last_id = 1
-
- def append(self, value, notify=True):
- key = str(self.last_id)
- if not notify:
- # pre-locate key number item to avoid multiple notifications
- locate(value, self, key)
- self[key] = value
- self.last_id += 1
- if not notify:
- # make sure that key number item is correctly indexed
- index_object(value)
-
- def get_visible_items(self):
- return filter(lambda x: IKeyNumber(x).visible, self.values())
-
-
-@adapter_config(context=IKeyNumberContainerTarget, provides=IKeyNumberContainer)
-def keynumber_container_factory(target):
- """Key number container factory"""
- return get_annotation_adapter(target, KEYNUMBER_CONTAINER_KEY, KeyNumberContainer, name='++keynumbers++')
-
-
-@adapter_config(name='keynumbers', context=IKeyNumberContainerTarget, provides=ITraversable)
-class KeyNumberContainerNamespace(ContextAdapter):
- """Key numbers container ++keynumbers++ namespace"""
-
- def traverse(self, name, furtherpaath=None):
- return IKeyNumberContainer(self.context)
-
-
-@adapter_config(name='keynumbers', context=IKeyNumberContainerTarget, provides=ISublocations)
-class KeyNumberContainerSublocations(ContextAdapter):
- """Key numbers container sub-locations adapter"""
-
- def sublocations(self):
- return IKeyNumberContainer(self.context).values()
-
-
-@adapter_config(name='keynumbers', context=IKeyNumberContainerTarget, provides=IContentChecker)
-class KeyNumberContainerContentChecker(BaseContentChecker):
- """Key numbers container content checker"""
-
- label = KEYNUMBER_PARAGRAPH_NAME
- sep = '\n'
- weight = 200
-
- def inner_check(self, request):
- output = []
- registry = request.registry
- for keynumber in IKeyNumberContainer(self.context).values():
- if not keynumber.visible:
- continue
- for name, checker in sorted(registry.getAdapters((keynumber, ), IContentChecker),
- key=lambda x: x[1].weight):
- output.append('- {0} ({1}):'.format(keynumber.number,
- II18n(keynumber).query_attribute('label', request=request) or '--'))
- output.append(checker.get_check_output(request))
- return output
-
-
@implementer(IKeyNumberParagraph)
@factory_config(provided=IKeyNumberParagraph)
class KeyNumberParagraph(BaseParagraph):
--- a/src/pyams_content/component/paragraph/pictogram.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/pictogram.py Wed Jun 27 16:42:01 2018 +0200
@@ -78,7 +78,8 @@
@volatile_property
def pictogram(self):
table = query_utility(IPictogramTable)
- return table.get(self.pictogram_name)
+ if table is not None:
+ return table.get(self._pictogram_name)
@adapter_config(context=IPictogramItem, provides=IFormContextPermissionChecker)
--- a/src/pyams_content/component/paragraph/video.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/video.py Wed Jun 27 16:42:01 2018 +0200
@@ -43,10 +43,9 @@
icon_class = 'fa-film'
icon_hint = VIDEO_PARAGRAPH_NAME
- body = FieldProperty(IVideoParagraph['body'])
+ data = FileProperty(IVideoParagraph['data'])
description = FieldProperty(IVideoParagraph['description'])
author = FieldProperty(IVideoParagraph['author'])
- data = FileProperty(IVideoParagraph['data'])
renderer = FieldProperty(IVideoParagraph['renderer'])
--- a/src/pyams_content/component/paragraph/zmi/audio.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/audio.py Wed Jun 27 16:42:01 2018 +0200
@@ -31,10 +31,9 @@
# import packages
from pyams_content.component.paragraph.audio import AudioParagraph
from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, BaseParagraphAJAXEditForm, \
- BaseParagraphAddMenu, BaseParagraphPropertiesEditForm, IParagraphEditFormButtons
+ BaseParagraphAddMenu, BaseParagraphPropertiesEditForm, IParagraphEditFormButtons, get_json_paragraph_refresh_event
from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
from pyams_form.form import ajax_config
-from pyams_form.group import NamedWidgetsGroup
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.event import get_json_form_refresh_event, get_json_widget_refresh_event
from pyams_utils.adapter import adapter_config
@@ -75,20 +74,6 @@
super(AudioParagraphAddForm, self).updateWidgets(prefix)
if 'description' in self.widgets:
self.widgets['description'].widget_css_class = 'textarea'
- if 'body' in self.widgets:
- self.widgets['body'].label = ''
-
- def updateGroups(self):
- self.add_group(NamedWidgetsGroup(self, 'body_group', self.widgets, ('body',),
- bordered=False,
- legend=_("HTML content"),
- css_class='inner switcher padding-right-10 no-y-padding pull-left',
- switch=True,
- display_mode='auto'))
- self.add_group(NamedWidgetsGroup(self, 'data_group', self.widgets,
- ('description', 'author', 'data', 'renderer'),
- bordered=False))
- super(AudioParagraphAddForm, self).updateGroups()
def create(self, data):
return AudioParagraph()
@@ -118,21 +103,6 @@
super(AudioParagraphPropertiesEditForm, self).updateWidgets(prefix)
if 'description' in self.widgets:
self.widgets['description'].widget_css_class = 'textarea'
- if 'body' in self.widgets:
- self.widgets['body'].label = ''
-
- def updateGroups(self):
- self.add_group(NamedWidgetsGroup(self, 'body_group', self.widgets, ('body',),
- bordered=False,
- fieldset_class='margin-top-10 padding-y-5',
- legend=_("HTML content"),
- css_class='inner switcher padding-right-10 no-y-padding pull-left',
- switch=True,
- display_mode='auto'))
- self.add_group(NamedWidgetsGroup(self, 'data_group', self.widgets,
- ('description', 'author', 'data', 'renderer'),
- bordered=False))
- super(AudioParagraphPropertiesEditForm, self).updateGroups()
@adapter_config(context=(IAudioParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
@@ -159,8 +129,12 @@
ITransactionManager(self.context).get().commit()
output.setdefault('events', []).append(
get_json_form_refresh_event(self.context, self.request, AudioParagraphPropertiesInnerEditForm))
- elif 'renderer' in updated:
- output.setdefault('events', []).append(
- get_json_widget_refresh_event(self.context, self.request,
- AudioParagraphPropertiesInnerEditForm, 'renderer'))
+ else:
+ if 'title' in updated:
+ output.setdefault('events', []).append(
+ get_json_paragraph_refresh_event(self.context, self.request))
+ if 'renderer' in updated:
+ output.setdefault('events', []).append(
+ get_json_widget_refresh_event(self.context, self.request,
+ AudioParagraphPropertiesInnerEditForm, 'renderer'))
return output
--- a/src/pyams_content/component/paragraph/zmi/container.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/container.py Wed Jun 27 16:42:01 2018 +0200
@@ -101,7 +101,6 @@
def data_attributes(self):
attributes = super(ParagraphContainerBaseTable, self).data_attributes
attributes.setdefault('table', {}).update({
- 'id': self.id,
'data-ams-plugins': 'pyams_content',
'data-ams-plugin-pyams_content-src': get_resource_path(pyams_content),
'data-ams-location': absolute_url(IParagraphContainer(self.context), self.request),
@@ -132,7 +131,7 @@
message = '{0}<br />{1}'.format(message,
translate(_("Check allowed paragraph types to be able to create "
"new paragraphs.")))
- return message
+ return self.renderEmptyTable(message)
return super(ParagraphContainerBaseTable, self).render()
--- a/src/pyams_content/component/paragraph/zmi/frame.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/frame.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationTarget
+from pyams_content.component.association.interfaces import IAssociationContainerTarget
from pyams_content.component.association.zmi.interfaces import IAssociationsParentForm
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer
from pyams_content.component.paragraph.interfaces.frame import IFrameParagraph, FRAME_PARAGRAPH_TYPE
@@ -150,7 +150,7 @@
output = super(self.__class__, self).get_ajax_output(changes)
if 'body' in changes.get(IFrameParagraph, ()):
# refresh associations count markers
- parent = get_parent(self.context, IAssociationTarget)
+ parent = get_parent(self.context, IAssociationContainerTarget)
output.setdefault('events', []).append(
get_json_paragraph_toolbar_refresh_event(parent, self.request,
ParagraphContainerTable, ParagraphTitleToolbarViewletManager))
--- a/src/pyams_content/component/paragraph/zmi/html.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/html.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.association.interfaces import IAssociationTarget
+from pyams_content.component.association.interfaces import IAssociationContainerTarget
from pyams_content.component.association.zmi.interfaces import IAssociationsParentForm
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphFactorySettings, \
IParagraphContainer
@@ -223,7 +223,7 @@
output = super(self.__class__, self).get_ajax_output(changes)
if 'body' in changes.get(IHTMLParagraph, ()):
# refresh associations count markers
- parent = get_parent(self.context, IAssociationTarget)
+ parent = get_parent(self.context, IAssociationContainerTarget)
output.setdefault('events', []).append(
get_json_paragraph_toolbar_refresh_event(parent, self.request))
# refresh associations table
@@ -252,7 +252,7 @@
output = super(self.__class__, self).get_ajax_output(changes)
if 'body' in changes.get(IHTMLParagraph, ()):
# refresh associations count markers
- parent = get_parent(self.context, IAssociationTarget)
+ parent = get_parent(self.context, IAssociationContainerTarget)
output.setdefault('events', []).append(
get_json_paragraph_toolbar_refresh_event(parent, self.request))
# refresh associations table
--- a/src/pyams_content/component/paragraph/zmi/keynumber.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/keynumber.py Wed Jun 27 16:42:01 2018 +0200
@@ -14,60 +14,39 @@
# import standard library
-import json
# import interfaces
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer
-from pyams_content.component.paragraph.interfaces.keynumber import KEYNUMBER_PARAGRAPH_TYPE, IKeyNumberParagraph, \
- IKeyNumberContainer, IKeyNumberContainerTarget, IKeyNumber
+from pyams_content.component.paragraph.interfaces.keynumber import KEYNUMBER_PARAGRAPH_TYPE, IKeyNumberParagraph
from pyams_content.component.paragraph.zmi import IParagraphContainerView, IParagraphEditFormButtons
from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
from pyams_content.shared.common import IWfSharedContent
-from pyams_form.interfaces.form import IInnerForm, IInnerSubForm
+from pyams_form.interfaces.form import IInnerForm
from pyams_i18n.interfaces import II18n
-from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
+from pyams_skin.interfaces.viewlet import IToolbarAddingMenu
from pyams_skin.layer import IPyAMSLayer
from z3c.form.interfaces import INPUT_MODE
-from z3c.table.interfaces import IValues, IColumn
# import packages
-from pyams_content.component.paragraph.keynumber import KeyNumberParagraph, KeyNumber
+from pyams_content.component.keynumber.zmi import IKeyNumbersParentForm
+from pyams_content.component.paragraph.keynumber import KeyNumberParagraph
from pyams_content.component.paragraph.zmi import BaseParagraphAddMenu, BaseParagraphAJAXAddForm, \
BaseParagraphPropertiesEditForm, BaseParagraphAJAXEditForm
from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
-from pyams_form.form import AJAXAddForm, ajax_config
-from pyams_form.security import ProtectedFormObjectMixin
-from pyams_i18n.column import I18nAttrColumn
+from pyams_form.form import ajax_config
from pyams_pagelet.pagelet import pagelet_config
-from pyams_skin.container import switch_element_visibility
-from pyams_skin.event import get_json_widget_refresh_event, get_json_switched_table_refresh_event, \
- get_json_table_row_refresh_event
-from pyams_skin.table import BaseTable, SorterColumn, I18nColumn, VisibilitySwitcherColumn, TrashColumn
-from pyams_skin.viewlet.toolbar import ToolbarAction
-from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
+from pyams_skin.event import get_json_widget_refresh_event
+from pyams_utils.adapter import adapter_config
from pyams_utils.traversing import get_parent
-from pyams_utils.url import absolute_url
from pyams_viewlet.viewlet import viewlet_config
-from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
-from pyams_zmi.zmi.table import InnerTableView
-from pyramid.decorator import reify
-from pyramid.view import view_config
+from pyams_zmi.form import AdminDialogAddForm
from z3c.form import field, button
-from z3c.table.column import GetAttrColumn
from zope.interface import implementer, Interface
from pyams_content import _
-class IKeyNumbersView(Interface):
- """Key numbers view marker interface"""
-
-
-class IKeyNumbersParentForm(Interface):
- """Key numbers parent form marker interface"""
-
-
@viewlet_config(name='add-keynumber-paragraph.menu', context=IParagraphContainerTarget, view=IParagraphContainerView,
layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=600)
class KeyNumberParagraphAddMenu(BaseParagraphAddMenu):
@@ -103,6 +82,7 @@
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='properties.json', context=IKeyNumberParagraph, layer=IPyAMSLayer,
base=BaseParagraphAJAXEditForm)
+@implementer(IKeyNumbersParentForm)
class KeyNumberParagraphPropertiesEditForm(BaseParagraphPropertiesEditForm):
"""Key number paragraph properties edit form"""
@@ -145,191 +125,3 @@
output.setdefault('events', []).append(
get_json_widget_refresh_event(self.context, self.request, KeyNumberParagraphInnerEditForm, 'renderer'))
return output
-
-
-#
-# Key number items table view
-#
-
-class KeyNumbersTable(ProtectedFormObjectMixin, BaseTable):
- """Key numbers view inner table"""
-
- prefix = 'keynumbers'
-
- hide_header = True
- sortOn = None
-
- @property
- def cssClasses(self):
- classes = ['table', 'table-bordered', 'table-striped', 'table-hover', 'table-tight']
- permission = self.permission
- if (not permission) or self.request.has_permission(permission, self.context):
- classes.append('table-dnd')
- return {'table': ' '.join(classes)}
-
- @property
- def data_attributes(self):
- attributes = super(KeyNumbersTable, self).data_attributes
- attributes['table'] = {
- 'id': self.id,
- 'data-ams-location': absolute_url(IKeyNumberContainer(self.context), self.request),
- 'data-ams-tablednd-drag-handle': 'td.sorter',
- 'data-ams-tablednd-drop-target': 'set-keynumbers-order.json',
- 'data-ams-visibility-switcher': 'switch-keynumber-visibility.json'
- }
- return attributes
-
- @reify
- def values(self):
- return list(super(KeyNumbersTable, self).values)
-
-
-@adapter_config(context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IValues)
-class KeyNumbersTableValuesAdapter(ContextRequestViewAdapter):
- """Key numbers table values adapter"""
-
- @property
- def values(self):
- return IKeyNumberContainer(self.context).values()
-
-
-@adapter_config(name='sorter', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
-class KeyNumbersTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
- """Key numbers table sorter column"""
-
-
-@view_config(name='set-keynumbers-order.json', context=IKeyNumberContainer, request_type=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
-def set_keynumbers_order(request):
- """Update key numbers order"""
- order = list(map(str, json.loads(request.params.get('names'))))
- request.context.updateOrder(order)
- return {'status': 'success'}
-
-
-@adapter_config(name='show-hide', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable),
- provides=IColumn)
-class KeyNumbersTableShowHideColumn(ProtectedFormObjectMixin, VisibilitySwitcherColumn):
- """Key numbers container visibility switcher column"""
-
-
-@view_config(name='switch-keynumber-visibility.json', context=IKeyNumberContainer, request_type=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
-def switch_keynumber_visibility(request):
- """Switch key number visibility"""
- return switch_element_visibility(request, IKeyNumberContainer)
-
-
-@adapter_config(name='name', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
-class KeyNumbersTableNameColumn(I18nColumn, GetAttrColumn):
- """Key numbers table number column"""
-
- _header = _("Number")
- attrName = 'number'
- weight = 10
-
-
-@adapter_config(name='label', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
-class KeyNumbersTableLabelColumn(I18nColumn, I18nAttrColumn):
- """Key numbers table label column"""
-
- _header = _('key-number-label', default="Header")
- attrName = 'label'
- weight = 20
-
- def getValue(self, obj):
- return super(KeyNumbersTableLabelColumn, self).getValue(obj) or '--'
-
-
-@adapter_config(name='text', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
-class KeyNumbersTableTextColumn(I18nColumn, I18nAttrColumn):
- """Key numbers table text column"""
-
- _header = _("Associated text")
- attrName = 'text'
- weight = 30
-
- def getValue(self, obj):
- return super(KeyNumbersTableTextColumn, self).getValue(obj) or '--'
-
-
-@adapter_config(name='trash', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
-class KeyNumbersTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
- """Key numbers table trash column"""
-
-
-@adapter_config(name='keynumbers', context=(IKeyNumberContainerTarget, IPyAMSLayer, IKeyNumbersParentForm),
- provides=IInnerSubForm)
-@implementer(IKeyNumbersView)
-class KeyNumbersView(InnerTableView):
- """Key numbers view"""
-
- title = _("Key numbers")
-
- table_class = KeyNumbersTable
- weight = 110
-
-
-#
-# Key numbers forms
-#
-
-@viewlet_config(name='add-keynumber.action', context=IKeyNumberContainerTarget, layer=IPyAMSLayer, view=IKeyNumbersView,
- manager=IWidgetTitleViewletManager, permission=MANAGE_CONTENT_PERMISSION, weight=1)
-class KeyNumberAddAction(ToolbarAction):
- """Key number add action"""
-
- label = _("Add keynumber")
- label_css_class = 'fa fa-fw fa-plus'
- url = 'add-keynumber.html'
- modal_target = True
-
-
-@pagelet_config(name='add-keynumber.html', context=IKeyNumberContainerTarget, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION)
-@ajax_config(name='add-keynumber.json', context=IParagraphContainerTarget, layer=IPyAMSLayer,
- base=AJAXAddForm)
-class KeyNumberAddForm(AdminDialogAddForm):
- """Key number add form"""
-
- legend = _("Add new keynumber")
- icon_css_class = 'fa fa-fw fa-dashboard'
-
- fields = field.Fields(IKeyNumber).omit('__parent__', '__name__', 'visible')
- edit_permission = MANAGE_CONTENT_PERMISSION
-
- def create(self, data):
- return KeyNumber()
-
- def add(self, object):
- IKeyNumberContainer(self.context).append(object)
-
- def get_ajax_output(self, changes):
- return {
- 'status': 'success',
- 'message': self.request.localizer.translate(_("Key number was correctly added")),
- 'events': [get_json_switched_table_refresh_event(self.context, self.request, KeyNumbersTable), ]
- }
-
-
-@pagelet_config(name='properties.html', context=IKeyNumber, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION)
-@ajax_config(name='properties.json', context=IKeyNumber, layer=IPyAMSLayer)
-class KeyNumberPropertiesEditForm(AdminDialogEditForm):
- """Key number properties edit form"""
-
- prefix = 'keynumber_properties.'
-
- legend = _("Edit keynumber properties")
- icon_css_class = 'fa fa-fw fa-dashboard'
-
- fields = field.Fields(IKeyNumber).omit('__parent__', '__name__', 'visible')
- edit_permission = MANAGE_CONTENT_PERMISSION
-
- def get_ajax_output(self, changes):
- output = super(self.__class__, self).get_ajax_output(changes)
- updated = changes.get(IKeyNumber, ())
- if updated:
- target = get_parent(self.context, IKeyNumberContainerTarget)
- output.setdefault('events', []).append(
- get_json_table_row_refresh_event(target, self.request, KeyNumbersTable, self.context))
- return output
--- a/src/pyams_content/component/paragraph/zmi/milestone.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/milestone.py Wed Jun 27 16:42:01 2018 +0200
@@ -304,7 +304,7 @@
@pagelet_config(name='add-milestone.html', context=IMilestoneContainerTarget, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
-@ajax_config(name='add-milestone.json', context=IParagraphContainerTarget, layer=IPyAMSLayer,
+@ajax_config(name='add-milestone.json', context=IMilestoneContainerTarget, layer=IPyAMSLayer,
base=AJAXAddForm)
class MilestoneAddForm(AdminDialogAddForm):
"""Milestone add form"""
--- a/src/pyams_content/component/paragraph/zmi/pictogram.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/pictogram.py Wed Jun 27 16:42:01 2018 +0200
@@ -23,13 +23,11 @@
from pyams_content.component.paragraph.zmi import IParagraphContainerView, IParagraphEditFormButtons
from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
-from pyams_content.reference.pictograms.interfaces import IPictogramTable
from pyams_content.shared.common import IWfSharedContent
from pyams_form.interfaces.form import IInnerForm, IInnerSubForm
from pyams_i18n.interfaces import II18n
from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces.data import IObjectData
from pyams_zmi.interfaces import IPropertiesEditForm
from z3c.form.interfaces import INPUT_MODE, IDataExtractedEvent
from z3c.table.interfaces import IValues, IColumn
@@ -40,6 +38,8 @@
from pyams_content.component.paragraph.zmi import BaseParagraphAddMenu, BaseParagraphAJAXAddForm, \
BaseParagraphPropertiesEditForm, BaseParagraphAJAXEditForm
from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
+from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
+from pyams_file.zmi.image import render_image
from pyams_form.form import AJAXAddForm, ajax_config
from pyams_form.security import ProtectedFormObjectMixin
from pyams_i18n.column import I18nAttrColumn
@@ -50,7 +50,6 @@
from pyams_skin.table import BaseTable, SorterColumn, I18nColumn, TrashColumn, VisibilitySwitcherColumn
from pyams_skin.viewlet.toolbar import ToolbarAction
from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
-from pyams_utils.registry import query_utility
from pyams_utils.text import get_text_start
from pyams_utils.traversing import get_parent
from pyams_utils.url import absolute_url
@@ -229,7 +228,7 @@
if pictogram is not None:
image = II18n(pictogram).query_attribute('image', request=self.request)
if image:
- return '<img src="{0}" />'.format(absolute_url(image, self.request, '++thumb++48x48'))
+ return render_image(image, 48, 48, self.request)
return '--'
@@ -273,7 +272,7 @@
value = super(PictogramsTableBodyColumn, self).getValue(obj)
if not value:
return BaseParagraph.empty_title
- return get_text_start(value, 40, 10)
+ return get_text_start(value, 80, 10)
@adapter_config(name='trash', context=(IPictogramContainerTarget, IPyAMSLayer, PictogramsTable), provides=IColumn)
@@ -319,26 +318,12 @@
icon_css_class = 'fa fa-fw fa-arrow-h'
fields = field.Fields(IPictogramItem).omit('__parent__', '__name__', 'visible')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = MANAGE_CONTENT_PERMISSION
def updateWidgets(self, prefix=None):
super(PictogramAddForm, self).updateWidgets(prefix)
- if 'pictogram_name' in self.widgets:
- pictograms = query_utility(IPictogramTable)
- if pictograms is not None:
- label_id = '{0}_pictogram_label'.format(self.id)
- widget = self.widgets['pictogram_name']
- widget.after_widget_notice = '<span id="{0}" class="text-info">{1}</span>'.format(
- label_id,
- self.request.localizer.translate(_("Default header: --")))
- widget.object_data = {
- 'ams-change-handler': 'MyAMS.helpers.select2ChangeHelper',
- 'ams-stop-propagation': 'true',
- 'ams-select2-helper-type': 'html',
- 'ams-select2-helper-url': absolute_url(pictograms, self.request, 'get-pictogram-header.html'),
- 'ams-select2-helper-target': '#{0}'.format(label_id)
- }
- alsoProvides(widget, IObjectData)
if 'body' in self.widgets:
self.widgets['body'].widget_css_class = 'textarea height-100'
@@ -375,32 +360,12 @@
icon_css_class = 'fa fa-fw fa-linode'
fields = field.Fields(IPictogramItem).omit('__parent__', '__name__', 'visible')
+ fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
+
edit_permission = MANAGE_CONTENT_PERMISSION
def updateWidgets(self, prefix=None):
super(PictogramPropertiesEditForm, self).updateWidgets(prefix)
- if 'pictogram_name' in self.widgets:
- pictograms = query_utility(IPictogramTable)
- if pictograms is not None:
- pictogram = pictograms.get(self.context.pictogram_name)
- label_id = '{0}_pictogram_label'.format(self.id)
- widget = self.widgets['pictogram_name']
- widget.required = True
- if pictogram is None:
- widget.after_widget_notice = '<span id="{0}" class="text-info">{1}</span>'.format(label_id, '--')
- else:
- widget.after_widget_notice = '<span id="{0}" class="text-info">{1}</span>'.format(
- label_id,
- self.request.localizer.translate(_("Default header: {0}")).format(
- II18n(pictogram).query_attribute('header', request=self.request) or '--'))
- widget.object_data = {
- 'ams-change-handler': 'MyAMS.helpers.select2ChangeHelper',
- 'ams-stop-propagation': 'true',
- 'ams-select2-helper-type': 'html',
- 'ams-select2-helper-url': absolute_url(pictograms, self.request, 'get-pictogram-header.html'),
- 'ams-select2-helper-target': '#{0}'.format(label_id)
- }
- alsoProvides(widget, IObjectData)
if 'body' in self.widgets:
self.widgets['body'].widget_css_class = 'textarea height-100'
--- a/src/pyams_content/component/paragraph/zmi/preview.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/preview.py Wed Jun 27 16:42:01 2018 +0200
@@ -18,7 +18,7 @@
# import interfaces
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer, \
IParagraphRenderer
-from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_content.features.renderer.interfaces import ISharedContentRenderer
from pyams_skin.layer import IPyAMSLayer
# import packages
@@ -27,7 +27,7 @@
@adapter_config(name='paragraphs-render', context=(IParagraphContainerTarget, IPyAMSLayer),
- provides=IContentRenderer)
+ provides=ISharedContentRenderer)
class ParagraphsContainerRenderer(BaseContentRenderer):
"""Paragraphs container renderer"""
@@ -37,7 +37,8 @@
super(ParagraphsContainerRenderer, self).__init__(context, request)
paragraphs = [para for para in IParagraphContainer(self.context).values()
if para.visible]
- self.renderers = [self.request.registry.queryMultiAdapter((paragraph, self.request), IParagraphRenderer)
+ registry = self.request.registry
+ self.renderers = [registry.queryMultiAdapter((paragraph, self.request), IParagraphRenderer)
for paragraph in paragraphs]
def update(self):
--- a/src/pyams_content/component/paragraph/zmi/video.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/paragraph/zmi/video.py Wed Jun 27 16:42:01 2018 +0200
@@ -31,16 +31,14 @@
# import packages
from pyams_content.component.paragraph.video import VideoParagraph
from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, BaseParagraphAJAXEditForm, \
- BaseParagraphAddMenu, BaseParagraphPropertiesEditForm, IParagraphEditFormButtons
+ BaseParagraphAddMenu, BaseParagraphPropertiesEditForm, IParagraphEditFormButtons, get_json_paragraph_refresh_event
from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
from pyams_form.form import ajax_config
-from pyams_form.group import NamedWidgetsGroup
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.event import get_json_form_refresh_event, get_json_widget_refresh_event
from pyams_utils.adapter import adapter_config
from pyams_viewlet.viewlet import viewlet_config
from pyams_zmi.form import AdminDialogAddForm
-from pyramid.view import view_config
from z3c.form import field, button
from zope.interface import implementer
@@ -76,20 +74,6 @@
super(VideoParagraphAddForm, self).updateWidgets(prefix)
if 'description' in self.widgets:
self.widgets['description'].widget_css_class = 'textarea'
- if 'body' in self.widgets:
- self.widgets['body'].label = ''
-
- def updateGroups(self):
- self.add_group(NamedWidgetsGroup(self, 'body_group', self.widgets, ('body',),
- bordered=False,
- legend=_("HTML content"),
- css_class='inner switcher padding-right-10 no-y-padding pull-left',
- switch=True,
- display_mode='auto'))
- self.add_group(NamedWidgetsGroup(self, 'data_group', self.widgets,
- ('description', 'author', 'data', 'renderer'),
- bordered=False))
- super(VideoParagraphAddForm, self).updateGroups()
def create(self, data):
return VideoParagraph()
@@ -120,21 +104,6 @@
super(VideoParagraphPropertiesEditForm, self).updateWidgets(prefix)
if 'description' in self.widgets:
self.widgets['description'].widget_css_class = 'textarea'
- if 'body' in self.widgets:
- self.widgets['body'].label = ''
-
- def updateGroups(self):
- self.add_group(NamedWidgetsGroup(self, 'body_group', self.widgets, ('body',),
- bordered=False,
- fieldset_class='margin-top-10 padding-y-5',
- legend=_("HTML content"),
- css_class='inner switcher padding-right-10 no-y-padding pull-left',
- switch=True,
- display_mode='auto'))
- self.add_group(NamedWidgetsGroup(self, 'data_group', self.widgets,
- ('description', 'author', 'data', 'renderer'),
- bordered=False))
- super(VideoParagraphPropertiesEditForm, self).updateGroups()
@adapter_config(context=(IVideoParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
@@ -161,8 +130,12 @@
ITransactionManager(self.context).get().commit()
output.setdefault('events', []).append(
get_json_form_refresh_event(self.context, self.request, VideoParagraphPropertiesInnerEditForm))
- elif 'renderer' in updated:
- output.setdefault('events', []).append(
- get_json_widget_refresh_event(self.context, self.request,
- VideoParagraphPropertiesInnerEditForm, 'renderer'))
+ else:
+ if 'title' in updated:
+ output.setdefault('events', []).append(
+ get_json_paragraph_refresh_event(self.context, self.request))
+ if 'renderer' in updated:
+ output.setdefault('events', []).append(
+ get_json_widget_refresh_event(self.context, self.request,
+ VideoParagraphPropertiesInnerEditForm, 'renderer'))
return output
--- a/src/pyams_content/component/theme/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/theme/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -88,7 +88,7 @@
def get_subterms(self, term):
for subterm in term.specifics:
- if self.extract_name in subterm.extracts:
+ if (not self.extract_name) or (self.extract_name in subterm.extracts):
yield subterm
for another in self.get_subterms(subterm):
yield another
--- a/src/pyams_content/component/video/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/video/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -21,7 +21,7 @@
from zope.contentprovider.interfaces import IContentProvider
# import packages
-from pyams_i18n.schema import I18nHTMLField, I18nTextField
+from pyams_i18n.schema import I18nTextField, I18nTextLineField
from zope.interface import Interface, Attribute
from zope.schema import Choice, TextLine
@@ -72,8 +72,8 @@
class IExternalVideoParagraph(IExternalVideo, IBaseParagraph):
"""External video paragraph"""
- body = I18nHTMLField(title=_("Body"),
- required=False)
+ title = I18nTextLineField(title=_("Legend"),
+ required=False)
renderer = Choice(title=_("Video template"),
description=_("Presentation template used for this video"),
--- a/src/pyams_content/component/video/paragraph.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/video/paragraph.py Wed Jun 27 16:42:01 2018 +0200
@@ -44,7 +44,6 @@
icon_class = 'fa-youtube-play'
icon_hint = EXTERNAL_VIDEO_PARAGRAPH_NAME
- body = FieldProperty(IExternalVideoParagraph['body'])
renderer = FieldProperty(IExternalVideoParagraph['renderer'])
--- a/src/pyams_content/component/video/zmi/paragraph.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/component/video/zmi/paragraph.py Wed Jun 27 16:42:01 2018 +0200
@@ -76,15 +76,13 @@
dialog_class = 'modal-large'
icon_css_class = 'fa fa-fw fa-youtube-play'
- fields = field.Fields(IExternalVideoParagraph).omit('__parent__', '__name__', 'visible')
+ fields = field.Fields(IExternalVideoParagraph).select('title', 'description', 'author', 'renderer', 'provider_name')
edit_permission = MANAGE_CONTENT_PERMISSION
def updateWidgets(self, prefix=None):
super(ExternalVideoParagraphAddForm, self).updateWidgets(prefix)
if 'description' in self.widgets:
self.widgets['description'].widget_css_class = 'textarea'
- if 'body' in self.widgets:
- self.widgets['body'].label = ''
if 'provider_name' in self.widgets:
widget = self.widgets['provider_name']
widget.object_data = {
@@ -98,19 +96,6 @@
}
alsoProvides(widget, IObjectData)
- def updateGroups(self):
- if 'body' in self.widgets:
- self.add_group(NamedWidgetsGroup(self, 'body_group', self.widgets, ('body',),
- bordered=False,
- legend=_("HTML content"),
- css_class='inner switcher padding-right-10 no-y-padding pull-left',
- switch=True,
- display_mode='auto'))
- self.add_group(NamedWidgetsGroup(self, 'data_group', self.widgets,
- ('description', 'author', 'renderer', 'provider_name'),
- bordered=False))
- super(ExternalVideoParagraphAddForm, self).updateGroups()
-
def create(self, data):
return ExternalVideoParagraph()
@@ -211,7 +196,8 @@
@property
def fields(self):
- fields = field.Fields(IExternalVideoParagraph).omit('__parent__', '__name__', 'visible')
+ fields = field.Fields(IExternalVideoParagraph).select('title', 'description', 'author', 'renderer',
+ 'provider_name')
fields['renderer'].widgetFactory = RendererFieldWidget
provider = self.context.get_provider()
if provider is not None:
@@ -222,23 +208,10 @@
super(ExternalVideoParagraphPropertiesEditForm, self).updateWidgets(prefix)
if 'description' in self.widgets:
self.widgets['description'].widget_css_class = 'textarea'
- if 'body' in self.widgets:
- self.widgets['body'].label = ''
if 'provider_name' in self.widgets:
self.widgets['provider_name'].mode = DISPLAY_MODE
def updateGroups(self):
- if 'body' in self.widgets:
- self.add_group(NamedWidgetsGroup(self, 'body_group', self.widgets, ('body',),
- bordered=False,
- fieldset_class='margin-top-10 padding-y-5',
- legend=_("HTML content"),
- css_class='inner switcher padding-right-10 no-y-padding pull-left',
- switch=True,
- display_mode='auto'))
- self.add_group(NamedWidgetsGroup(self, 'data_group', self.widgets,
- ('description', 'author', 'renderer', 'provider_name'),
- bordered=False))
if 'provider_name' in self.widgets:
provider = self.context.get_provider()
if provider is not None:
@@ -261,7 +234,7 @@
def get_ajax_output(self, changes):
output = super(self.__class__, self).get_ajax_output(changes)
- if 'title' in changes.get(IBaseParagraph, ()):
+ if 'title' in changes.get(IExternalVideoParagraph, ()):
output.setdefault('events', []).append(
get_json_paragraph_refresh_event(self.context, self.request))
return output
--- a/src/pyams_content/features/alert/zmi/container.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/alert/zmi/container.py Wed Jun 27 16:42:01 2018 +0200
@@ -71,7 +71,6 @@
def data_attributes(self):
attributes = super(AlertContainerTable, self).data_attributes
attributes.setdefault('table', {}).update({
- 'id': self.id,
'data-ams-plugins': 'pyams_content',
'data-ams-plugin-pyams_content-src': get_resource_path(pyams_content),
'data-ams-location': absolute_url(IAlertContainer(self.context), self.request),
--- a/src/pyams_content/features/footer/skin/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/footer/skin/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,10 +19,12 @@
from pyams_content.features.footer.interfaces import IFooterTarget, IFooterRenderer, IFooterSettings
from pyams_content.features.renderer.interfaces import HIDDEN_RENDERER_NAME
from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces.url import DISPLAY_CONTEXT
# import packages
from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_utils.adapter import adapter_config
+from pyams_utils.traversing import get_parent
from pyramid.decorator import reify
from pyams_content import _
@@ -35,7 +37,11 @@
def settings(self):
if self.settings_interface is None:
return None
- settings = IFooterSettings(self.context)
+ context = self.request.annotations.get(DISPLAY_CONTEXT)
+ if context is None:
+ context = self.context
+ target = get_parent(context, IFooterTarget)
+ settings = IFooterSettings(target)
while settings.inherit:
settings = IFooterSettings(settings.parent)
return settings.settings
--- a/src/pyams_content/features/footer/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/footer/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,22 +19,26 @@
from pyams_content.features.footer.interfaces import IFooterTarget, IFooterSettings, IFooterRenderer, \
IFooterRendererSettings
from pyams_form.interfaces.form import IWidgetForm, IUncheckedEditFormButtons, IInnerSubForm, \
- IWidgetsSuffixViewletsManager
+ IWidgetsSuffixViewletsManager, IFormHelp
from pyams_portal.interfaces import MANAGE_TEMPLATE_PERMISSION
from pyams_portal.zmi.interfaces import IPortalContextTemplatePropertiesMenu
from pyams_skin.interfaces import IInnerPage
from pyams_skin.layer import IPyAMSLayer
from pyams_utils.interfaces.data import IObjectData
from pyams_utils.interfaces.inherit import IInheritInfo
+from pyams_zmi.layer import IAdminLayer
from z3c.form.interfaces import INPUT_MODE
# import packages
-from pyams_form.form import ajax_config
+from pyams_content.skin import pyams_content
+from pyams_form.form import AJAXEditForm
from pyams_form.group import NamedWidgetsGroup
+from pyams_form.help import FormHelp
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.viewlet.menu import MenuItem
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
+from pyams_utils.fanstatic import get_resource_path
from pyams_utils.url import absolute_url
from pyams_viewlet.viewlet import viewlet_config, Viewlet
from pyams_zmi.form import AdminEditForm, InnerAdminEditForm
@@ -63,8 +67,6 @@
@pagelet_config(name='footer-settings.html', context=IFooterTarget, layer=IPyAMSLayer,
permission=MANAGE_TEMPLATE_PERMISSION)
-@ajax_config(name='footer-settings.json', context=IFooterTarget, layer=IPyAMSLayer,
- permission=MANAGE_TEMPLATE_PERMISSION)
@implementer(IWidgetForm, IInnerPage)
class FooterSettingsEditForm(AdminEditForm):
"""Footer settings edit form"""
@@ -87,6 +89,8 @@
fields = field.Fields(Interface)
return fields
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
@property
def buttons(self):
if self.mode == INPUT_MODE:
@@ -94,6 +98,8 @@
else:
return button.Buttons(Interface)
+ ajax_handler = 'footer-settings.json'
+
def updateGroups(self):
if self.getContent().can_inherit:
group = NamedWidgetsGroup(self, 'footer', self.widgets,
@@ -104,19 +110,49 @@
checkbox_switch=True,
checkbox_mode='disable',
checkbox_field=IFooterSettings['no_inherit'])
+ if self.mode == INPUT_MODE:
+ group.object_data = {
+ 'ams-plugins': 'pyams_content',
+ 'ams-plugin-pyams_content-src': get_resource_path(pyams_content),
+ 'ams-plugin-pyams_content-async': False,
+ 'ams-events-handlers': {
+ 'ams.checker.opened': 'PyAMS_content.footer.submitEditForm',
+ 'ams.checker.closed': 'PyAMS_content.footer.submitEditForm'
+ }
+ }
+ alsoProvides(group, IObjectData)
else:
group = NamedWidgetsGroup(self, 'footer', self.widgets, (), css_class='inner')
alsoProvides(group, IFooterSettingsGroup)
self.add_group(group)
super(FooterSettingsEditForm, self).updateGroups()
+
+@view_config(name='footer-settings.json', context=IFooterTarget, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+class FooterSettingsAJAXEditForm(AJAXEditForm, FooterSettingsEditForm):
+ """Footer settings edit form, JSON renderer"""
+
def get_ajax_output(self, changes):
- output = super(self.__class__, self).get_ajax_output(changes) or {}
+ output = super(FooterSettingsAJAXEditForm, self).get_ajax_output(changes) or {}
if 'no_inherit' in changes.get(IInheritInfo, ()):
output['status'] = 'reload'
return output
+@adapter_config(context=(Interface, IAdminLayer, FooterSettingsEditForm), provides=IFormHelp)
+class FooterSettingsEditFormHelpAdapter(FormHelp):
+ """Footer settings edit form help adapter"""
+
+ def __new__(cls, context, request, view):
+ if (not view.getContent().can_inherit) or (view.mode != INPUT_MODE):
+ return None
+ return FormHelp.__new__(cls)
+
+ message = _("""WARNING: Footer properties are saved automatically when changing inherit mode!!""")
+ message_format = 'rest'
+
+
@adapter_config(name='renderer', context=(IFooterTarget, IPyAMSLayer, IFooterSettingsGroup), provides=IInnerSubForm)
class FooterSettingsRendererEditSubform(InnerAdminEditForm):
"""Footer settings renderer edit form"""
@@ -126,10 +162,17 @@
fields = field.Fields(IFooterSettings).select('renderer')
weight = 1
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
+ _changes = None
+
def __init__(self, context, request, group):
context = IFooterSettings(context)
super(FooterSettingsRendererEditSubform, self).__init__(context, request, group)
+ def getContent(self):
+ return IFooterSettings(self.context)
+
def updateWidgets(self, prefix=None):
super(FooterSettingsRendererEditSubform, self).updateWidgets(prefix)
if 'renderer' in self.widgets:
@@ -146,19 +189,30 @@
alsoProvides(widget, IObjectData)
def get_forms(self, include_self=True):
- if include_self and self.request.method == 'POST':
+ if include_self and (self._changes is None) and (self.request.method == 'POST'):
data, errors = self.extractData()
if not errors:
- self.applyChanges(data)
+ self._changes = self.applyChanges(data)
for form in super(FooterSettingsRendererEditSubform, self).get_forms(include_self):
yield form
+ def get_ajax_output(self, changes):
+ if not changes:
+ changes = self._changes
+ if changes:
+ return {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(self.successMessage)
+ }
+ else:
+ return super(FooterSettingsRendererEditSubform, self).get_ajax_output(changes)
+
@adapter_config(name='footer-renderer-settings-form',
context=(IFooterRendererSettings, IPyAMSLayer, FooterSettingsRendererEditSubform),
provides=IInnerSubForm)
@adapter_config(name='footer-renderer-settings-form',
- context=(IFooterTarget, IPyAMSLayer, FooterSettingsEditForm),
+ context=(IFooterTarget, IPyAMSLayer, FooterSettingsAJAXEditForm),
provides=IInnerSubForm)
class FooterSettingsRendererSettingsEditForm(InnerAdminEditForm):
"""Footer settings renderer settings edit form"""
--- a/src/pyams_content/features/header/skin/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/header/skin/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,10 +19,12 @@
from pyams_content.features.header.interfaces import IHeaderTarget, IHeaderRenderer, IHeaderSettings
from pyams_content.features.renderer.interfaces import HIDDEN_RENDERER_NAME
from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces.url import DISPLAY_CONTEXT
# import packages
from pyams_content.features.renderer.skin import BaseContentRenderer
from pyams_utils.adapter import adapter_config
+from pyams_utils.traversing import get_parent
from pyramid.decorator import reify
from pyams_content import _
@@ -35,7 +37,11 @@
def settings(self):
if self.settings_interface is None:
return None
- settings = IHeaderSettings(self.context)
+ context = self.request.annotations.get(DISPLAY_CONTEXT)
+ if context is None:
+ context = self.context
+ target = get_parent(context, IHeaderTarget)
+ settings = IHeaderSettings(target)
while settings.inherit:
settings = IHeaderSettings(settings.parent)
return settings.settings
--- a/src/pyams_content/features/header/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/header/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,22 +19,26 @@
from pyams_content.features.header.interfaces import IHeaderTarget, IHeaderSettings, IHeaderRenderer, \
IHeaderRendererSettings
from pyams_form.interfaces.form import IWidgetForm, IUncheckedEditFormButtons, IInnerSubForm, \
- IWidgetsSuffixViewletsManager
+ IWidgetsSuffixViewletsManager, IFormHelp
from pyams_portal.interfaces import MANAGE_TEMPLATE_PERMISSION
from pyams_portal.zmi.interfaces import IPortalContextTemplatePropertiesMenu
from pyams_skin.interfaces import IInnerPage
from pyams_skin.layer import IPyAMSLayer
from pyams_utils.interfaces.data import IObjectData
from pyams_utils.interfaces.inherit import IInheritInfo
+from pyams_zmi.layer import IAdminLayer
from z3c.form.interfaces import INPUT_MODE
# import packages
-from pyams_form.form import ajax_config
+from pyams_content.skin import pyams_content
+from pyams_form.form import AJAXEditForm
from pyams_form.group import NamedWidgetsGroup
+from pyams_form.help import FormHelp
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.viewlet.menu import MenuItem, MenuDivider
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
+from pyams_utils.fanstatic import get_resource_path
from pyams_utils.url import absolute_url
from pyams_viewlet.viewlet import viewlet_config, Viewlet
from pyams_zmi.form import AdminEditForm, InnerAdminEditForm
@@ -69,8 +73,6 @@
@pagelet_config(name='header-settings.html', context=IHeaderTarget, layer=IPyAMSLayer,
permission=MANAGE_TEMPLATE_PERMISSION)
-@ajax_config(name='header-settings.json', context=IHeaderTarget, layer=IPyAMSLayer,
- permission=MANAGE_TEMPLATE_PERMISSION)
@implementer(IWidgetForm, IInnerPage)
class HeaderSettingsEditForm(AdminEditForm):
"""Header settings edit form"""
@@ -93,6 +95,8 @@
fields = field.Fields(Interface)
return fields
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
@property
def buttons(self):
if self.mode == INPUT_MODE:
@@ -100,6 +104,8 @@
else:
return button.Buttons(Interface)
+ ajax_handler = 'header-settings.json'
+
def updateGroups(self):
if self.getContent().can_inherit:
group = NamedWidgetsGroup(self, 'header', self.widgets,
@@ -110,19 +116,52 @@
checkbox_switch=True,
checkbox_mode='disable',
checkbox_field=IHeaderSettings['no_inherit'])
+ if self.mode == INPUT_MODE:
+ group.object_data = {
+ 'ams-plugins': 'pyams_content',
+ 'ams-plugin-pyams_content-src': get_resource_path(pyams_content),
+ 'ams-plugin-pyams_content-async': False,
+ 'ams-events-handlers': {
+ 'ams.checker.opened': 'PyAMS_content.header.submitEditForm',
+ 'ams.checker.closed': 'PyAMS_content.header.submitEditForm'
+ }
+ }
+ alsoProvides(group, IObjectData)
else:
group = NamedWidgetsGroup(self, 'header', self.widgets, (), css_class='inner')
alsoProvides(group, IHeaderSettingsGroup)
self.add_group(group)
super(HeaderSettingsEditForm, self).updateGroups()
+
+@view_config(name='header-settings.json', context=IHeaderTarget, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+class HeaderSettingsAJAXEditForm(AJAXEditForm, HeaderSettingsEditForm):
+ """Header settings edit form, JSON renderer"""
+
def get_ajax_output(self, changes):
- output = super(self.__class__, self).get_ajax_output(changes) or {}
+ output = super(HeaderSettingsAJAXEditForm, self).get_ajax_output(changes) or {}
if 'no_inherit' in changes.get(IInheritInfo, ()):
- output['status'] = 'reload'
+ if 'autosubmit' in self.request.params:
+ output['close_form'] = False
+ else:
+ output['status'] = 'reload'
return output
+@adapter_config(context=(Interface, IAdminLayer, HeaderSettingsEditForm), provides=IFormHelp)
+class HeaderSettingsEditFormHelpAdapter(FormHelp):
+ """Header settings edit form help adapter"""
+
+ def __new__(cls, context, request, view):
+ if (not view.getContent().can_inherit) or (view.mode != INPUT_MODE):
+ return None
+ return FormHelp.__new__(cls)
+
+ message = _("""WARNING: Header properties are saved automatically when changing inherit mode!!""")
+ message_format = 'rest'
+
+
@adapter_config(name='renderer', context=(IHeaderTarget, IPyAMSLayer, IHeaderSettingsGroup), provides=IInnerSubForm)
class HeaderSettingsRendererEditSubform(InnerAdminEditForm):
"""Header settings renderer edit form"""
@@ -132,10 +171,17 @@
fields = field.Fields(IHeaderSettings).select('renderer')
weight = 1
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
+ _changes = None
+
def __init__(self, context, request, group):
context = IHeaderSettings(context)
super(HeaderSettingsRendererEditSubform, self).__init__(context, request, group)
+ def getContent(self):
+ return IHeaderSettings(self.context)
+
def updateWidgets(self, prefix=None):
super(HeaderSettingsRendererEditSubform, self).updateWidgets(prefix)
if 'renderer' in self.widgets:
@@ -152,19 +198,30 @@
alsoProvides(widget, IObjectData)
def get_forms(self, include_self=True):
- if include_self and self.request.method == 'POST':
+ if include_self and (self._changes is None) and (self.request.method == 'POST'):
data, errors = self.extractData()
if not errors:
- self.applyChanges(data)
+ self._changes = self.applyChanges(data)
for form in super(HeaderSettingsRendererEditSubform, self).get_forms(include_self):
yield form
+ def get_ajax_output(self, changes):
+ if not changes:
+ changes = self._changes
+ if changes:
+ return {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(self.successMessage)
+ }
+ else:
+ return super(HeaderSettingsRendererEditSubform, self).get_ajax_output(changes)
+
@adapter_config(name='header-renderer-settings-form',
context=(IHeaderRendererSettings, IPyAMSLayer, HeaderSettingsRendererEditSubform),
provides=IInnerSubForm)
@adapter_config(name='header-renderer-settings-form',
- context=(IHeaderTarget, IPyAMSLayer, HeaderSettingsEditForm),
+ context=(IHeaderTarget, IPyAMSLayer, HeaderSettingsAJAXEditForm),
provides=IInnerSubForm)
class HeaderSettingsRendererSettingsEditForm(InnerAdminEditForm):
"""Header settings renderer settings edit form"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.features.menu.interfaces import IMenu, IMenusContainer, IMenuLink
+
+# import packages
+from pyams_content.component.association.container import AssociationContainer
+from zope.interface import implementer
+from zope.schema.fieldproperty import FieldProperty
+
+
+#
+# Menus classes
+#
+
+@implementer(IMenu)
+class Menu(AssociationContainer):
+ """Associations menu"""
+
+ visible = FieldProperty(IMenu['visible'])
+ title = FieldProperty(IMenu['title'])
+
+
+@implementer(IMenusContainer)
+class MenusContainer(AssociationContainer):
+ """Associations menus container"""
+
+ def get_visible_items(self):
+ return filter(lambda x: IMenu(x).visible, self.values())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationContainerTarget
+from zope.annotation.interfaces import IAttributeAnnotatable
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField
+from zope.container.constraints import containers, contains
+from zope.interface import Interface
+from zope.schema import Bool
+
+from pyams_content import _
+
+
+class IMenuLink(Interface):
+ """Menu link marker interface"""
+
+
+class IMenuInternalLink(IMenuLink):
+ """Menu internal link marker interface"""
+
+
+class IMenuExternalLink(IMenuLink):
+ """Menu external link marker interface"""
+
+
+class IMenuLinksContainer(IAssociationContainer):
+ """Menu links container interface"""
+
+ contains(IMenuLink)
+
+
+class IMenuLinksContainerTarget(IAssociationContainerTarget):
+ """Menu links container marker interface"""
+
+
+class IMenu(IMenuLinksContainer):
+ """Menu container interface"""
+
+ containers('.IMenusContainer')
+
+ visible = Bool(title=_("Visible?"),
+ description=_("Is this item visible in front-office?"),
+ required=True,
+ default=True)
+
+ title = I18nTextLineField(title=_("Menu title"),
+ description=_("Displayed menu label"),
+ required=True)
+
+
+class IMenusContainer(IAssociationContainer):
+ """Menus container interface"""
+
+ contains(IMenu)
+
+
+class IMenusContainerTarget(IAssociationContainerTarget):
+ """Menus container target marker interface"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/double.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
+from pyams_content.component.illustration.interfaces import IBasicIllustrationTarget
+from pyams_content.features.menu.interfaces import IMenusContainer, IMenusContainerTarget
+from pyams_content.features.menu.portlet.navigation.interfaces.double import IDoubleNavigationPortletSettings, \
+ IDoubleNavigationMenu, IDoubleNavigationMenusContainer
+from pyams_utils.interfaces import VIEW_PERMISSION
+from zope.lifecycleevent.interfaces import IObjectAddedEvent
+
+# import packages
+from pyams_content.features.menu import MenusContainer
+from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
+from pyams_utils.adapter import get_annotation_adapter, adapter_config
+from pyams_utils.factory import factory_config
+from pyramid.events import subscriber
+from zope.interface import implementer, alsoProvides
+from zope.schema.fieldproperty import FieldProperty
+
+from pyams_content import _
+
+
+DOUBLE_NAVIGATION_PORTLET_NAME = 'pyams_content.portlet.navigation.double'
+DOUBLE_NAVIGATION_LINKS_KEY = '{0}::menus'.format(ASSOCIATION_CONTAINER_KEY)
+
+
+@implementer(IDoubleNavigationPortletSettings, IMenusContainerTarget)
+@factory_config(provided=IDoubleNavigationPortletSettings)
+class DoubleNavigationPortletSettings(PortletSettings):
+ """Double navigation portlet settings"""
+
+ title = FieldProperty(IDoubleNavigationPortletSettings['title'])
+ subtitle = FieldProperty(IDoubleNavigationPortletSettings['subtitle'])
+
+ @property
+ def menus(self):
+ return get_annotation_adapter(self, DOUBLE_NAVIGATION_LINKS_KEY, MenusContainer,
+ markers=IDoubleNavigationMenusContainer, name='++ass++menus')
+
+
+@adapter_config(name='menus', context=IDoubleNavigationPortletSettings, provides=IMenusContainer)
+def simple_navigation_links_adapter(context):
+ """Double navigation menus factory"""
+ return context.menus
+
+
+@portlet_config(permission=VIEW_PERMISSION)
+class DoubleNavigationPortlet(Portlet):
+ """Double navigation portlet"""
+
+ name = DOUBLE_NAVIGATION_PORTLET_NAME
+ label = _("Double navigation")
+
+ toolbar_css_class = 'fa fa-fw fa-2x fa-list-alt'
+
+ settings_factory = IDoubleNavigationPortletSettings
+
+
+@subscriber(IObjectAddedEvent, parent_selector=IDoubleNavigationMenusContainer)
+def handle_added_navigation_menu(event):
+ """Add marker interface to added menus container"""
+ alsoProvides(event.object, IDoubleNavigationMenu, IBasicIllustrationTarget)
+
+
+@subscriber(IObjectAddedEvent, parent_selector=IDoubleNavigationMenu)
+def handle_added_navigation_menu_link(event):
+ """Add marker interface to added menu link"""
+ alsoProvides(event.object, IBasicIllustrationTarget)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,1 @@
+#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/interfaces/double.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_portal.interfaces import IPortletSettings
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField
+from zope.interface import Interface, Attribute
+
+from pyams_content import _
+
+
+class IDoubleNavigationPortletSettings(IPortletSettings):
+ """Double navigation portlet settings interface"""
+
+ title = I18nTextLineField(title=_("Title"),
+ description=_("Portlet main title"),
+ required=False)
+
+ subtitle = I18nTextLineField(title=_("Subtitle"),
+ description=_("Portlet subtitle"),
+ required=False)
+
+ menus = Attribute("Navigation menus")
+
+
+class IDoubleNavigationMenusContainer(Interface):
+ """Double navigation menus container marker interface"""
+
+
+class IDoubleNavigationMenu(Interface):
+ """Double navigation menu marker interface"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_portal.interfaces import IPortletSettings
+
+# import packages
+from pyams_i18n.schema import I18nTextLineField
+from zope.interface import Interface, Attribute
+
+from pyams_content import _
+
+
+class ISimpleNavigationPortletSettings(IPortletSettings):
+ """Simple navigation portlet settings interface"""
+
+ title = I18nTextLineField(title=_("Title"),
+ description=_("Portlet main title"),
+ required=False)
+
+ subtitle = I18nTextLineField(title=_("Subtitle"),
+ description=_("Portlet subtitle"),
+ required=False)
+
+ links = Attribute("Navigation links")
+
+
+class ISimpleNavigationMenu(Interface):
+ """Simple navigation menu marker interface"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/simple.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,77 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
+from pyams_content.component.illustration import IBasicIllustrationTarget
+from pyams_content.features.menu.interfaces import IMenuLinksContainer, IMenuLinksContainerTarget
+from pyams_content.features.menu.portlet.navigation.interfaces.simple import ISimpleNavigationPortletSettings, \
+ ISimpleNavigationMenu
+from pyams_utils.interfaces import VIEW_PERMISSION
+from zope.lifecycleevent.interfaces import IObjectAddedEvent
+
+# import packages
+from pyams_content.features.menu import Menu
+from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
+from pyams_utils.adapter import get_annotation_adapter, adapter_config
+from pyams_utils.factory import factory_config
+from pyramid.events import subscriber
+from zope.interface import implementer, alsoProvides
+from zope.schema.fieldproperty import FieldProperty
+
+from pyams_content import _
+
+
+SIMPLE_NAVIGATION_PORTLET_NAME = 'pyams_content.portlet.navigation.simple'
+SIMPLE_NAVIGATION_LINKS_KEY = '{0}::links'.format(ASSOCIATION_CONTAINER_KEY)
+
+
+@implementer(ISimpleNavigationPortletSettings, IMenuLinksContainerTarget)
+@factory_config(provided=ISimpleNavigationPortletSettings)
+class SimpleNavigationPortletSettings(PortletSettings):
+ """Simple navigation portlet settings"""
+
+ title = FieldProperty(ISimpleNavigationPortletSettings['title'])
+ subtitle = FieldProperty(ISimpleNavigationPortletSettings['subtitle'])
+
+ @property
+ def links(self):
+ return get_annotation_adapter(self, SIMPLE_NAVIGATION_LINKS_KEY, Menu,
+ markers=ISimpleNavigationMenu, name='++ass++links')
+
+
+@adapter_config(name='links', context=ISimpleNavigationPortletSettings, provides=IMenuLinksContainer)
+def simple_navigation_links_adapter(context):
+ """Simple navigation links factory"""
+ return context.links
+
+
+@portlet_config(permission=VIEW_PERMISSION)
+class SimpleNavigationPortlet(Portlet):
+ """Simple navigation portlet"""
+
+ name = SIMPLE_NAVIGATION_PORTLET_NAME
+ label = _("Simple navigation")
+
+ toolbar_css_class = 'fa fa-fw fa-2x fa-bars'
+
+ settings_factory = ISimpleNavigationPortletSettings
+
+
+@subscriber(IObjectAddedEvent, parent_selector=ISimpleNavigationMenu)
+def handle_added_navigation_link(event):
+ alsoProvides(event.object, IBasicIllustrationTarget)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/zmi/double.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,104 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.illustration.interfaces import IIllustration, ILinkIllustration
+from pyams_content.component.links.interfaces import IInternalLink
+from pyams_content.features.menu.portlet.navigation.interfaces.double import IDoubleNavigationPortletSettings, \
+ IDoubleNavigationMenusContainer
+from pyams_form.interfaces.form import IInnerSubForm
+from pyams_pagelet.interfaces import IPagelet
+from pyams_portal.interfaces import IPortletPreviewer
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_workflow.interfaces import IWorkflowPublicationInfo
+
+# import packages
+from pyams_content.component.association.interfaces import IAssociationInfo
+from pyams_content.features.menu.zmi import MenusTable, IMenusView, MenusView
+from pyams_form.form import AJAXEditForm
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_portal.portlet import PortletPreviewer
+from pyams_portal.zmi.portlet import PortletSettingsEditor, PortletSettingsPropertiesEditor
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+from zope.interface import alsoProvides, Interface
+
+from pyams_content import _
+
+
+@pagelet_config(name='properties.html', context=IDoubleNavigationPortletSettings, layer=IPyAMSLayer,
+ permission=VIEW_SYSTEM_PERMISSION)
+class DoubleNavigationPortletSettingsEditor(PortletSettingsEditor):
+ """Double navigation portlet settings editor"""
+
+ settings = IDoubleNavigationPortletSettings
+
+
+@adapter_config(name='properties.json', context=(IDoubleNavigationPortletSettings, IPyAMSLayer), provides=IPagelet)
+class DoubleNavigationPortletSettingsAJAXEditor(AJAXEditForm, DoubleNavigationPortletSettingsEditor):
+ """Double navigation portlet settings editor, JSON renderer"""
+
+
+class DoubleNavigationPortletMenusTable(MenusTable):
+ """Double navigation portlet menus table"""
+
+ associations_name = 'menus'
+
+
+@adapter_config(name='double-navigation-menus',
+ context=(IDoubleNavigationPortletSettings, IPyAMSLayer, PortletSettingsPropertiesEditor),
+ provides=IInnerSubForm)
+@adapter_config(name='++ass++menus', context=(IDoubleNavigationMenusContainer, IPyAMSLayer), provides=IMenusView)
+class DoubleNavigationPortletLinksView(MenusView):
+ """Double navigation portlet menus view"""
+
+ title = _("Navigation menus")
+
+ table_class = DoubleNavigationPortletMenusTable
+ weight = 10
+
+
+@adapter_config(context=(Interface, IPyAMSLayer, Interface, IDoubleNavigationPortletSettings),
+ provides=IPortletPreviewer)
+@template_config(template='templates/double-preview.pt', layer=IPyAMSLayer)
+class DoubleNavigationPortletPreviewer(PortletPreviewer):
+ """Double navigation portlet previewer"""
+
+ @classmethod
+ def get_link_info(cls, link):
+ return IAssociationInfo(link)
+
+ @classmethod
+ def get_link_status(cls, link):
+ if not IInternalLink.providedBy(link):
+ return True
+ target = link.get_target()
+ return (target is not None) and IWorkflowPublicationInfo(target).is_published()
+
+ @classmethod
+ def get_link_illustration(cls, link):
+ illustration = IIllustration(link, None)
+ if (illustration is None) or not illustration.has_data():
+ if IInternalLink.providedBy(link):
+ target = link.get_target()
+ if target is None:
+ return
+ illustration = ILinkIllustration(target, None)
+ if (illustration is None) or not illustration.has_data():
+ illustration = IIllustration(target, None)
+ return illustration
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/zmi/simple.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,104 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.illustration.interfaces import IIllustration, ILinkIllustration
+from pyams_content.component.links.interfaces import IInternalLink
+from pyams_content.features.menu.portlet.navigation.interfaces.simple import ISimpleNavigationPortletSettings, \
+ ISimpleNavigationMenu
+from pyams_form.interfaces.form import IInnerSubForm
+from pyams_pagelet.interfaces import IPagelet
+from pyams_portal.interfaces import IPortletPreviewer
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_workflow.interfaces import IWorkflowPublicationInfo
+
+# import packages
+from pyams_content.component.association.interfaces import IAssociationInfo
+from pyams_content.features.menu.zmi import LinksTable, IMenuLinksView, MenuLinksView
+from pyams_form.form import AJAXEditForm
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_portal.portlet import PortletPreviewer
+from pyams_portal.zmi.portlet import PortletSettingsEditor, PortletSettingsPropertiesEditor
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+from zope.interface import alsoProvides, Interface
+
+from pyams_content import _
+
+
+@pagelet_config(name='properties.html', context=ISimpleNavigationPortletSettings, layer=IPyAMSLayer,
+ permission=VIEW_SYSTEM_PERMISSION)
+class SimpleNavigationPortletSettingsEditor(PortletSettingsEditor):
+ """Simple navigation portlet settings editor"""
+
+ settings = ISimpleNavigationPortletSettings
+
+
+@adapter_config(name='properties.json', context=(ISimpleNavigationPortletSettings, IPyAMSLayer), provides=IPagelet)
+class SimpleNavigationPortletSettingsAJAXEditor(AJAXEditForm, SimpleNavigationPortletSettingsEditor):
+ """Simple navigation portlet settings editor, JSON renderer"""
+
+
+class SimpleNavigationPortletLinksTable(LinksTable):
+ """Simple navigation portlet links table"""
+
+ associations_name = 'links'
+
+
+@adapter_config(name='simple-navigation-links',
+ context=(ISimpleNavigationPortletSettings, IPyAMSLayer, PortletSettingsPropertiesEditor),
+ provides=IInnerSubForm)
+@adapter_config(name='++ass++links', context=(ISimpleNavigationMenu, IPyAMSLayer), provides=IMenuLinksView)
+class SimpleNavigationPortletLinksView(MenuLinksView):
+ """Simple navigation portlet links view"""
+
+ title = _("Navigation links")
+
+ table_class = SimpleNavigationPortletLinksTable
+ weight = 10
+
+
+@adapter_config(context=(Interface, IPyAMSLayer, Interface, ISimpleNavigationPortletSettings),
+ provides=IPortletPreviewer)
+@template_config(template='templates/simple-preview.pt', layer=IPyAMSLayer)
+class SimpleNavigationPortletPreviewer(PortletPreviewer):
+ """Simple navigation portlet previewer"""
+
+ @classmethod
+ def get_link_info(cls, link):
+ return IAssociationInfo(link)
+
+ @classmethod
+ def get_link_status(cls, link):
+ if not IInternalLink.providedBy(link):
+ return True
+ target = link.get_target()
+ return (target is not None) and IWorkflowPublicationInfo(target).is_published()
+
+ @classmethod
+ def get_link_illustration(cls, link):
+ illustration = IIllustration(link, None)
+ if (illustration is None) or not illustration.has_data():
+ if IInternalLink.providedBy(link):
+ target = link.get_target()
+ if target is None:
+ return
+ illustration = ILinkIllustration(target, None)
+ if (illustration is None) or not illustration.has_data():
+ illustration = IIllustration(target, None)
+ return illustration
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/zmi/templates/double-preview.pt Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,26 @@
+<div tal:define="settings view.settings">
+ <strong tal:content="i18n:settings.title">Title</strong>
+ <tal:var define="subtitle i18n:settings.subtitle" condition="subtitle" content="subtitle" />
+ <ul>
+ <li tal:repeat="menu settings.menus.get_visible_items()">
+ <span tal:content="i18n:menu.title">Title</span>
+ <ul>
+ <li tal:repeat="link menu.get_visible_items()"
+ tal:attributes="illustration view.get_link_illustration(link);">
+ <i class="fa fa-fw fa-eye-slash text-danger hint opaque align-base"
+ tal:condition="not:view.get_link_status(link)"
+ title="Link target is not published!" i18n:attributes="title"></i>
+ <i class="fa fa-fw fa-file-image-o text-danger hint opaque align-base"
+ tal:define="illustration view.get_link_illustration(link)"
+ tal:condition="not:illustration and illustration.has_data()"
+ title="Link has no illustration"></i>
+ <tal:var define="info view.get_link_info(link)">
+ <span tal:content="info.user_title">User title</span>
+ –
+ <span tal:content="info.inner_title">Inner title</span>
+ </tal:var>
+ </li>
+ </ul>
+ </li>
+ </ul>
+</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,21 @@
+<div tal:define="settings view.settings" i18n:domain="pyams_content">
+ <strong tal:content="i18n:settings.title">Title</strong>
+ <tal:var define="subtitle i18n:settings.subtitle" condition="subtitle" content="subtitle" />
+ <ul>
+ <li tal:repeat="link settings.links.get_visible_items()"
+ tal:attributes="illustration view.get_link_illustration(link);">
+ <i class="fa fa-fw fa-eye-slash text-danger hint opaque align-base"
+ tal:condition="not:view.get_link_status(link)"
+ title="Link target is not published!" i18n:attributes="title"></i>
+ <i class="fa fa-fw fa-file-image-o text-danger hint opaque align-base"
+ tal:define="illustration view.get_link_illustration(link)"
+ tal:condition="not:illustration and illustration.has_data()"
+ title="Link has no illustration" i18n:attributes="title"></i>
+ <tal:var define="info view.get_link_info(link)">
+ <span tal:content="info.user_title">User title</span>
+ –
+ <span tal:content="info.inner_title">Inner title</span>
+ </tal:var>
+ </li>
+ </ul>
+</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,489 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import json
+
+# import interfaces
+from pyams_content.component.links.zmi import InternalLinkAddMenu, InternalLinkAddForm, InternalLinkPropertiesEditForm, \
+ ExternalLinkAddMenu, ExternalLinkAddForm, ExternalLinkPropertiesEditForm
+from pyams_content.features.menu import IMenusContainer, IMenu, Menu, IMenuLink
+from pyams_content.features.menu.interfaces import IMenusContainerTarget, IMenuLinksContainer, IMenuInternalLink, \
+ IMenuExternalLink, IMenuLinksContainerTarget
+from pyams_form.interfaces.form import IFormContextPermissionChecker
+from pyams_portal.interfaces import MANAGE_TEMPLATE_PERMISSION
+from pyams_skin.interfaces.viewlet import IWidgetTitleViewletManager, IToolbarAddingMenu
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_viewlet.interfaces import IViewletManager
+from pyams_zmi.interfaces import IPropertiesEditForm
+from z3c.table.interfaces import IValues, IColumn
+
+# import packages
+from pyams_content.component.association.zmi import AssociationsTable, AssociationsTablePublicNameColumn
+from pyams_form.form import ajax_config, AJAXAddForm, AJAXEditForm
+from pyams_i18n.column import I18nAttrColumn
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.container import switch_element_visibility, delete_container_element
+from pyams_skin.event import get_json_switched_table_refresh_event, get_json_table_row_refresh_event
+from pyams_skin.table import BaseTable, SorterColumn, VisibilitySwitcherColumn, I18nColumn, TrashColumn, NameColumn, \
+ get_table_id
+from pyams_skin.viewlet.toolbar import ToolbarAction
+from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter, ContextAdapter
+from pyams_utils.traversing import get_parent
+from pyams_utils.url import absolute_url
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
+from pyams_zmi.zmi.table import InnerTableView
+from pyramid.decorator import reify
+from pyramid.exceptions import NotFound
+from pyramid.renderers import render
+from pyramid.view import view_config
+from z3c.form import field
+from zope.interface import implementer, alsoProvides, Interface
+
+from pyams_content import _
+
+
+#
+# Custom marker interfaces
+#
+
+class IMenuLinksView(Interface):
+ """Menu links view marker interface"""
+
+
+class IMenusView(Interface):
+ """Menus view marker interface"""
+
+
+#
+# Menus add and edit forms
+#
+
+@viewlet_config(name='add-menu.action', context=IMenusContainerTarget, layer=IPyAMSLayer,
+ view=IMenusView, manager=IWidgetTitleViewletManager, weight=10)
+class MenuAddAction(ToolbarAction):
+ """Menu add action"""
+
+ label = _("Add menu...")
+ url = 'add-menu.html'
+ modal_target = True
+
+
+@pagelet_config(name='add-menu.html', context=IMenusContainer, layer=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION)
+@ajax_config(name='add-menu.json', context=IMenusContainer, layer=IPyAMSLayer, base=AJAXAddForm)
+class MenuAddForm(AdminDialogAddForm):
+ """Menu add form"""
+
+ legend = _("Add new menu")
+ icon_css_class = 'fa fa-fw fa-bars'
+
+ fields = field.Fields(IMenu).select('title')
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
+ def create(self, data):
+ return Menu()
+
+ def add(self, object):
+ self.context.append(object)
+
+ def get_ajax_output(self, changes):
+ settings = get_parent(self.context, IMenusContainerTarget)
+ view = self.request.registry.getMultiAdapter((self.context, self.request), IMenusView,
+ name=self.context.__name__)
+ return {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(_("Menu was correctly added.")),
+ 'events': [
+ get_json_switched_table_refresh_event(settings, self.request, view.table_class)
+ ]
+ }
+
+
+@pagelet_config(name='properties.html', context=IMenu, layer=IPyAMSLayer, permission=MANAGE_TEMPLATE_PERMISSION)
+@ajax_config(name='properties.json', context=IMenu, layer=IPyAMSLayer)
+@implementer(IPropertiesEditForm)
+class MenuPropertiesEditForm(AdminDialogEditForm):
+ """Menu properties edit form"""
+
+ legend = _("Edit menu properties")
+ icon_css_class = 'fa fa-fw fa-bars'
+
+ dialog_class = 'modal-large'
+
+ fields = field.Fields(IMenu).select('title')
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
+ def get_ajax_output(self, changes):
+ output = super(self.__class__, self).get_ajax_output(changes)
+ if changes:
+ settings = get_parent(self.context, IMenusContainerTarget)
+ container = settings.menus
+ view = self.request.registry.getMultiAdapter((container, self.request), IMenusView,
+ name=container.__name__)
+ output.setdefault('events', []).append(
+ get_json_table_row_refresh_event(settings, self.request, view.table_class, self.context))
+ return output
+
+
+#
+# Menus table views
+#
+
+class MenusTable(BaseTable):
+ """Menus table"""
+
+ prefix = 'menus'
+ associations_name = 'menus'
+
+ permission = MANAGE_TEMPLATE_PERMISSION
+ hide_header = True
+ hide_body_toolbar = True
+ sortOn = None
+
+ @property
+ def cssClasses(self):
+ classes = ['table', 'table-bordered', 'table-striped', 'table-hover', 'table-tight']
+ permission = self.permission
+ if (not permission) or self.request.has_permission(permission, self.context):
+ classes.append('table-dnd')
+ return {'table': ' '.join(classes)}
+
+ @property
+ def data_attributes(self):
+ menus = getattr(self.context, self.associations_name)
+ attributes = super(MenusTable, self).data_attributes
+ attributes.setdefault('table', {}).update({
+ 'data-ams-location': absolute_url(menus, self.request),
+ 'data-ams-tablednd-drag-handle': 'td.sorter',
+ 'data-ams-tablednd-drop-target': 'set-menus-order.json',
+ 'data-ams-visibility-switcher': 'switch-menu-visibility.json'
+ })
+ return attributes
+
+
+@adapter_config(context=(IMenusContainerTarget, IPyAMSLayer, MenusTable), provides=IValues)
+class MenusTableValuesAdapter(ContextRequestViewAdapter):
+ """Menus table values adapter"""
+
+ @property
+ def values(self):
+ return getattr(self.context, self.view.associations_name).values()
+
+
+@adapter_config(name='sorter', context=(IMenusContainerTarget, IPyAMSLayer, MenusTable),
+ provides=IColumn)
+class MenusTableSorterColumn(SorterColumn):
+ """Menus table sorter column"""
+
+ permission = MANAGE_TEMPLATE_PERMISSION
+
+
+@adapter_config(name='show-hide', context=(IMenusContainerTarget, IPyAMSLayer, MenusTable),
+ provides=IColumn)
+class MenusTableShowHideColumn(VisibilitySwitcherColumn):
+ """Menus table visibility switcher column"""
+
+ permission = MANAGE_TEMPLATE_PERMISSION
+
+
+@adapter_config(name='name', context=(IMenusContainerTarget, IPyAMSLayer, MenusTable), provides=IColumn)
+class MenusTableNameColumn(I18nColumn, I18nAttrColumn):
+ """Menus table name column"""
+
+ _header = _("Label")
+ attrName = 'title'
+ weight = 10
+
+ def renderCell(self, item):
+ return render('templates/menu-name-cell.pt', {'context': item}, request=self.request)
+
+
+@adapter_config(name='trash', context=(IMenusContainerTarget, IPyAMSLayer, MenusTable), provides=IColumn)
+class MenusTableTrashColumn(TrashColumn):
+ """Menus table trash column"""
+
+ permission = MANAGE_TEMPLATE_PERMISSION
+
+
+@implementer(IMenusView)
+class MenusView(InnerTableView):
+ """Menus view"""
+
+ table_class = MenusTable
+
+ @property
+ def actions_context(self): # define context for internal actions
+ return self.request.registry.getAdapter(self.context, IMenusContainer,
+ name=self.table.associations_name)
+
+
+#
+# Menus container views
+#
+
+@view_config(name='set-menus-order.json', context=IMenusContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+def set_menus_order(request):
+ """Update menus order"""
+ order = list(map(str, json.loads(request.params.get('names'))))
+ request.context.updateOrder(order)
+ return {'status': 'success'}
+
+
+@view_config(name='switch-menu-visibility.json', context=IMenusContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+def set_menu_visibility(request):
+ """Set menu visibility"""
+ return switch_element_visibility(request, IMenusContainer)
+
+
+@view_config(name='delete-element.json', context=IMenusContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+def delete_menu(request):
+ """Delete menu"""
+ return delete_container_element(request, ignore_permission=True)
+
+
+@view_config(name='get-menu-items.json', context=IMenusContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+def get_menu_items_table(request):
+ """Get menu items table"""
+ menu = request.context.get(str(request.params.get('object_name')))
+ if menu is None:
+ raise NotFound()
+ table = MenuLinksTable(menu, request)
+ table.update()
+ return table.render()
+
+
+#
+# Menu links table
+#
+
+class LinksTable(AssociationsTable):
+ """Links base table class"""
+
+ associations_name = None
+
+ @reify
+ def id(self):
+ if IMenu.providedBy(self.context):
+ context = self.context
+ else:
+ context = self.request.registry.getAdapter(self.context, IMenuLinksContainer,
+ name=self.associations_name)
+ return get_table_id(self, context)
+
+ @property
+ def prefix(self):
+ return '{0}_links'.format(self.associations_name)
+
+ permission = MANAGE_TEMPLATE_PERMISSION
+ hide_header = True
+ hide_body_toolbar = True
+
+
+class MenuLinksTable(LinksTable):
+ """Menu links associations table"""
+
+ prefix = 'menu_links'
+ associations_name = ''
+
+ @property
+ def data_attributes(self):
+ attributes = super(LinksTable, self).data_attributes
+ attributes.setdefault('table', {}).update({
+ 'data-ams-location': absolute_url(self.context, self.request),
+ })
+ attributes.setdefault('tr', {}).update({'data-ams-stop-propagation': 'true'})
+ return attributes
+
+
+@adapter_config(name='name', context=(IMenu, IPyAMSLayer, MenuLinksTable), provides=IColumn)
+class MenuLinksTableNameColumn(AssociationsTablePublicNameColumn):
+ """Menu links table name column"""
+
+ def renderHeadCell(self):
+ result = super(MenuLinksTableNameColumn, self).renderHeadCell()
+ registry = self.request.registry
+ viewlet = registry.queryMultiAdapter((self.context, self.request, self.table), IViewletManager,
+ name='pyams.widget_title')
+ if viewlet is not None:
+ viewlet.update()
+ result += viewlet.render()
+ return result
+
+
+@adapter_config(context=(IMenu, IPyAMSLayer), provides=IMenuLinksView)
+@implementer(IMenuLinksView)
+class MenuLinksView(InnerTableView):
+ """Links base view"""
+
+ table_class = MenuLinksTable
+
+ @property
+ def actions_context(self): # define context for internal actions
+ return self.request.registry.getAdapter(self.context, IMenuLinksContainer,
+ name=self.table.associations_name)
+
+
+#
+# Menu links container views
+#
+
+@view_config(name='set-associations-order.json', context=IMenuLinksContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+def set_associations_order(request):
+ """Update associations order"""
+ order = list(map(str, json.loads(request.params.get('names'))))
+ request.context.updateOrder(order)
+ return {'status': 'success'}
+
+
+@view_config(name='switch-association-visibility.json', context=IMenuLinksContainer, request_type=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION, renderer='json', xhr=True)
+def set_association_visibility(request):
+ """Set association visibility"""
+ return switch_element_visibility(request, IMenuLinksContainer)
+
+
+#
+# Link add and edit forms
+#
+
+@adapter_config(context=IMenuLink, provides=IFormContextPermissionChecker)
+class MenuLinkPermissionChecker(ContextAdapter):
+ """Menu link permission checker"""
+
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
+
+class LinkAJAXAddForm(AJAXAddForm):
+ """Menu link add form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ registry = self.request.registry
+ container = get_parent(self.context, IMenuLinksContainer)
+ view = registry.queryMultiAdapter((container, self.request), IMenuLinksView,
+ name=container.__name__)
+ if view is None:
+ view = registry.getMultiAdapter((container, self.request), IMenuLinksView)
+ return {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(_("Link was correctly added.")),
+ 'events': [
+ get_json_switched_table_refresh_event(self.context, self.request, view.table_class)
+ ]
+ }
+
+
+class LinkPropertiesAJAXEditForm(AJAXEditForm):
+ """Menu link properties edit form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ output = AJAXEditForm.get_ajax_output(self, changes)
+ if changes:
+ registry = self.request.registry
+ container = get_parent(self.context, IMenuLinksContainer)
+ view = registry.queryMultiAdapter((container, self.request), IMenuLinksView,
+ name=container.__name__)
+ if view is None:
+ view = registry.getMultiAdapter((container, self.request), IMenuLinksView)
+ output.setdefault('events', []).append(
+ get_json_table_row_refresh_event(container, self.request, view.table_class, self.context))
+ return output
+
+
+#
+# Internal links
+#
+
+@viewlet_config(name='add-internal-link.menu', context=IMenuLinksContainerTarget, layer=IPyAMSLayer,
+ view=IMenuLinksView, manager=IToolbarAddingMenu, weight=50)
+@viewlet_config(name='add-internal-link.menu', context=IMenu, layer=IPyAMSLayer,
+ view=MenuLinksTable, manager=IToolbarAddingMenu, permission=MANAGE_TEMPLATE_PERMISSION, weight=50)
+class MenuInternalLinkAddMenu(InternalLinkAddMenu):
+ """Header internal link add menu"""
+
+
+@pagelet_config(name='add-internal-link.html', context=IMenuLinksContainer, layer=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION)
+@ajax_config(name='add-internal-link.json', context=IMenuLinksContainer, layer=IPyAMSLayer,
+ base=LinkAJAXAddForm)
+class MenuInternalLinkAddForm(InternalLinkAddForm):
+ """Menu internal link add form"""
+
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
+ def create(self, data):
+ result = super(MenuInternalLinkAddForm, self).create(data)
+ alsoProvides(result, IMenuInternalLink)
+ return result
+
+ def add(self, object):
+ self.context.append(object)
+
+
+@pagelet_config(name='properties.html', context=IMenuInternalLink, layer=IPyAMSLayer,
+ permission=VIEW_SYSTEM_PERMISSION)
+@ajax_config(name='properties.json', context=IMenuInternalLink, layer=IPyAMSLayer,
+ base=LinkPropertiesAJAXEditForm)
+class MenuInternalLinkPropertiesEditForm(InternalLinkPropertiesEditForm):
+ """Menu internal link properties edit form"""
+
+ edit_permission = None # managed by IFormContextPermissionChecker adapter
+
+
+#
+# External links
+#
+
+@viewlet_config(name='add-external-link.menu', context=IMenuLinksContainerTarget, view=IMenuLinksView,
+ layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=51)
+@viewlet_config(name='add-external-link.menu', context=IMenu, layer=IPyAMSLayer,
+ view=MenuLinksTable, manager=IToolbarAddingMenu, permission=MANAGE_TEMPLATE_PERMISSION, weight=51)
+class MenuExternalLinkAddMenu(ExternalLinkAddMenu):
+ """Menu external link add menu"""
+
+
+@pagelet_config(name='add-external-link.html', context=IMenuLinksContainer, layer=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION)
+@ajax_config(name='add-external-link.json', context=IMenuLinksContainer, layer=IPyAMSLayer,
+ base=LinkAJAXAddForm)
+class MenuExternalLinkAddForm(ExternalLinkAddForm):
+ """Menu external link add form"""
+
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+
+ def create(self, data):
+ result = super(MenuExternalLinkAddForm, self).create(data)
+ alsoProvides(result, IMenuExternalLink)
+ return result
+
+ def add(self, object):
+ self.context.append(object)
+
+
+@pagelet_config(name='properties.html', context=IMenuExternalLink, layer=IPyAMSLayer,
+ permission=VIEW_SYSTEM_PERMISSION)
+@ajax_config(name='properties.json', context=IMenuExternalLink, layer=IPyAMSLayer,
+ base=LinkPropertiesAJAXEditForm)
+class MenuExternalLinkPropertiesEditForm(ExternalLinkPropertiesEditForm):
+ """Menu external link properties edit form"""
+
+ edit_permission = None # managed by IFormContextPermissionChecker adapter
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/features/menu/zmi/templates/menu-name-cell.pt Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,13 @@
+<i18n:v domain="pyams_content">
+ <span data-ams-stop-propagation="true"
+ data-ams-click-handler="MyAMS.skin.switchCellContent"
+ data-ams-switch-handler="get-menu-items.json"
+ data-ams-switch-target=".menus">
+ <span class="small hint"
+ title="Click to see menu items" i18n:attributes="title"
+ data-ams-hint-gravity="e">
+ <i class="fa fa-plus-square-o switch"></i>
+ </span>
+ </span> <span class="title" tal:content="i18n:context.title">title</span>
+ <div class="inner-table-form menus margin-x-10 margin-bottom-0 padding-left-5"></div>
+</i18n:v>
--- a/src/pyams_content/features/preview/zmi/templates/preview.pt Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/preview/zmi/templates/preview.pt Wed Jun 27 16:42:01 2018 +0200
@@ -14,7 +14,7 @@
</button>
<h3 class="modal-title"
tal:define="config extension:configuration;">
- <span class="title" tal:content="view.title | context.title | config.title">Title</span>
+ <span class="title" tal:content="structure view.title | context.title | config.title">Title</span>
</h3>
<tal:var replace="structure provider:form_toolbar" />
</tal:if>
@@ -36,7 +36,7 @@
tal:attributes="class string:small ${active}">
<a data-toggle="tab" class="xsmall"
tal:define="url extension:absolute_url(context, 'preview.html')"
- tal:attributes="src string:${url}?lang=${lang}">
+ tal:attributes="href string:#preview-${lang}">
<img tal:attributes="src string:/--static--/pyams_i18n/img/flags/${lang}.png" />
</a>
</li>
--- a/src/pyams_content/features/renderer/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/renderer/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -43,7 +43,11 @@
"""Get rendering adapter based on selected renderer name"""
if request is None:
request = check_request()
- return request.registry.queryMultiAdapter((self, request), self.renderer_interface, name=self.renderer or '')
+ renderer = request.registry.queryMultiAdapter((self, request), self.renderer_interface,
+ name=self.renderer or '')
+ if 'lang' in request.params:
+ renderer.language = request.params['lang']
+ return renderer
@adapter_config(context=IRenderedContent, provides=IContentRenderer)
--- a/src/pyams_content/features/renderer/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/renderer/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -41,6 +41,11 @@
label = Attribute("Renderer label")
weight = Attribute("Renderer weight")
settings_interface = Attribute("Renderer target interface")
+ language = Attribute("Renderer language (if forced)")
+
+
+class ISharedContentRenderer(IContentRenderer):
+ """Shared content renderer interface"""
class IRendererSettings(Interface):
--- a/src/pyams_content/features/renderer/skin/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/renderer/skin/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -55,7 +55,7 @@
i18n = II18n(self.context, None)
if i18n is not None:
for attr in self.i18n_context_attrs:
- setattr(self, attr, i18n.get_attribute(attr, lang=self.language, request=self.request))
+ setattr(self, attr, i18n.query_attribute(attr, lang=self.language, request=self.request))
render = get_view_template()
--- a/src/pyams_content/features/renderer/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/renderer/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -47,7 +47,6 @@
def update(self):
renderer = self.renderer
if renderer is not None:
- renderer.language = self.language
renderer.update()
def render(self):
@@ -57,10 +56,9 @@
#
-# Base content renderer
+# Base content renderer edit form
#
-
@pagelet_config(name='renderer-properties.html', context=IRenderedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='renderer-properties.json', context=IRenderedContent, layer=IPyAMSLayer)
--- a/src/pyams_content/features/review/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/features/review/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -22,7 +22,6 @@
from pyams_content.interfaces import READER_ROLE
from pyams_content.features.review.interfaces import IReviewManager, IReviewComment, IReviewComments, \
REVIEW_COMMENTS_ANNOTATION_KEY, CommentAddedEvent, ICommentAddedEvent, IReviewTarget
-from pyams_content.shared.common.interfaces import IWfSharedContentRoles
from pyams_i18n.interfaces import II18n
from pyams_mail.interfaces import IPrincipalMailInfo
from pyams_security.interfaces import ISecurityManager, IProtectedObject
@@ -124,6 +123,8 @@
def ask_review(self, reviewers, comment, notify_all=True):
"""Ask for content review"""
+ from pyams_content.shared.common.interfaces import IWfSharedContentRoles
+
roles = IWfSharedContentRoles(self.context, None)
if roles is None:
return
--- a/src/pyams_content/generations/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/generations/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,7 +19,9 @@
# import interfaces
from pyams_catalog.interfaces import MINUTE_RESOLUTION, DATE_RESOLUTION
-from pyams_content.interfaces import IBaseContent
+from pyams_content.component.theme import IThemesInfo
+from pyams_content.interfaces import IBaseContent, WEBMASTER_ROLE, OWNER_ROLE, PILOT_ROLE, MANAGER_ROLE, \
+ CONTRIBUTOR_ROLE
from pyams_content.root.interfaces import ISiteRootToolsConfiguration
from pyams_content.shared.common.interfaces import IWfSharedContent
from pyams_content.shared.form.interfaces import IFormsManagerFactory
@@ -42,6 +44,7 @@
from pyams_content.shared.common.manager import SharedToolContainer
from pyams_i18n.index import I18nTextIndexWithInterface
from pyams_security.index import PrincipalsRoleIndex
+from pyams_thesaurus.index import ThesaurusTermsListFieldIndex
from pyams_utils.registry import utility_config, get_global_registry
from pyams_utils.site import check_required_utilities
from pyramid.path import DottedNameResolver
@@ -53,9 +56,26 @@
RENAMED_CLASSES = {
- 'pyams_content.shared.common.review ReviewComment': 'pyams_content.features.review ReviewComment',
+ 'pyams_content.shared.common.review ReviewComment':
+ 'pyams_content.features.review ReviewComment',
'pyams_content.shared.common.review ReviewCommentsContainer':
- 'pyams_content.features.review ReviewCommentsContainer'
+ 'pyams_content.features.review ReviewCommentsContainer',
+ 'pyams_portal.portlets.content ContentPortletSettings':
+ 'pyams_content.portlet.content SharedContentPortletSettings',
+ 'pyams_content.component.association.menu MenusContainer':
+ 'pyams_content.features.menu MenusContainer',
+ 'pyams_content.component.association.menu Menu':
+ 'pyams_content.features.menu Menu',
+ 'pyams_content.component.paragraph.keynumber KeyNumber':
+ 'pyams_content.component.keynumber KeyNumber',
+ 'pyams_content.component.paragraph.keynumber KeyNumberContainer':
+ 'pyams_content.component.keynumber KeyNumberContainer',
+ 'pyams_content.portlet.content SharedContentPortletSettings':
+ 'pyams_content.shared.common.portlet.content SharedContentPortletSettings',
+ 'pyams_content.portlet.navigation SimpleNavigationPortletSettings':
+ 'pyams_content.features.menu.portlet.navigation.simple SimpleNavigationPortletSettings',
+ 'pyams_content.portlet.navigation.interfaces ISimpleNavigationMenu':
+ 'pyams_content.features.menu.portlet.navigation.interfaces.simple ISimpleNavigationMenu'
}
@@ -76,11 +96,11 @@
REQUIRED_INDEXES = [
('content_type', FieldIndexWithInterface, {'interface': IBaseContent,
'discriminator': 'content_type'}),
- ('role:owner', PrincipalsRoleIndex, {'role_id': 'pyams.Owner'}),
- ('role:pilot', PrincipalsRoleIndex, {'role_id': 'pyams.Pilot'}),
- ('role:manager', PrincipalsRoleIndex, {'role_id': 'pyams.Manager'}),
- ('role:contributor', PrincipalsRoleIndex, {'role_id': 'pyams.Contributor'}),
- ('role:webmaster', PrincipalsRoleIndex, {'role_id': 'pyams.Webmaster'}),
+ ('role:owner', PrincipalsRoleIndex, {'role_id': OWNER_ROLE}),
+ ('role:pilot', PrincipalsRoleIndex, {'role_id': PILOT_ROLE}),
+ ('role:manager', PrincipalsRoleIndex, {'role_id': MANAGER_ROLE}),
+ ('role:contributor', PrincipalsRoleIndex, {'role_id': CONTRIBUTOR_ROLE}),
+ ('role:webmaster', PrincipalsRoleIndex, {'role_id': WEBMASTER_ROLE}),
('parents', KeywordIndexWithInterface, {'interface': IPathElements,
'discriminator': 'parents'}),
('workflow_state', FieldIndexWithInterface, {'interface': IWorkflowState,
@@ -109,7 +129,19 @@
'resolution': MINUTE_RESOLUTION}),
('first_publication_date', DatetimeIndexWithInterface, {'interface': IWorkflowPublicationInfo,
'discriminator': 'first_publication_date',
- 'resolution': MINUTE_RESOLUTION})
+ 'resolution': MINUTE_RESOLUTION}),
+ ('themes', ThesaurusTermsListFieldIndex, {'interface': IThemesInfo,
+ 'discriminator': 'themes',
+ 'include_parents': False,
+ 'include_synonyms': False}),
+ ('themes_tree', ThesaurusTermsListFieldIndex, {'interface': IThemesInfo,
+ 'discriminator': 'themes',
+ 'include_parents': True,
+ 'include_synonyms': False}),
+ ('themes_all', ThesaurusTermsListFieldIndex, {'interface': IThemesInfo,
+ 'discriminator': 'themes',
+ 'include_parents': True,
+ 'include_synonyms': True})
]
--- a/src/pyams_content/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -93,7 +93,9 @@
"""Base content interface"""
__name__ = TextLine(title=_("Unique key"),
- description=_("WARNING: this key can't be modified after creation!!!"),
+ description=_("WARNING: this key can't be modified after creation!!! Spaces, "
+ "uppercase letters ou accentuated characters will be replaced "
+ "automatically."),
required=True)
title = I18nTextLineField(title=_("Title"),
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 Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/locales/fr/LC_MESSAGES/pyams_content.po Wed Jun 27 16:42:01 2018 +0200
@@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-06-06 13:20+0200\n"
+"POT-Creation-Date: 2018-06-26 14:52+0200\n"
"PO-Revision-Date: 2015-09-10 10:42+0200\n"
"Last-Translator: Thierry Florac <tflorac@ulthar.net>\n"
"Language-Team: French\n"
@@ -48,31 +48,31 @@
msgid "Webmaster (role)"
msgstr "Webmestre (rôle)"
-#: src/pyams_content/__init__.py:62
+#: src/pyams_content/__init__.py:64
msgid "Pilot (role)"
msgstr "Pilote (rôle)"
-#: src/pyams_content/__init__.py:70
+#: src/pyams_content/__init__.py:74
msgid "Manager (role)"
msgstr "Responsable (rôle)"
-#: src/pyams_content/__init__.py:77
+#: src/pyams_content/__init__.py:83
msgid "Owner (role)"
msgstr "Propriétaire (rôle)"
-#: src/pyams_content/__init__.py:82
+#: src/pyams_content/__init__.py:88
msgid "Contributor (role)"
msgstr "Contributeur (rôle)"
-#: src/pyams_content/__init__.py:90
+#: src/pyams_content/__init__.py:99
msgid "Reader (role)"
msgstr "Relecteur (rôle)"
-#: src/pyams_content/__init__.py:96
+#: src/pyams_content/__init__.py:109
msgid "Operator (role)"
msgstr "Opérateur (rôle)"
-#: src/pyams_content/__init__.py:100
+#: src/pyams_content/__init__.py:114
msgid "Guest user (role)"
msgstr "Invité (rôle)"
@@ -80,25 +80,25 @@
msgid "Gallery"
msgstr "Galerie de médias"
-#: src/pyams_content/component/gallery/zmi/file.py:58
+#: src/pyams_content/component/gallery/zmi/file.py:57
#: src/pyams_content/component/gallery/zmi/file.py:69
-#: src/pyams_content/component/gallery/zmi/paragraph.py:174
+#: src/pyams_content/component/gallery/zmi/paragraph.py:164
msgid "Add media(s)"
msgstr "Ajouter des médias"
-#: src/pyams_content/component/gallery/zmi/file.py:189
+#: src/pyams_content/component/gallery/zmi/file.py:184
msgid "Update media properties"
msgstr "Propriétés du média"
-#: src/pyams_content/component/gallery/zmi/file.py:249
+#: src/pyams_content/component/gallery/zmi/file.py:238
msgid "Remove media..."
msgstr "Supprimer le média"
-#: src/pyams_content/component/gallery/zmi/file.py:154
+#: src/pyams_content/component/gallery/zmi/file.py:148
msgid "Show/hide media"
msgstr "Cliquez pour rendre le média visible ou non"
-#: src/pyams_content/component/gallery/zmi/file.py:216
+#: src/pyams_content/component/gallery/zmi/file.py:211
msgid "Audio content"
msgstr "Contenu audio associé"
@@ -106,25 +106,25 @@
msgid "Medias gallery..."
msgstr "Galerie de médias"
-#: src/pyams_content/component/gallery/zmi/paragraph.py:67
+#: src/pyams_content/component/gallery/zmi/paragraph.py:69
msgid "Add new gallery"
msgstr "Ajout d'une galerie de médias"
-#: src/pyams_content/component/gallery/zmi/paragraph.py:99
+#: src/pyams_content/component/gallery/zmi/paragraph.py:96
msgid "Edit gallery properties"
msgstr "Propriétés de la galerie de médias"
-#: src/pyams_content/component/gallery/zmi/__init__.py:62
+#: src/pyams_content/component/gallery/zmi/__init__.py:63
msgid "Update gallery properties"
msgstr "Propriétés de la galerie de médias"
-#: src/pyams_content/component/gallery/zmi/__init__.py:101
+#: src/pyams_content/component/gallery/zmi/__init__.py:95
msgid "Update gallery contents"
msgstr "Contenu de la galerie de médias"
#: src/pyams_content/component/gallery/zmi/interfaces.py:36
msgid "Images or videos data"
-msgstr "Fichier (image ou vidéo)"
+msgstr "Fichier"
#: src/pyams_content/component/gallery/zmi/interfaces.py:37
msgid "You can upload a single file or choose to upload a whole ZIP archive"
@@ -135,8 +135,8 @@
#: src/pyams_content/component/gallery/zmi/interfaces.py:40
#: 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/illustration/interfaces/__init__.py:68
+#: src/pyams_content/component/paragraph/interfaces/video.py:52
#: src/pyams_content/component/paragraph/interfaces/audio.py:48
#: src/pyams_content/component/paragraph/interfaces/verbatim.py:44
#: src/pyams_content/component/video/interfaces/__init__.py:52
@@ -146,7 +146,7 @@
#: src/pyams_content/component/gallery/zmi/interfaces.py:41
#: 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:53
#: src/pyams_content/component/paragraph/interfaces/audio.py:49
#: src/pyams_content/component/video/interfaces/__init__.py:53
msgid "Name of document's author"
@@ -180,25 +180,27 @@
msgstr "Galerie de médias"
#: src/pyams_content/component/gallery/interfaces/__init__.py:47
-#: src/pyams_content/component/illustration/interfaces/__init__.py:41
-#: src/pyams_content/component/illustration/interfaces/__init__.py:77
+#: src/pyams_content/component/illustration/interfaces/__init__.py:46
+#: src/pyams_content/component/illustration/interfaces/__init__.py:105
msgid "Image or video data"
-msgstr "Fichier (image ou vidéo)"
+msgstr "Fichier"
#: src/pyams_content/component/gallery/interfaces/__init__.py:48
-#: src/pyams_content/component/illustration/interfaces/__init__.py:42
-#: src/pyams_content/component/illustration/interfaces/__init__.py:78
+#: src/pyams_content/component/illustration/interfaces/__init__.py:47
+#: src/pyams_content/component/illustration/interfaces/__init__.py:106
msgid "Image or video content"
msgstr ""
"Cliquez sur le bouton 'Parcourir...' pour sélectionner un nouveau contenu..."
#: src/pyams_content/component/gallery/interfaces/__init__.py:51
-#: src/pyams_content/component/illustration/interfaces/__init__.py:45
+#: src/pyams_content/component/illustration/interfaces/__init__.py:53
+#: src/pyams_content/component/paragraph/interfaces/video.py:45
+#: src/pyams_content/component/video/interfaces/__init__.py:75
msgid "Legend"
msgstr "Légende"
#: src/pyams_content/component/gallery/interfaces/__init__.py:54
-#: src/pyams_content/component/illustration/interfaces/__init__.py:48
+#: src/pyams_content/component/illustration/interfaces/__init__.py:56
#: src/pyams_content/reference/pictograms/interfaces/__init__.py:48
msgid "Accessibility title"
msgstr "Alternative (accessibilité)"
@@ -214,13 +216,13 @@
#: src/pyams_content/component/gallery/interfaces/__init__.py:58
#: 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/illustration/interfaces/__init__.py:64
+#: src/pyams_content/component/paragraph/interfaces/video.py:48
#: src/pyams_content/component/paragraph/interfaces/audio.py:44
-#: src/pyams_content/component/links/interfaces/__init__.py:37
+#: src/pyams_content/component/links/interfaces/__init__.py:39
#: src/pyams_content/component/video/interfaces/__init__.py:48
-#: src/pyams_content/shared/common/interfaces/__init__.py:145
-#: src/pyams_content/shared/form/interfaces/__init__.py:65
+#: src/pyams_content/shared/common/interfaces/__init__.py:154
+#: src/pyams_content/shared/form/interfaces/__init__.py:66
msgid "Description"
msgstr "Description"
@@ -273,17 +275,20 @@
msgstr "Si 'non', ce média ne sera pas présenté aux internautes"
#: src/pyams_content/component/gallery/interfaces/__init__.py:94
-#: src/pyams_content/component/paragraph/zmi/milestone.py:246
-#: src/pyams_content/component/paragraph/zmi/container.py:224
+#: src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:31
+#: src/pyams_content/component/paragraph/zmi/milestone.py:231
+#: src/pyams_content/component/paragraph/zmi/container.py:223
#: src/pyams_content/component/paragraph/interfaces/milestone.py:45
-#: src/pyams_content/component/links/zmi/reverse.py:71
+#: src/pyams_content/component/links/zmi/reverse.py:73
#: src/pyams_content/shared/common/zmi/dashboard.py:109
#: src/pyams_content/shared/common/zmi/templates/advanced-search.pt:188
#: src/pyams_content/shared/imagemap/zmi/container.py:123
-#: src/pyams_content/shared/site/zmi/folder.py:68
+#: src/pyams_content/shared/site/zmi/folder.py:70
#: src/pyams_content/root/zmi/templates/advanced-search.pt:188
-#: src/pyams_content/interfaces/__init__.py:99
-#: src/pyams_content/reference/pictograms/zmi/__init__.py:165
+#: src/pyams_content/interfaces/__init__.py:101
+#: src/pyams_content/reference/pictograms/zmi/__init__.py:150
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:31
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:31
msgid "Title"
msgstr "Titre"
@@ -338,59 +343,59 @@
msgid "Add external file"
msgstr "Fichier"
-#: src/pyams_content/component/extfile/zmi/__init__.py:101
+#: src/pyams_content/component/extfile/zmi/__init__.py:103
msgid "Add new external file"
msgstr "Ajout d'un fichier"
-#: src/pyams_content/component/extfile/zmi/__init__.py:141
+#: src/pyams_content/component/extfile/zmi/__init__.py:138
msgid "Update file properties"
msgstr "Propriétés du fichier"
-#: src/pyams_content/component/extfile/zmi/__init__.py:181
+#: src/pyams_content/component/extfile/zmi/__init__.py:171
msgid "Images"
msgstr "Images"
-#: src/pyams_content/component/extfile/zmi/__init__.py:196
+#: src/pyams_content/component/extfile/zmi/__init__.py:186
msgid "Add image"
msgstr "Image téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:208
+#: src/pyams_content/component/extfile/zmi/__init__.py:200
msgid "Add new image"
msgstr "Ajout d'une image téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:244
+#: src/pyams_content/component/extfile/zmi/__init__.py:231
msgid "Update image properties"
msgstr "Propriétés de l'image téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:283
+#: src/pyams_content/component/extfile/zmi/__init__.py:264
msgid "Videos"
msgstr "Vidéos"
-#: src/pyams_content/component/extfile/zmi/__init__.py:298
+#: src/pyams_content/component/extfile/zmi/__init__.py:279
msgid "Add video"
msgstr "Vidéo téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:310
+#: src/pyams_content/component/extfile/zmi/__init__.py:293
msgid "Add new video"
msgstr "Ajout d'une vidéo téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:339
+#: src/pyams_content/component/extfile/zmi/__init__.py:317
msgid "Update video properties"
msgstr "Propriétés de la vidéo téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:371
+#: src/pyams_content/component/extfile/zmi/__init__.py:343
msgid "Audios files"
msgstr "Fichiers audios"
-#: src/pyams_content/component/extfile/zmi/__init__.py:386
+#: src/pyams_content/component/extfile/zmi/__init__.py:358
msgid "Add audio file"
msgstr "Bande son téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:398
+#: src/pyams_content/component/extfile/zmi/__init__.py:372
msgid "Add new audio file"
msgstr "Ajout d'une bande son téléchargeable"
-#: src/pyams_content/component/extfile/zmi/__init__.py:427
+#: src/pyams_content/component/extfile/zmi/__init__.py:396
msgid "Update audio file properties"
msgstr "Propriétés de la bande son téléchargeable"
@@ -399,7 +404,7 @@
msgstr "Type de fichier joint"
#: src/pyams_content/component/extfile/interfaces/__init__.py:36
-#: src/pyams_content/component/links/interfaces/__init__.py:33
+#: src/pyams_content/component/links/interfaces/__init__.py:35
#: src/pyams_content/shared/imagemap/interfaces/__init__.py:54
#: src/pyams_content/shared/site/interfaces/__init__.py:113
msgid "Alternate title"
@@ -410,14 +415,14 @@
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:49
#: src/pyams_content/component/paragraph/interfaces/audio.py:45
#: 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"
#: src/pyams_content/component/extfile/interfaces/__init__.py:48
-#: src/pyams_content/component/links/interfaces/__init__.py:59
+#: src/pyams_content/component/links/interfaces/__init__.py:68
msgid "Language"
msgstr "Langue"
@@ -456,7 +461,7 @@
"Cliquez sur le bouton 'Parcourir...' pour sélectionner un nouveau contenu..."
#: src/pyams_content/component/extfile/interfaces/__init__.py:81
-#: src/pyams_content/component/paragraph/interfaces/video.py:52
+#: src/pyams_content/component/paragraph/interfaces/video.py:41
msgid "Video data"
msgstr "Fichier"
@@ -471,30 +476,145 @@
msgstr ""
"Cliquez sur le bouton 'Parcourir...' pour sélectionner un nouveau contenu"
-#: src/pyams_content/component/illustration/__init__.py:132
-#: src/pyams_content/component/illustration/zmi/__init__.py:54
-#: src/pyams_content/component/illustration/zmi/__init__.py:81
-#: src/pyams_content/component/illustration/interfaces/__init__.py:71
+#: src/pyams_content/component/keynumber/__init__.py:189
+#: src/pyams_content/component/keynumber/zmi/__init__.py:198
+#: src/pyams_content/component/keynumber/portlet/zmi/__init__.py:79
+#: src/pyams_content/component/paragraph/interfaces/keynumber.py:29
+msgid "Key numbers"
+msgstr "Chiffres-clés"
+
+#. Default: Header
+#: src/pyams_content/component/keynumber/zmi/__init__.py:146
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:44
+msgid "key-number-label"
+msgstr "En-tête"
+
+#: src/pyams_content/component/keynumber/zmi/__init__.py:158
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:49
+msgid "Number"
+msgstr "Chiffre"
+
+#. Default: Unit
+#: src/pyams_content/component/keynumber/zmi/__init__.py:167
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:53
+msgid "key-number-unit"
+msgstr "Unité"
+
+#: src/pyams_content/component/keynumber/zmi/__init__.py:179
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:57
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:267
+#: src/pyams_content/component/paragraph/interfaces/pictogram.py:58
+msgid "Associated text"
+msgstr "Texte associé"
+
+#: src/pyams_content/component/keynumber/zmi/__init__.py:217
+msgid "Add keynumber"
+msgstr "Ajouter un chiffre-clé"
+
+#: src/pyams_content/component/keynumber/zmi/__init__.py:229
+msgid "Add new keynumber"
+msgstr "Ajout d'un chiffre-clé"
+
+#: src/pyams_content/component/keynumber/zmi/__init__.py:258
+msgid "Edit keynumber properties"
+msgstr "Propriétés du chiffre-clé"
+
+#: src/pyams_content/component/keynumber/zmi/__init__.py:244
+msgid "Key number was correctly added"
+msgstr "Le chiffre-clé a été ajouté."
+
+#: src/pyams_content/component/keynumber/portlet/__init__.py:71
+msgid "Key Numbers"
+msgstr "Chiffres-clés"
+
+#: src/pyams_content/component/keynumber/portlet/zmi/__init__.py:102
+#: src/pyams_content/component/keynumber/portlet/zmi/templates/keynumber-preview.pt:22
+msgid "Associated links"
+msgstr "Liens associés"
+
+#: src/pyams_content/component/keynumber/portlet/zmi/templates/keynumber-preview.pt:27
+#: src/pyams_content/features/menu/portlet/navigation/zmi/templates/double-preview.pt:12
+#: src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt:9
+msgid "Link target is not published!"
+msgstr "Le contenu ciblé n'est pas publié"
+
+#: src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:32
+msgid "Portlet title"
+msgstr "Titre"
+
+#: src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:35
+msgid "Teaser"
+msgstr "Accroche"
+
+#: src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:36
+msgid "Short text displayed above key numbers"
+msgstr "Texte d'introduction des chiffres-clés"
+
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:39
+#: 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/association/interfaces/__init__.py:42
+#: src/pyams_content/shared/form/interfaces/__init__.py:87
+#: src/pyams_content/shared/site/interfaces/__init__.py:117
+#: src/pyams_content/features/alert/interfaces.py:54
+#: src/pyams_content/features/menu/interfaces/__init__.py:58
+msgid "Visible?"
+msgstr "Visible ?"
+
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:40
+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/keynumber/interfaces/__init__.py:45
+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/keynumber/interfaces/__init__.py:50
+msgid "Key number value"
+msgstr "Chiffre"
+
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:54
+msgid "Displayed unit"
+msgstr "Unité affichée"
+
+#: src/pyams_content/component/keynumber/interfaces/__init__.py:58
+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/illustration/__init__.py:177
+#: src/pyams_content/component/illustration/zmi/paragraph.py:168
+#: src/pyams_content/component/illustration/zmi/__init__.py:56
+#: src/pyams_content/component/illustration/zmi/__init__.py:100
+#: src/pyams_content/component/illustration/interfaces/__init__.py:99
msgid "Illustration"
msgstr "Illustration"
-#: src/pyams_content/component/illustration/zmi/paragraph.py:57
+#: src/pyams_content/component/illustration/zmi/paragraph.py:60
msgid "Illustration..."
msgstr "Illustration"
-#: src/pyams_content/component/illustration/zmi/paragraph.py:68
+#: src/pyams_content/component/illustration/zmi/paragraph.py:73
msgid "Add new illustration"
msgstr "Ajout d'une illustration"
-#: src/pyams_content/component/illustration/zmi/paragraph.py:102
+#: src/pyams_content/component/illustration/zmi/paragraph.py:103
msgid "Edit illustration properties"
msgstr "Propriétés de l'illustration"
-#: src/pyams_content/component/illustration/zmi/__init__.py:83
+#: src/pyams_content/component/illustration/zmi/__init__.py:155
+msgid "Navigation link illustration"
+msgstr "Illustration de navigation"
+
+#: src/pyams_content/component/illustration/zmi/__init__.py:102
msgid "Header illustration"
msgstr "Illustration d'en-tête"
-#: src/pyams_content/component/illustration/interfaces/__init__.py:49
+#: src/pyams_content/component/illustration/interfaces/__init__.py:57
#: src/pyams_content/reference/pictograms/interfaces/__init__.py:49
msgid "Alternate title used to describe image content"
msgstr ""
@@ -503,15 +623,15 @@
"déficiences visuelles. Il doit donc décrire le contenu, pour se conformer "
"aux normes d'accessibilité."
-#: src/pyams_content/component/illustration/interfaces/__init__.py:57
+#: src/pyams_content/component/illustration/interfaces/__init__.py:69
msgid "Name of picture's author"
msgstr "Sous la forme \"Prénom Nom / Organisme\""
-#: src/pyams_content/component/illustration/interfaces/__init__.py:60
+#: src/pyams_content/component/illustration/interfaces/__init__.py:72
msgid "Illustration template"
msgstr "Mode de rendu"
-#: src/pyams_content/component/illustration/interfaces/__init__.py:61
+#: src/pyams_content/component/illustration/interfaces/__init__.py:73
msgid "Presentation template used for illustration"
msgstr ""
"<span>Modèle de présentation utilisé par cette illustration.<br /"
@@ -534,7 +654,7 @@
msgid "no visible paragraph"
msgstr "aucun bloc de contenu visible"
-#: src/pyams_content/component/paragraph/pictogram.py:134
+#: src/pyams_content/component/paragraph/pictogram.py:135
msgid "Selected pictogram is missing"
msgstr "le pictogramme sélectionné est introuvable"
@@ -542,62 +662,62 @@
msgid "Milestones..."
msgstr "Chronologie"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:88
+#: src/pyams_content/component/paragraph/zmi/milestone.py:90
msgid "Add new milestone paragraph"
msgstr "Ajout d'une chronologie"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:120
+#: src/pyams_content/component/paragraph/zmi/milestone.py:117
msgid "Edit milestone paragraph properties"
msgstr "Propriétés de la chronologie"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:258
+#: src/pyams_content/component/paragraph/zmi/milestone.py:243
#: src/pyams_content/component/paragraph/interfaces/milestone.py:49
msgid "Associated label"
msgstr "Information associée"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:270
+#: src/pyams_content/component/paragraph/zmi/milestone.py:255
#: src/pyams_content/component/paragraph/interfaces/milestone.py:53
msgid "Anchor"
msgstr "Ancre"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:299
+#: src/pyams_content/component/paragraph/zmi/milestone.py:284
#: src/pyams_content/component/paragraph/interfaces/milestone.py:76
msgid "Milestones"
msgstr "Chronologie"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:314
+#: src/pyams_content/component/paragraph/zmi/milestone.py:299
msgid "Add milestone"
msgstr "Ajouter un jalon"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:325
+#: src/pyams_content/component/paragraph/zmi/milestone.py:312
msgid "Add new milestone"
msgstr "Ajout d'un jalon"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:358
+#: src/pyams_content/component/paragraph/zmi/milestone.py:339
msgid "Edit milestone properties"
msgstr "Propriétés du jalon"
-#: src/pyams_content/component/paragraph/zmi/milestone.py:347
+#: src/pyams_content/component/paragraph/zmi/milestone.py:327
msgid "Milestone was correctly added"
msgstr "Le jalon a été ajouté."
-#: src/pyams_content/component/paragraph/zmi/milestone.py:285
+#: src/pyams_content/component/paragraph/zmi/milestone.py:270
msgid "(missing paragraph)"
msgstr "(paragraphe supprimé)"
-#: src/pyams_content/component/paragraph/zmi/keypoint.py:50
+#: src/pyams_content/component/paragraph/zmi/keypoint.py:51
msgid "Key points..."
msgstr "Points clés"
-#: src/pyams_content/component/paragraph/zmi/keypoint.py:61
+#: src/pyams_content/component/paragraph/zmi/keypoint.py:64
msgid "Add new key points paragraph"
msgstr "Ajout de points clés"
-#: src/pyams_content/component/paragraph/zmi/keypoint.py:93
+#: src/pyams_content/component/paragraph/zmi/keypoint.py:91
msgid "Edit key points paragraph properties"
msgstr "Propriétés des points clés"
-#: src/pyams_content/component/paragraph/zmi/__init__.py:66
+#: src/pyams_content/component/paragraph/zmi/__init__.py:65
msgid "Content block types..."
msgstr "Types de blocs de contenu"
@@ -605,7 +725,7 @@
msgid "Content block types"
msgstr "Types de blocs de contenu"
-#: src/pyams_content/component/paragraph/zmi/__init__.py:96
+#: src/pyams_content/component/paragraph/zmi/__init__.py:89
msgid ""
"You can define which types of paragraphs are allowed in this container.\n"
"\n"
@@ -624,230 +744,176 @@
"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:214
+#: src/pyams_content/component/paragraph/zmi/__init__.py:207
#: src/pyams_content/shared/common/zmi/templates/preview-input.pt:39
#: src/pyams_content/features/preview/zmi/__init__.py:45
msgid "Preview"
msgstr "Aperçu"
-#: src/pyams_content/component/paragraph/zmi/__init__.py:219
-#: src/pyams_content/shared/common/zmi/workflow.py:125
-#: src/pyams_content/shared/common/zmi/workflow.py:217
-#: src/pyams_content/shared/common/zmi/workflow.py:262
-#: src/pyams_content/shared/common/zmi/workflow.py:321
-#: src/pyams_content/shared/common/zmi/workflow.py:415
-#: src/pyams_content/shared/common/zmi/workflow.py:476
-#: src/pyams_content/shared/common/zmi/workflow.py:521
-#: src/pyams_content/shared/common/zmi/workflow.py:567
-#: src/pyams_content/shared/common/zmi/workflow.py:615
-#: src/pyams_content/shared/common/zmi/workflow.py:660
-#: src/pyams_content/shared/common/zmi/workflow.py:706
-#: src/pyams_content/shared/common/zmi/workflow.py:762
-#: src/pyams_content/shared/common/zmi/__init__.py:276
-#: src/pyams_content/shared/common/zmi/owner.py:74
+#: src/pyams_content/component/paragraph/zmi/__init__.py:212
+#: src/pyams_content/shared/common/zmi/workflow.py:122
+#: src/pyams_content/shared/common/zmi/workflow.py:209
+#: src/pyams_content/shared/common/zmi/workflow.py:249
+#: src/pyams_content/shared/common/zmi/workflow.py:303
+#: src/pyams_content/shared/common/zmi/workflow.py:392
+#: src/pyams_content/shared/common/zmi/workflow.py:448
+#: src/pyams_content/shared/common/zmi/workflow.py:488
+#: src/pyams_content/shared/common/zmi/workflow.py:529
+#: src/pyams_content/shared/common/zmi/workflow.py:572
+#: src/pyams_content/shared/common/zmi/workflow.py:612
+#: src/pyams_content/shared/common/zmi/workflow.py:653
+#: src/pyams_content/shared/common/zmi/workflow.py:704
+#: src/pyams_content/shared/common/zmi/__init__.py:275
+#: src/pyams_content/shared/common/zmi/owner.py:73
#: src/pyams_content/features/review/zmi/__init__.py:90
msgid "Cancel"
msgstr "Annuler"
-#: src/pyams_content/component/paragraph/zmi/__init__.py:221
+#: src/pyams_content/component/paragraph/zmi/__init__.py:214
msgid "Submit"
msgstr "Enregistrer"
-#: src/pyams_content/component/paragraph/zmi/__init__.py:202
+#: src/pyams_content/component/paragraph/zmi/__init__.py:195
msgid "Paragraph was correctly added."
msgstr "Le bloc a été ajouté."
-#: src/pyams_content/component/paragraph/zmi/video.py:54
+#: src/pyams_content/component/paragraph/zmi/video.py:53
msgid "Video paragraph..."
msgstr "Vidéo"
-#: src/pyams_content/component/paragraph/zmi/video.py:65
+#: 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:112
-#: src/pyams_content/component/video/zmi/paragraph.py:209
+#: src/pyams_content/component/paragraph/zmi/video.py:94
+#: src/pyams_content/component/video/zmi/paragraph.py:192
msgid "Edit video properties"
msgstr "Propriétés de la vidéo"
-#: src/pyams_content/component/paragraph/zmi/video.py:83
-#: src/pyams_content/component/paragraph/zmi/video.py:133
-#: src/pyams_content/component/paragraph/zmi/audio.py:83
-#: src/pyams_content/component/paragraph/zmi/audio.py:133
-#: src/pyams_content/component/video/zmi/paragraph.py:103
-#: src/pyams_content/component/video/zmi/paragraph.py:238
-msgid "HTML content"
-msgstr "Contenu HTML"
-
#: src/pyams_content/component/paragraph/zmi/container.py:74
msgid "Contents..."
msgstr "Contenu"
-#: src/pyams_content/component/paragraph/zmi/container.py:240
+#: src/pyams_content/component/paragraph/zmi/container.py:239
msgid "Show/hide all paragraphs"
msgstr "Afficher/masquer tous les blocs"
-#: src/pyams_content/component/paragraph/zmi/container.py:288
-#: src/pyams_content/component/paragraph/zmi/container.py:297
-#: src/pyams_content/component/paragraph/zmi/container.py:310
+#: src/pyams_content/component/paragraph/zmi/container.py:287
+#: src/pyams_content/component/paragraph/zmi/container.py:296
+#: src/pyams_content/component/paragraph/zmi/container.py:309
msgid "Content blocks"
msgstr "Blocs de contenu"
-#: src/pyams_content/component/paragraph/zmi/container.py:367
+#: src/pyams_content/component/paragraph/zmi/container.py:366
msgid "Links and attachments..."
msgstr "Récap. liens et PJ"
-#: src/pyams_content/component/paragraph/zmi/container.py:379
+#: src/pyams_content/component/paragraph/zmi/container.py:378
msgid "Content blocks links and attachments"
msgstr "Récapitulatif des liens et pièces jointes par bloc de contenu"
-#: src/pyams_content/component/paragraph/zmi/container.py:127
+#: src/pyams_content/component/paragraph/zmi/container.py:126
msgid "No currently defined paragraph."
msgstr "Aucun bloc n'est associé à ce contenu."
-#: src/pyams_content/component/paragraph/zmi/container.py:249
+#: src/pyams_content/component/paragraph/zmi/container.py:248
msgid "Click to open/close all paragraphs editors"
msgstr "Afficher/masquer tous les blocs"
-#: src/pyams_content/component/paragraph/zmi/container.py:262
+#: src/pyams_content/component/paragraph/zmi/container.py:261
msgid "Click to open/close paragraph editor"
msgstr "Afficher/masquer ce bloc"
-#: src/pyams_content/component/paragraph/zmi/container.py:133
+#: src/pyams_content/component/paragraph/zmi/container.py:132
msgid "Check allowed paragraph types to be able to create new paragraphs."
msgstr ""
"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:83
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:82
msgid "Pictograms..."
msgstr "Pictogrammes"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:94
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:95
msgid "Add new pictogram paragraph"
msgstr "Ajout de pictogrammes"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:126
+#: 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:268
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:252
msgid "pictogram-item-header"
msgstr "En-tête"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:283
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:263
-#: 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:305
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:289
#: src/pyams_content/component/paragraph/interfaces/pictogram.py:80
msgid "Pictograms"
msgstr "Pictogrammes"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:320
-#: src/pyams_content/reference/pictograms/zmi/__init__.py:62
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:304
+#: src/pyams_content/reference/pictograms/zmi/__init__.py:59
msgid "Add pictogram"
msgstr "Ajouter un pictogramme"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:331
-#: src/pyams_content/reference/pictograms/zmi/__init__.py:73
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:317
+#: src/pyams_content/reference/pictograms/zmi/__init__.py:71
msgid "Add new pictogram"
msgstr "Ajout d'un pictogramme"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:393
-#: src/pyams_content/reference/pictograms/zmi/__init__.py:103
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:359
+#: src/pyams_content/reference/pictograms/zmi/__init__.py:95
msgid "Edit pictogram properties"
msgstr "Propriétés du pictogramme"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:374
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:339
msgid "Pictogram was correctly added"
msgstr "Le pictogramme a été ajouté."
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:384
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:448
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:349
+#: src/pyams_content/component/paragraph/zmi/pictogram.py:387
msgid "You must select a pictogram!"
msgstr "Vous devez sélectionner un pictogramme !"
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:347
-#: src/pyams_content/reference/pictograms/zmi/__init__.py:186
-msgid "Default header: --"
-msgstr "En-tête par défaut : --"
-
-#: src/pyams_content/component/paragraph/zmi/pictogram.py:414
-#: src/pyams_content/reference/pictograms/zmi/__init__.py:190
-#, python-format
-msgid "Default header: {0}"
-msgstr "En-tête par défaut : {0}"
-
#: src/pyams_content/component/paragraph/zmi/audio.py:54
msgid "Audio paragraph..."
msgstr "Bande son"
-#: src/pyams_content/component/paragraph/zmi/audio.py:65
+#: src/pyams_content/component/paragraph/zmi/audio.py:67
msgid "Add new audio paragraph"
msgstr "Ajout d'une bande son"
-#: src/pyams_content/component/paragraph/zmi/audio.py:112
+#: src/pyams_content/component/paragraph/zmi/audio.py:108
msgid "Edit audio properties"
msgstr "Propriétés de la bande son"
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:76
+#: src/pyams_content/component/paragraph/zmi/audio.py:84
+#: src/pyams_content/component/paragraph/zmi/audio.py:128
+msgid "HTML content"
+msgstr "Contenu HTML"
+
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:55
msgid "Key numbers..."
msgstr "Chiffres-clés"
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:87
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:68
msgid "Add new key number paragraph"
msgstr "Ajout de chiffres-clés"
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:119
+#: src/pyams_content/component/paragraph/zmi/keynumber.py:96
msgid "Edit key number paragraph properties"
msgstr "Propriétés des chiffres-clés"
-#: 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: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:282
-#: src/pyams_content/component/paragraph/interfaces/keynumber.py:76
-msgid "Key numbers"
-msgstr "Chiffres-clés"
-
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:297
-msgid "Add keynumber"
-msgstr "Ajouter un chiffre-clé"
-
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:308
-msgid "Add new keynumber"
-msgstr "Ajout d'un chiffre-clé"
-
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:341
-msgid "Edit keynumber properties"
-msgstr "Propriétés du chiffre-clé"
-
-#: src/pyams_content/component/paragraph/zmi/keynumber.py:330
-msgid "Key number was correctly added"
-msgstr "Le chiffre-clé a été ajouté."
-
#: src/pyams_content/component/paragraph/zmi/frame.py:84
msgid "Framed text..."
msgstr "Encadré"
-#: src/pyams_content/component/paragraph/zmi/frame.py:96
+#: src/pyams_content/component/paragraph/zmi/frame.py:98
msgid "Add new framed text paragraph"
msgstr "Ajout d'un encadré"
-#: src/pyams_content/component/paragraph/zmi/frame.py:132
+#: src/pyams_content/component/paragraph/zmi/frame.py:129
msgid "Edit framed text paragraph properties"
msgstr "Propriétés de l'encadré"
@@ -855,11 +921,11 @@
msgid "Verbatim..."
msgstr "Verbatim"
-#: src/pyams_content/component/paragraph/zmi/verbatim.py:67
+#: src/pyams_content/component/paragraph/zmi/verbatim.py:69
msgid "Add new verbatim paragraph"
msgstr "Ajout d'un verbatim"
-#: src/pyams_content/component/paragraph/zmi/verbatim.py:99
+#: src/pyams_content/component/paragraph/zmi/verbatim.py:96
msgid "Edit verbatim paragraph properties"
msgstr "Propriétés du verbatim"
@@ -867,23 +933,23 @@
msgid "Raw HTML..."
msgstr "Code HTML"
-#: src/pyams_content/component/paragraph/zmi/html.py:87
+#: src/pyams_content/component/paragraph/zmi/html.py:89
msgid "Add new raw HTML paragraph"
msgstr "Ajout d'un bloc de code HTML"
-#: src/pyams_content/component/paragraph/zmi/html.py:122
+#: src/pyams_content/component/paragraph/zmi/html.py:119
msgid "Edit raw HTML paragraph properties"
msgstr "Propriétés du code HTML"
-#: src/pyams_content/component/paragraph/zmi/html.py:174
+#: src/pyams_content/component/paragraph/zmi/html.py:159
msgid "Rich text..."
msgstr "Texte enrichi"
-#: src/pyams_content/component/paragraph/zmi/html.py:185
+#: src/pyams_content/component/paragraph/zmi/html.py:172
msgid "Add new rich text paragraph"
msgstr "Ajout d'un bloc de texte enrichi"
-#: src/pyams_content/component/paragraph/zmi/html.py:220
+#: src/pyams_content/component/paragraph/zmi/html.py:202
msgid "Edit rich text paragraph properties"
msgstr "Propriétés du texte enrichi"
@@ -891,11 +957,11 @@
msgid "Contact card..."
msgstr "Fiche contact"
-#: src/pyams_content/component/paragraph/zmi/contact.py:64
+#: src/pyams_content/component/paragraph/zmi/contact.py:66
msgid "Add new contact card"
msgstr "Ajout d'une fiche contact"
-#: src/pyams_content/component/paragraph/zmi/contact.py:97
+#: src/pyams_content/component/paragraph/zmi/contact.py:94
msgid "Edit contact card properties"
msgstr "Propriétés de la fiche contact"
@@ -903,25 +969,14 @@
msgid "Header..."
msgstr "Chapô"
-#: src/pyams_content/component/paragraph/zmi/header.py:61
+#: src/pyams_content/component/paragraph/zmi/header.py:63
msgid "Add new header paragraph"
msgstr "Ajout d'un chapô"
-#: src/pyams_content/component/paragraph/zmi/header.py:93
+#: src/pyams_content/component/paragraph/zmi/header.py:90
msgid "Edit header paragraph properties"
msgstr "Propriétés du chapô"
-#: 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:117
-#: src/pyams_content/features/alert/interfaces.py:54
-msgid "Visible?"
-msgstr "Visible ?"
-
#: 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"
@@ -990,8 +1045,8 @@
msgstr "Liste des types de blocs de contenu autorisés pour ce gabarit."
#: 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
+#: src/pyams_content/shared/common/zmi/types.py:169
+#: src/pyams_content/shared/common/zmi/types.py:380
msgid "Default paragraphs"
msgstr "Types de blocs par défaut"
@@ -999,14 +1054,7 @@
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/audio.py:41
-#: src/pyams_content/component/paragraph/interfaces/html.py:63
-#: src/pyams_content/component/video/interfaces/__init__.py:75
-msgid "Body"
-msgstr "Contenu HTML"
-
-#: src/pyams_content/component/paragraph/interfaces/video.py:53
+#: src/pyams_content/component/paragraph/interfaces/video.py:42
msgid "Video file content"
msgstr ""
"Cliquez sur le bouton 'Parcourir...' pour sélectionner un nouveau contenu"
@@ -1026,7 +1074,8 @@
msgstr "Si 'non', ce pictogramme ne sera pas présenté aux internautes"
#: src/pyams_content/component/paragraph/interfaces/pictogram.py:46
-#: src/pyams_content/shared/common/interfaces/types.py:67
+#: src/pyams_content/component/links/interfaces/__init__.py:43
+#: src/pyams_content/shared/common/interfaces/types.py:68
#: src/pyams_content/features/alert/interfaces.py:79
msgid "Pictogram"
msgstr "Pictogramme"
@@ -1045,7 +1094,7 @@
"Alternate pictogram label; if not specified, the pictogram header will be "
"used"
msgstr ""
-"EN-tête de substitution utilisé par le pictogramme; si rien n'est spécifié, "
+"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:59
@@ -1064,6 +1113,11 @@
msgid "Audio"
msgstr "Bande son"
+#: src/pyams_content/component/paragraph/interfaces/audio.py:41
+#: src/pyams_content/component/paragraph/interfaces/html.py:63
+msgid "Body"
+msgstr "Contenu HTML"
+
#: src/pyams_content/component/paragraph/interfaces/audio.py:56
msgid "Audio template"
msgstr "Mode de rendu"
@@ -1072,31 +1126,11 @@
msgid "Presentation template used for this audio file"
msgstr "Mode de rendu utilisé pour cette bande son"
-#: 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:46
-msgid "Key number value"
-msgstr "Chiffre"
-
-#: 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: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:36
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:37
msgid "Presentation template used for key numbers"
msgstr "Modèle de présentation utilisé par ce bloc de contenu"
@@ -1254,8 +1288,8 @@
msgid "no defined theme"
msgstr "aucun thème défini"
-#: src/pyams_content/component/theme/zmi/__init__.py:52
-#: src/pyams_content/shared/view/zmi/theme.py:49
+#: src/pyams_content/component/theme/zmi/__init__.py:51
+#: src/pyams_content/shared/view/zmi/theme.py:48
msgid "Themes..."
msgstr "Thèmes"
@@ -1263,7 +1297,7 @@
msgid "Content themes"
msgstr "Thèmes du contenu"
-#: src/pyams_content/component/theme/zmi/manager.py:46
+#: src/pyams_content/component/theme/zmi/manager.py:45
msgid "Themes settings..."
msgstr "Paramétrage des thèmes"
@@ -1273,20 +1307,20 @@
#: src/pyams_content/component/association/container.py:88
#: src/pyams_content/component/association/zmi/__init__.py:296
-#: src/pyams_content/component/association/interfaces/__init__.py:86
+#: src/pyams_content/component/association/interfaces/__init__.py:90
msgid "Associations"
msgstr "Liens et pièces jointes"
#: src/pyams_content/component/association/zmi/paragraph.py:54
-#: src/pyams_content/component/association/zmi/__init__.py:95
+#: src/pyams_content/component/association/zmi/__init__.py:96
msgid "Associations..."
msgstr "Liens et pièces jointes"
-#: src/pyams_content/component/association/zmi/paragraph.py:65
+#: src/pyams_content/component/association/zmi/paragraph.py:67
msgid "Add new association paragraph"
msgstr "Ajout d'un bloc « liens et pièces jointes »"
-#: src/pyams_content/component/association/zmi/paragraph.py:97
+#: src/pyams_content/component/association/zmi/paragraph.py:93
msgid "Edit association paragraph properties"
msgstr "Propriétés du bloc « liens et pièces jointes »"
@@ -1307,135 +1341,140 @@
msgid "Associations list"
msgstr "Liste des liens et pièces jointes"
-#: src/pyams_content/component/association/zmi/__init__.py:65
+#: src/pyams_content/component/association/zmi/__init__.py:66
msgid "Association was correctly added."
msgstr "L'association a été ajoutée."
#: src/pyams_content/component/association/interfaces/__init__.py:43
+#: src/pyams_content/features/menu/interfaces/__init__.py:59
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:93
+#: src/pyams_content/component/association/interfaces/__init__.py:97
msgid "Associations template"
msgstr "Mode de rendu"
-#: src/pyams_content/component/association/interfaces/__init__.py:94
+#: src/pyams_content/component/association/interfaces/__init__.py:98
msgid "Presentation template used for associations"
msgstr "Modèle de présentation utilisé par ce bloc de contenu"
-#: src/pyams_content/component/links/__init__.py:104
+#: src/pyams_content/component/links/__init__.py:125
msgid "Internal link"
msgstr "Lien interne"
-#: src/pyams_content/component/links/__init__.py:186
+#: src/pyams_content/component/links/__init__.py:207
msgid "External link"
msgstr "Lien externe"
-#: src/pyams_content/component/links/__init__.py:239
+#: src/pyams_content/component/links/__init__.py:260
msgid "Mailto link"
msgstr "Lien mailto"
-#: src/pyams_content/component/links/__init__.py:173
+#: src/pyams_content/component/links/__init__.py:194
msgid "target is not published"
msgstr "le contenu ciblé n'est pas publié"
-#: src/pyams_content/component/links/zmi/__init__.py:57
+#: src/pyams_content/component/links/zmi/__init__.py:60
msgid "Internal links"
msgstr "Liens internes"
-#: src/pyams_content/component/links/zmi/__init__.py:72
+#: src/pyams_content/component/links/zmi/__init__.py:75
msgid "Add internal link"
msgstr "Lien interne"
-#: src/pyams_content/component/links/zmi/__init__.py:84
+#: src/pyams_content/component/links/zmi/__init__.py:89
msgid "Add new internal link"
msgstr "Ajout d'un lien interne"
-#: src/pyams_content/component/links/zmi/__init__.py:122
+#: src/pyams_content/component/links/zmi/__init__.py:125
msgid "Edit internal link properties"
msgstr "Propriétés du lien interne"
-#: src/pyams_content/component/links/zmi/__init__.py:160
+#: src/pyams_content/component/links/zmi/__init__.py:159
msgid "External links"
msgstr "Liens externes"
-#: src/pyams_content/component/links/zmi/__init__.py:175
+#: src/pyams_content/component/links/zmi/__init__.py:174
msgid "Add external link"
msgstr "Lien externe"
-#: src/pyams_content/component/links/zmi/__init__.py:187
+#: src/pyams_content/component/links/zmi/__init__.py:188
msgid "Add new external link"
msgstr "Ajout d'un lien externe"
-#: src/pyams_content/component/links/zmi/__init__.py:225
+#: src/pyams_content/component/links/zmi/__init__.py:224
msgid "Edit external link properties"
msgstr "Propriétés du lien externe"
-#: src/pyams_content/component/links/zmi/__init__.py:263
+#: src/pyams_content/component/links/zmi/__init__.py:258
msgid "Mailto links"
msgstr "Liens mailto"
-#: src/pyams_content/component/links/zmi/__init__.py:278
+#: src/pyams_content/component/links/zmi/__init__.py:273
msgid "Add mailto link"
msgstr "Lien mailto"
-#: src/pyams_content/component/links/zmi/__init__.py:290
+#: src/pyams_content/component/links/zmi/__init__.py:287
msgid "Add new mailto link"
msgstr "Ajout d'un lien « mailto »"
-#: src/pyams_content/component/links/zmi/__init__.py:328
+#: src/pyams_content/component/links/zmi/__init__.py:323
msgid "Edit mailto link properties"
msgstr "Propriétés du lien « mailto »"
-#: src/pyams_content/component/links/zmi/reverse.py:55
+#: src/pyams_content/component/links/zmi/reverse.py:57
msgid "Reverse links"
msgstr "Liens amont"
-#: src/pyams_content/component/links/zmi/reverse.py:64
+#: src/pyams_content/component/links/zmi/reverse.py:66
msgid "Content's internal links"
msgstr "Autres contenus qui pointent vers ce contenu"
-#: src/pyams_content/component/links/interfaces/__init__.py:34
+#: src/pyams_content/component/links/interfaces/__init__.py:36
msgid "Link title, as shown in front-office"
msgstr ""
"Le contexte d'utilisation de ce lien peut nécessiter de modifier son titre "
"d'origine. Ce titre de substitution sera alors présenté aux internautes."
-#: src/pyams_content/component/links/interfaces/__init__.py:38
+#: src/pyams_content/component/links/interfaces/__init__.py:40
msgid "Link description displayed by front-office template"
msgstr "Description du lien, présentée aux internautes"
-#: src/pyams_content/component/links/interfaces/__init__.py:55
+#: src/pyams_content/component/links/interfaces/__init__.py:44
+msgid "Name of the pictogram associated with this link"
+msgstr "Pictogramme à associer à ce lien"
+
+#: src/pyams_content/component/links/interfaces/__init__.py:64
#: 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/component/links/interfaces/__init__.py:65
#: 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 "
"protocole d'accès au site, comme « http:// » ou « https:// »."
-#: src/pyams_content/component/links/interfaces/__init__.py:60
+#: src/pyams_content/component/links/interfaces/__init__.py:69
msgid "Language used in this remote resource"
msgstr ""
"Langue utilisée par cette ressource extene ; à préciser lorsqu'il ne s'agit "
"pas de la langue par défaut du site."
-#: src/pyams_content/component/links/interfaces/__init__.py:68
+#: src/pyams_content/component/links/interfaces/__init__.py:77
msgid "Target address"
msgstr "Adresse mail"
-#: src/pyams_content/component/links/interfaces/__init__.py:69
+#: src/pyams_content/component/links/interfaces/__init__.py:78
msgid "Target email address"
msgstr "Adresse de messagerie \"stricte\", soit uniquement \"xxx@yyy.com\""
-#: src/pyams_content/component/links/interfaces/__init__.py:72
+#: src/pyams_content/component/links/interfaces/__init__.py:81
msgid "Address name"
msgstr "Nom de messagerie"
-#: src/pyams_content/component/links/interfaces/__init__.py:73
+#: src/pyams_content/component/links/interfaces/__init__.py:82
msgid "Address as displayed in address book"
msgstr ""
"Nom de la boîte aux lettres, tel qu'il sera affiché dans l'application de "
@@ -1704,24 +1743,24 @@
msgid "Youtube settings"
msgstr "Paramétres Youtube"
-#: src/pyams_content/component/video/zmi/paragraph.py:61
+#: src/pyams_content/component/video/zmi/paragraph.py:62
msgid "External video..."
msgstr "Vidéo externe"
-#: src/pyams_content/component/video/zmi/paragraph.py:72
+#: src/pyams_content/component/video/zmi/paragraph.py:75
msgid "Add new external video..."
msgstr "Ajout d'une vidéo externe"
-#: src/pyams_content/component/video/zmi/paragraph.py:145
+#: src/pyams_content/component/video/zmi/paragraph.py:126
msgid "Video provider is required"
msgstr "Le nom du fournisseur est obligatoire"
-#: src/pyams_content/component/video/zmi/paragraph.py:194
-#: src/pyams_content/component/video/zmi/paragraph.py:259
+#: src/pyams_content/component/video/zmi/paragraph.py:175
+#: src/pyams_content/component/video/zmi/paragraph.py:229
msgid "Video provider settings"
msgstr "Paramètres liés au fournisseur"
-#: src/pyams_content/component/video/zmi/paragraph.py:174
+#: src/pyams_content/component/video/zmi/paragraph.py:155
msgid "Other settings"
msgstr "Autres paramètres"
@@ -1733,19 +1772,19 @@
msgid "Name of external platform providing selected video"
msgstr "Nom de la plate-forme externe fournissant la vidéo à afficher"
-#: src/pyams_content/shared/common/__init__.py:237
-#: src/pyams_content/shared/common/zmi/properties.py:72
-#: src/pyams_content/shared/common/zmi/manager.py:97
+#: src/pyams_content/shared/common/__init__.py:240
+#: src/pyams_content/shared/common/zmi/properties.py:70
+#: src/pyams_content/shared/common/zmi/manager.py:96
msgid "Properties"
msgstr "Propriétés"
-#: src/pyams_content/shared/common/__init__.py:147
-#: src/pyams_content/shared/common/__init__.py:155
+#: src/pyams_content/shared/common/__init__.py:150
+#: src/pyams_content/shared/common/__init__.py:158
#, python-format
msgid "{date} by {principal}"
msgstr "{date} par {principal}"
-#: src/pyams_content/shared/common/__init__.py:260
+#: src/pyams_content/shared/common/__init__.py:263
#, python-format
msgid "title length should be between 40 and 66 characters ({length} actually)"
msgstr ""
@@ -1799,11 +1838,11 @@
msgid "Modified before..."
msgstr "et le"
-#: src/pyams_content/shared/common/zmi/properties.py:62
+#: src/pyams_content/shared/common/zmi/properties.py:60
msgid "Composition"
msgstr "Composition"
-#: src/pyams_content/shared/common/zmi/properties.py:83
+#: src/pyams_content/shared/common/zmi/properties.py:82
msgid "Content properties"
msgstr "Propriétés élémentaires"
@@ -1815,40 +1854,40 @@
msgid "Data type label"
msgstr "Libellé du type"
-#: src/pyams_content/shared/common/zmi/types.py:183
-#: src/pyams_content/shared/common/zmi/types.py:411
+#: src/pyams_content/shared/common/zmi/types.py:185
+#: src/pyams_content/shared/common/zmi/types.py:396
msgid "Default associations"
msgstr "Liens et pièces jointes par défaut"
-#: src/pyams_content/shared/common/zmi/types.py:211
+#: src/pyams_content/shared/common/zmi/types.py:213
msgid "Content data types"
msgstr "Types de contenus"
-#: src/pyams_content/shared/common/zmi/types.py:234
+#: src/pyams_content/shared/common/zmi/types.py:236
msgid "Add data type"
msgstr "Ajouter un type"
-#: src/pyams_content/shared/common/zmi/types.py:245
+#: src/pyams_content/shared/common/zmi/types.py:248
msgid "Add new data type"
msgstr "Ajout d'un type de contenu"
-#: src/pyams_content/shared/common/zmi/types.py:291
+#: src/pyams_content/shared/common/zmi/types.py:285
msgid "Data type properties"
msgstr "Propriétés du type de contenu"
-#: src/pyams_content/shared/common/zmi/types.py:374
+#: src/pyams_content/shared/common/zmi/types.py:359
msgid "Subtype label"
msgstr "Libellé du sous-type"
-#: src/pyams_content/shared/common/zmi/types.py:455
+#: src/pyams_content/shared/common/zmi/types.py:440
msgid "Add subtype"
msgstr "Ajouter un sous-type"
-#: src/pyams_content/shared/common/zmi/types.py:466
+#: src/pyams_content/shared/common/zmi/types.py:452
msgid "Add new subtype"
msgstr "Ajout d'un sous-type de contenu"
-#: src/pyams_content/shared/common/zmi/types.py:518
+#: src/pyams_content/shared/common/zmi/types.py:498
msgid "Data subtype properties"
msgstr "Propriétés du fichier standard"
@@ -1856,70 +1895,70 @@
msgid "No currently defined data type."
msgstr "Aucun type de contenu n'est actuellement défini."
-#: src/pyams_content/shared/common/zmi/types.py:273
+#: src/pyams_content/shared/common/zmi/types.py:275
msgid "Specified type name is already used!"
msgstr "Le nom indiqué pour ce type de contenu est déjà utilisé !"
-#: src/pyams_content/shared/common/zmi/types.py:494
-msgid "Specified subtype name is already used!"
-msgstr "Le nom indiqué pour ce sous-type de contenu est déjà utilisé !"
-
-#: src/pyams_content/shared/common/zmi/types.py:505
+#: src/pyams_content/shared/common/zmi/types.py:474
msgid "Subtype was correctly added."
msgstr "Le sous-type a été ajouté."
-#: src/pyams_content/shared/common/zmi/types.py:155
+#: src/pyams_content/shared/common/zmi/types.py:488
+msgid "Specified subtype name is already used!"
+msgstr "Le nom indiqué pour ce sous-type de contenu est déjà utilisé !"
+
+#: src/pyams_content/shared/common/zmi/types.py:157
msgid "Click to see subtypes"
msgstr "Montrer ou caher les sous-types"
-#: src/pyams_content/shared/common/zmi/workflow.py:907
+#: src/pyams_content/shared/common/zmi/workflow.py:844
msgid "Prior checks"
msgstr "Contrôles préalables : avez-vous ?"
-#: src/pyams_content/shared/common/zmi/workflow.py:126
+#: src/pyams_content/shared/common/zmi/workflow.py:123
msgid "Request publication"
msgstr "Demander la publication"
-#: src/pyams_content/shared/common/zmi/workflow.py:218
+#: src/pyams_content/shared/common/zmi/workflow.py:210
#: src/pyams_content/workflow/__init__.py:315
msgid "Cancel publication request"
msgstr "Annuler la demande de publication"
-#: src/pyams_content/shared/common/zmi/workflow.py:263
+#: src/pyams_content/shared/common/zmi/workflow.py:250
msgid "Refuse publication request"
msgstr "Refuser la demande de publication"
-#: src/pyams_content/shared/common/zmi/workflow.py:322
+#: src/pyams_content/shared/common/zmi/workflow.py:304
#: src/pyams_content/workflow/basic.py:196
msgid "Publish"
msgstr "Publier"
-#: src/pyams_content/shared/common/zmi/workflow.py:416
+#: src/pyams_content/shared/common/zmi/workflow.py:393
msgid "Request retire"
msgstr "Demander le retrait"
-#: src/pyams_content/shared/common/zmi/workflow.py:477
+#: src/pyams_content/shared/common/zmi/workflow.py:449
msgid "Cancel retire request"
msgstr "Annuler la demande de retrait"
-#: src/pyams_content/shared/common/zmi/workflow.py:522
+#: src/pyams_content/shared/common/zmi/workflow.py:489
msgid "Retire"
msgstr "Retirer"
-#: src/pyams_content/shared/common/zmi/workflow.py:568
+#: src/pyams_content/shared/common/zmi/workflow.py:530
#: src/pyams_content/workflow/__init__.py:436
msgid "Request archive"
msgstr "Demander l'archivage"
-#: src/pyams_content/shared/common/zmi/workflow.py:616
+#: src/pyams_content/shared/common/zmi/workflow.py:573
msgid "Cancel archive request"
msgstr "Annuler la demande d'archivage"
-#: src/pyams_content/shared/common/zmi/workflow.py:661
+#: src/pyams_content/shared/common/zmi/workflow.py:613
msgid "Archive"
msgstr "Archiver"
-#: src/pyams_content/shared/common/zmi/workflow.py:707
+#: src/pyams_content/shared/common/zmi/workflow.py:654
#: src/pyams_content/workflow/__init__.py:501
#: src/pyams_content/workflow/__init__.py:513
#: src/pyams_content/workflow/__init__.py:525
@@ -1930,39 +1969,39 @@
msgid "Create new version"
msgstr "Créer une nouvelle version"
-#: src/pyams_content/shared/common/zmi/workflow.py:763
+#: src/pyams_content/shared/common/zmi/workflow.py:705
#: src/pyams_content/workflow/__init__.py:561
#: src/pyams_content/workflow/basic.py:248
msgid "Delete version"
msgstr "Supprimer cette version"
-#: src/pyams_content/shared/common/zmi/workflow.py:853
+#: src/pyams_content/shared/common/zmi/workflow.py:790
msgid "Previewed content?"
msgstr "Prévisualisé ce contenu ?"
-#: src/pyams_content/shared/common/zmi/workflow.py:857
+#: src/pyams_content/shared/common/zmi/workflow.py:794
msgid "Verified content?"
msgstr "Audité ce contenu ?"
-#: src/pyams_content/shared/common/zmi/workflow.py:188
-#: src/pyams_content/shared/common/zmi/workflow.py:385
+#: src/pyams_content/shared/common/zmi/workflow.py:180
+#: src/pyams_content/shared/common/zmi/workflow.py:362
msgid "Publication start date is required"
msgstr "La date de début de publication est obligatoire"
-#: src/pyams_content/shared/common/zmi/workflow.py:291
-#: src/pyams_content/shared/common/zmi/workflow.py:447
+#: src/pyams_content/shared/common/zmi/workflow.py:273
+#: src/pyams_content/shared/common/zmi/workflow.py:419
msgid "A comment is required"
msgstr "Le commentaire est obligatoire"
-#: src/pyams_content/shared/common/zmi/workflow.py:786
+#: src/pyams_content/shared/common/zmi/workflow.py:729
msgid "Delete content"
msgstr "Supprimer définitivement ce contenu"
-#: src/pyams_content/shared/common/zmi/workflow.py:795
+#: src/pyams_content/shared/common/zmi/workflow.py:738
msgid "Delete definitively"
msgstr "Supprimer définitivement"
-#: src/pyams_content/shared/common/zmi/workflow.py:923
+#: src/pyams_content/shared/common/zmi/workflow.py:860
msgid ""
"You must confirm that you previewed and checked this content before "
"requesting publication!!"
@@ -1970,12 +2009,12 @@
"Vous devez avoir prévisualisé et audité ce contenu avant de pouvoir le "
"publier !!"
-#: src/pyams_content/shared/common/zmi/workflow.py:90
+#: src/pyams_content/shared/common/zmi/workflow.py:87
#, python-format
msgid "{state} | by {principal}"
msgstr "{state} | par {principal}"
-#: src/pyams_content/shared/common/zmi/workflow.py:86
+#: src/pyams_content/shared/common/zmi/workflow.py:83
#: src/pyams_content/workflow/__init__.py:648
#: src/pyams_content/workflow/__init__.py:619
#: src/pyams_content/workflow/basic.py:315
@@ -1984,7 +2023,7 @@
msgid "{state} {date}"
msgstr "{state} {date}"
-#: src/pyams_content/shared/common/zmi/__init__.py:266
+#: src/pyams_content/shared/common/zmi/__init__.py:265
msgid "Duplicate content..."
msgstr "Dupliquer le contenu"
@@ -1992,22 +2031,22 @@
msgid "Duplicate content"
msgstr "Dupliquer ce contenu"
-#: src/pyams_content/shared/common/zmi/__init__.py:85
+#: src/pyams_content/shared/common/zmi/__init__.py:84
msgid "This title can be modified afterwards"
msgstr "Pourra être modifié ultérieurement"
-#: src/pyams_content/shared/common/zmi/__init__.py:277
+#: src/pyams_content/shared/common/zmi/__init__.py:276
msgid "Duplicate this content"
msgstr "Dupliquer ce contenu"
-#: src/pyams_content/shared/common/zmi/__init__.py:338
+#: src/pyams_content/shared/common/zmi/__init__.py:337
#, python-format
msgid "Clone created from version {source} of {oid} (in « {state} » state)"
msgstr ""
"Duplication de la version {source} du contenu {oid} (alors en statut "
"« {state} »)"
-#: src/pyams_content/shared/common/zmi/__init__.py:389
+#: src/pyams_content/shared/common/zmi/__init__.py:382
msgid "Created or modified in this version"
msgstr "Créé ou modifié dans cette version"
@@ -2058,11 +2097,11 @@
msgid "Shared tool properties"
msgstr "Propriétés de l'outil"
-#: src/pyams_content/shared/common/zmi/manager.py:132
+#: src/pyams_content/shared/common/zmi/manager.py:125
msgid "WARNING"
msgstr "ATTENTION"
-#: src/pyams_content/shared/common/zmi/manager.py:134
+#: src/pyams_content/shared/common/zmi/manager.py:127
msgid ""
"Workflow shouldn't be modified if this tool already contains any shared "
"content!"
@@ -2070,15 +2109,15 @@
"Le workflow ne doit pas être modifié si cet outil renferme déjà des contenus "
"partagés !"
-#: src/pyams_content/shared/common/zmi/manager.py:157
+#: src/pyams_content/shared/common/zmi/manager.py:150
msgid "Languages"
msgstr "Langues"
-#: src/pyams_content/shared/common/zmi/manager.py:168
+#: src/pyams_content/shared/common/zmi/manager.py:162
msgid "Content languages"
msgstr "Langues pour la traduction de cet outil"
-#: src/pyams_content/shared/common/zmi/manager.py:185
+#: src/pyams_content/shared/common/zmi/manager.py:172
msgid ""
"Tool languages are used to translate own tool properties, and newly created "
"contents will propose these languages by default"
@@ -2087,15 +2126,15 @@
"\n"
"Les nouveaux contenus proposeront également ces langues par défaut."
-#: src/pyams_content/shared/common/zmi/manager.py:81
+#: src/pyams_content/shared/common/zmi/manager.py:80
msgid "Content management"
msgstr "Gérer ce gabarit"
-#: src/pyams_content/shared/common/zmi/manager.py:83
+#: src/pyams_content/shared/common/zmi/manager.py:82
msgid "Tool management"
-msgstr "Gérer l'outil partagé"
-
-#: src/pyams_content/shared/common/zmi/owner.py:51
+msgstr "Gérer cet outil"
+
+#: src/pyams_content/shared/common/zmi/owner.py:50
msgid "Change owner..."
msgstr "Changer de propriétaire"
@@ -2103,7 +2142,7 @@
msgid "Change content's owner"
msgstr "Changement de propriétaire"
-#: src/pyams_content/shared/common/zmi/owner.py:132
+#: src/pyams_content/shared/common/zmi/owner.py:125
msgid ""
"All versions of this content which are not archived will be transferred to "
"newly selected owner"
@@ -2111,28 +2150,48 @@
"Toutes les versions non archivées de ce contenu seront transférées au "
"nouveau propriétaire sélectionné"
-#: src/pyams_content/shared/common/zmi/owner.py:61
+#: src/pyams_content/shared/common/zmi/owner.py:60
msgid "New owner"
msgstr "Nouveau propriétaire"
-#: src/pyams_content/shared/common/zmi/owner.py:62
+#: src/pyams_content/shared/common/zmi/owner.py:61
msgid "The selected user will become the new content's owner"
msgstr "L'utilisateur sélectionné deviendra le nouveau propriétaire du contenu"
-#: src/pyams_content/shared/common/zmi/owner.py:64
+#: src/pyams_content/shared/common/zmi/owner.py:63
msgid "Keep previous owner as contributor"
msgstr "L'ancien propriétaire reste contributeur"
-#: src/pyams_content/shared/common/zmi/owner.py:65
+#: src/pyams_content/shared/common/zmi/owner.py:64
msgid "If 'yes', the previous owner will still be able to modify this content"
msgstr ""
"Si 'oui', l'actuel propriétaire du contenu en restera contributeur et pourra "
"donc continuer à le mettre à jour"
-#: src/pyams_content/shared/common/zmi/owner.py:75
+#: src/pyams_content/shared/common/zmi/owner.py:74
msgid "Change owner"
msgstr "Changer le propriétaire"
+#: src/pyams_content/shared/common/zmi/rename.py:62
+msgid "Change URL..."
+msgstr "Changer d'URL"
+
+#: src/pyams_content/shared/common/zmi/rename.py:79
+msgid "Change item URL"
+msgstr "Modification de l'URL"
+
+#: src/pyams_content/shared/common/zmi/rename.py:86
+msgid "Item URL part"
+msgstr "URL du contenu"
+
+#: src/pyams_content/shared/common/zmi/rename.py:87
+msgid "URL part used to access this content"
+msgstr "Portion de l'URL utilisée pour accéder à ce contenu"
+
+#: src/pyams_content/shared/common/zmi/rename.py:121
+msgid "You must provide an URL for this item!"
+msgstr "Vous devez fournir une URL pour ce contenu !"
+
#: src/pyams_content/shared/common/zmi/site.py:38
#, python-format
msgid ""
@@ -2141,6 +2200,37 @@
"RECHERCHE - Tous contenus présents dans « {site} » "
"confondus"
+#: src/pyams_content/shared/common/zmi/portal.py:46
+msgid "Edit default template properties"
+msgstr "Modèle de présentation par défaut"
+
+#: src/pyams_content/shared/common/zmi/portal.py:56
+msgid ""
+"**This form allows you to select shared content default template.**\n"
+"\n"
+"If you choose to use a shared template, you can only adjust settings of each "
+"portlet individually but can't change portlets list or page configuration.\n"
+"\n"
+"If you use a local template, you can define a whole custom configuration but "
+"the template definition can't be reused anywhere..."
+msgstr ""
+"Vous pouvez modifier le modèle de présentation qui sera appliqué **par "
+"défaut** à tous les contenus de ce gabarit.\n"
+"\n"
+"Si vous choisissez d'utiliser un modèle de présentation partagé, vous "
+"pourrez ajuster les paramètres de chaque composant mais ne pourrez pas "
+"modifier la liste des composants ou leur position et la configuration de la "
+"page.\n"
+"\n"
+"Si vous choisissez d'utiliser un modèle de présentation \"local\", vous "
+"pourrez définir l'ensemble de la configuration mais le modèle de "
+"présentation ne pourra pas être réutilisé ailleurs que dans les contenus de "
+"ce gabarit."
+
+#: src/pyams_content/shared/common/zmi/portal.py:72
+msgid "Override tool default template"
+msgstr "Ne pas utiliser le modèle par défaut de ce gabarit"
+
#: src/pyams_content/shared/common/zmi/dashboard.py:134
msgid "Unique ID"
msgstr "N° IN"
@@ -2158,7 +2248,7 @@
msgstr "Dernière modification"
#: src/pyams_content/shared/common/zmi/dashboard.py:273
-#: src/pyams_content/root/zmi/__init__.py:91
+#: src/pyams_content/root/zmi/__init__.py:110
msgid "Dashboard"
msgstr "Tableau de bord"
@@ -2167,55 +2257,55 @@
msgstr "Mon tableau de bord"
#: src/pyams_content/shared/common/zmi/dashboard.py:329
-#: src/pyams_content/root/zmi/__init__.py:140
+#: src/pyams_content/root/zmi/__init__.py:159
#, python-format
msgid "MANAGER - {0} content waiting for your action"
msgstr "RESPONSABLE - {0} contenu en attente de votre intervention"
#: src/pyams_content/shared/common/zmi/dashboard.py:330
-#: src/pyams_content/root/zmi/__init__.py:141
+#: src/pyams_content/root/zmi/__init__.py:160
#, python-format
msgid "MANAGER - {0} contents waiting for your action"
msgstr "RESPONSABLE - {0} contenus en attente de votre intervention"
#: src/pyams_content/shared/common/zmi/dashboard.py:370
-#: src/pyams_content/root/zmi/__init__.py:184
+#: src/pyams_content/root/zmi/__init__.py:203
#, python-format
msgid "CONTRIBUTOR - {0} content waiting for action"
msgstr "CONTRIBUTEUR - {0} contenu soumis à un responsable"
#: src/pyams_content/shared/common/zmi/dashboard.py:371
-#: src/pyams_content/root/zmi/__init__.py:185
+#: src/pyams_content/root/zmi/__init__.py:204
#, python-format
msgid "CONTRIBUTOR - {0} contents waiting for action"
msgstr "CONTRIBUTEUR - {0} contenus soumis à un responsable"
#: src/pyams_content/shared/common/zmi/dashboard.py:402
-#: src/pyams_content/root/zmi/__init__.py:219
+#: src/pyams_content/root/zmi/__init__.py:238
#, python-format
msgid "CONTRIBUTOR - {0} modified content"
msgstr "CONTRIBUTEUR - {0} contenu modifié"
#: src/pyams_content/shared/common/zmi/dashboard.py:443
-#: src/pyams_content/root/zmi/__init__.py:262
+#: src/pyams_content/root/zmi/__init__.py:281
msgid "My contents"
msgstr "Mes contenus"
#: src/pyams_content/shared/common/zmi/dashboard.py:458
#: src/pyams_content/shared/common/zmi/templates/dashboard.pt:8
-#: src/pyams_content/root/zmi/__init__.py:277
+#: src/pyams_content/root/zmi/__init__.py:296
#: src/pyams_content/root/zmi/templates/dashboard.pt:8
msgid "My favorites"
msgstr "Mes favoris"
#: src/pyams_content/shared/common/zmi/dashboard.py:467
-#: src/pyams_content/root/zmi/__init__.py:286
+#: src/pyams_content/root/zmi/__init__.py:305
#, python-format
msgid "CONTRIBUTOR - {0} favorite"
msgstr "CONTRIBUTEUR - {0} contenu favori"
#: src/pyams_content/shared/common/zmi/dashboard.py:468
-#: src/pyams_content/root/zmi/__init__.py:287
+#: src/pyams_content/root/zmi/__init__.py:306
#, python-format
msgid "CONTRIBUTOR - {0} favorites"
msgstr "CONTRIBUTEUR - {0} contenus favoris"
@@ -2226,188 +2316,188 @@
msgstr "Ajouter/enlever des favoris"
#: src/pyams_content/shared/common/zmi/dashboard.py:543
-#: src/pyams_content/root/zmi/__init__.py:325
+#: src/pyams_content/root/zmi/__init__.py:344
msgid "Your favorites"
msgstr "Mes favoris"
#: src/pyams_content/shared/common/zmi/dashboard.py:556
-#: src/pyams_content/root/zmi/__init__.py:338
+#: src/pyams_content/root/zmi/__init__.py:357
msgid "My preparations"
msgstr "Mes préparations"
#: src/pyams_content/shared/common/zmi/dashboard.py:565
-#: src/pyams_content/root/zmi/__init__.py:347
+#: src/pyams_content/root/zmi/__init__.py:366
#, python-format
msgid "CONTRIBUTOR - {0} prepared content"
msgstr "CONTRIBUTEUR - {0} contenu en préparation"
#: src/pyams_content/shared/common/zmi/dashboard.py:566
-#: src/pyams_content/root/zmi/__init__.py:348
+#: src/pyams_content/root/zmi/__init__.py:367
#, python-format
msgid "CONTRIBUTOR - {0} prepared contents"
msgstr "CONTRIBUTEUR - {0} contenus en préparation"
#: src/pyams_content/shared/common/zmi/dashboard.py:605
-#: src/pyams_content/root/zmi/__init__.py:386
+#: src/pyams_content/root/zmi/__init__.py:405
msgid "Your prepared contents"
msgstr "Mes contenus en préparation"
#: src/pyams_content/shared/common/zmi/dashboard.py:618
-#: src/pyams_content/root/zmi/__init__.py:399
+#: src/pyams_content/root/zmi/__init__.py:418
msgid "My submissions"
msgstr "Mes demandes"
#: src/pyams_content/shared/common/zmi/dashboard.py:627
-#: src/pyams_content/root/zmi/__init__.py:408
+#: src/pyams_content/root/zmi/__init__.py:427
#, python-format
msgid "CONTRIBUTOR - {0} submitted content"
msgstr "CONTRIBUTEUR - {0} contenu soumis à un responsable"
#: src/pyams_content/shared/common/zmi/dashboard.py:628
-#: src/pyams_content/root/zmi/__init__.py:409
+#: src/pyams_content/root/zmi/__init__.py:428
#, python-format
msgid "CONTRIBUTOR - {0} submitted contents"
msgstr "CONTRIBUTEUR - {0} contenus soumis à un responsable"
#: src/pyams_content/shared/common/zmi/dashboard.py:667
-#: src/pyams_content/root/zmi/__init__.py:447
+#: src/pyams_content/root/zmi/__init__.py:466
msgid "Your submitted contents"
msgstr "Mes contenus soumis à un responsable"
#: src/pyams_content/shared/common/zmi/dashboard.py:680
-#: src/pyams_content/root/zmi/__init__.py:460
+#: src/pyams_content/root/zmi/__init__.py:479
msgid "My publications"
msgstr "Mes publications"
#: src/pyams_content/shared/common/zmi/dashboard.py:689
-#: src/pyams_content/root/zmi/__init__.py:469
+#: src/pyams_content/root/zmi/__init__.py:488
#, python-format
msgid "CONTRIBUTOR - {0} published content"
msgstr "CONTRIBUTEUR - {0} contenu publié"
#: src/pyams_content/shared/common/zmi/dashboard.py:690
-#: src/pyams_content/root/zmi/__init__.py:470
+#: src/pyams_content/root/zmi/__init__.py:489
#, python-format
msgid "CONTRIBUTOR - {0} published contents"
msgstr "CONTRIBUTEUR - {0} contenus publiés"
#: src/pyams_content/shared/common/zmi/dashboard.py:729
-#: src/pyams_content/root/zmi/__init__.py:508
+#: src/pyams_content/root/zmi/__init__.py:527
msgid "Your published contents"
msgstr "Mes contenus publiés"
#: src/pyams_content/shared/common/zmi/dashboard.py:742
-#: src/pyams_content/root/zmi/__init__.py:521
+#: src/pyams_content/root/zmi/__init__.py:540
msgid "My retired contents"
msgstr "Mes contenus retirés"
#: src/pyams_content/shared/common/zmi/dashboard.py:751
-#: src/pyams_content/root/zmi/__init__.py:530
+#: src/pyams_content/root/zmi/__init__.py:549
#, python-format
msgid "CONTRIBUTOR - {0} retired content"
msgstr "CONTRIBUTEUR - {0} contenu retiré"
#: src/pyams_content/shared/common/zmi/dashboard.py:752
-#: src/pyams_content/root/zmi/__init__.py:531
+#: src/pyams_content/root/zmi/__init__.py:550
#, python-format
msgid "CONTRIBUTOR - {0} retired contents"
msgstr "CONTRIBUTEUR - {0} contenus retirés"
#: src/pyams_content/shared/common/zmi/dashboard.py:792
-#: src/pyams_content/root/zmi/__init__.py:570
+#: src/pyams_content/root/zmi/__init__.py:589
msgid "Your retired contents"
msgstr "Mes contenus retirés"
#: src/pyams_content/shared/common/zmi/dashboard.py:805
-#: src/pyams_content/root/zmi/__init__.py:583
+#: src/pyams_content/root/zmi/__init__.py:602
msgid "My archived contents"
msgstr "Mes contenus archivés"
#: src/pyams_content/shared/common/zmi/dashboard.py:814
-#: src/pyams_content/root/zmi/__init__.py:592
+#: src/pyams_content/root/zmi/__init__.py:611
#, python-format
msgid "CONTRIBUTOR - {0} archived content"
msgstr "CONTRIBUTEUR - {0} contenu archivé"
#: src/pyams_content/shared/common/zmi/dashboard.py:815
-#: src/pyams_content/root/zmi/__init__.py:593
+#: src/pyams_content/root/zmi/__init__.py:612
#, python-format
msgid "CONTRIBUTOR - {0} archived contents"
msgstr "CONTRIBUTEUR - {0} contenus archivés"
#: src/pyams_content/shared/common/zmi/dashboard.py:861
-#: src/pyams_content/root/zmi/__init__.py:638
+#: src/pyams_content/root/zmi/__init__.py:657
msgid "Your archived contents"
msgstr "Mes contenus archivés"
#: src/pyams_content/shared/common/zmi/dashboard.py:875
-#: src/pyams_content/root/zmi/__init__.py:652
+#: src/pyams_content/root/zmi/__init__.py:671
msgid "Other interventions"
msgstr "Toutes les interventions"
#: src/pyams_content/shared/common/zmi/dashboard.py:890
-#: src/pyams_content/root/zmi/__init__.py:667
+#: src/pyams_content/root/zmi/__init__.py:686
msgid "Last publications"
msgstr "Dernières publications"
#: src/pyams_content/shared/common/zmi/dashboard.py:899
-#: src/pyams_content/root/zmi/__init__.py:676
+#: src/pyams_content/root/zmi/__init__.py:695
#, python-format
msgid "CONTRIBUTORS - {0} published content"
msgstr "TOUS CONTRIBUTEURS - {0} contenu publié"
#: src/pyams_content/shared/common/zmi/dashboard.py:945
-#: src/pyams_content/root/zmi/__init__.py:721
+#: src/pyams_content/root/zmi/__init__.py:740
msgid "Last published contents"
msgstr "Derniers contenus publiés"
#: src/pyams_content/shared/common/zmi/dashboard.py:958
-#: src/pyams_content/root/zmi/__init__.py:734
+#: src/pyams_content/root/zmi/__init__.py:753
msgid "Last updates"
msgstr "Dernières modifications"
#: src/pyams_content/shared/common/zmi/dashboard.py:967
-#: src/pyams_content/root/zmi/__init__.py:743
+#: src/pyams_content/root/zmi/__init__.py:762
#, python-format
msgid "CONTRIBUTORS - {0} updated content"
msgstr "TOUS CONTRIBUTEURS - {0} contenu modifié"
#: src/pyams_content/shared/common/zmi/dashboard.py:1012
-#: src/pyams_content/root/zmi/__init__.py:787
+#: src/pyams_content/root/zmi/__init__.py:806
msgid "Last updated contents"
msgstr "Derniers contenus modifiés"
#: src/pyams_content/shared/common/zmi/dashboard.py:407
-#: src/pyams_content/root/zmi/__init__.py:224
+#: src/pyams_content/root/zmi/__init__.py:243
#, python-format
msgid "CONTRIBUTOR - {0} modified contents"
msgstr "CONTRIBUTEUR - {0} contenus modifiés"
#: src/pyams_content/shared/common/zmi/dashboard.py:409
-#: src/pyams_content/root/zmi/__init__.py:226
+#: src/pyams_content/root/zmi/__init__.py:245
#, python-format
msgid "CONTRIBUTOR - Last {0} modified contents"
msgstr "CONTRIBUTEUR - Les {0} dernières modifications"
#: src/pyams_content/shared/common/zmi/dashboard.py:904
-#: src/pyams_content/root/zmi/__init__.py:681
+#: src/pyams_content/root/zmi/__init__.py:700
#, python-format
msgid "CONTRIBUTORS - Last {0} published contents"
msgstr "TOUS CONTRIBUTEURS - Les {0} dernières publications"
#: src/pyams_content/shared/common/zmi/dashboard.py:906
-#: src/pyams_content/root/zmi/__init__.py:683
+#: src/pyams_content/root/zmi/__init__.py:702
msgid "CONTRIBUTORS - Last published contents (in the limit of 50)"
msgstr "TOUS CONTRIBUTEURS - Les {0} dernières publications"
#: src/pyams_content/shared/common/zmi/dashboard.py:972
-#: src/pyams_content/root/zmi/__init__.py:748
+#: src/pyams_content/root/zmi/__init__.py:767
#, python-format
msgid "CONTRIBUTORS - Last {0} updated contents"
msgstr "TOUS CONTRIBUTEURS - Les {0} dernières modifications"
#: src/pyams_content/shared/common/zmi/dashboard.py:974
-#: src/pyams_content/root/zmi/__init__.py:750
+#: src/pyams_content/root/zmi/__init__.py:769
msgid "CONTRIBUTORS - Last updated contents (in the limit of 50)"
msgstr "TOUS CONTRIBUTEURS - Les {0} dernières modifications"
@@ -2421,64 +2511,62 @@
msgid "Content publication start date is not passed yet"
msgstr "La date de début de publication n'est pas encore atteinte"
-#: src/pyams_content/shared/common/zmi/security.py:65
+#: src/pyams_content/shared/common/zmi/security.py:64
msgid "Contributors restrictions"
msgstr "Paramètres des contributeurs"
-#: src/pyams_content/shared/common/zmi/security.py:74
+#: src/pyams_content/shared/common/zmi/security.py:73
msgid "Content contributors restrictions"
msgstr "Liste des contributeurs"
-#: src/pyams_content/shared/common/zmi/security.py:108
+#: src/pyams_content/shared/common/zmi/security.py:107
msgid "Contributor name"
msgstr "Nom du contributeur"
-#: src/pyams_content/shared/common/zmi/security.py:119
-#: src/pyams_content/shared/common/zmi/security.py:277
-#: src/pyams_content/shared/common/interfaces/__init__.py:252
-#: src/pyams_content/shared/common/interfaces/__init__.py:277
-msgid "Publication checks"
-msgstr "Activer le tunnel de publication"
-
-#: src/pyams_content/shared/common/zmi/security.py:225
+#: src/pyams_content/shared/common/zmi/security.py:118
+#: src/pyams_content/shared/common/zmi/security.py:270
+msgid "Activated publication checks?"
+msgstr "Tunnel de publication actif ?"
+
+#: src/pyams_content/shared/common/zmi/security.py:218
msgid "Managers restrictions"
msgstr "Paramètres des responsables"
-#: src/pyams_content/shared/common/zmi/security.py:234
+#: src/pyams_content/shared/common/zmi/security.py:227
msgid "Content managers restrictions"
msgstr "Liste des responsables"
-#: src/pyams_content/shared/common/zmi/security.py:266
+#: src/pyams_content/shared/common/zmi/security.py:259
msgid "Manager name"
msgstr "Nom du responsable"
-#: src/pyams_content/shared/common/zmi/security.py:294
+#: src/pyams_content/shared/common/zmi/security.py:287
msgid "Restricted"
msgstr "Restrictions"
-#: src/pyams_content/shared/common/zmi/security.py:311
+#: src/pyams_content/shared/common/zmi/security.py:304
msgid "Owners"
msgstr "Propriétaires"
-#: src/pyams_content/shared/common/zmi/security.py:401
+#: src/pyams_content/shared/common/zmi/security.py:394
msgid "Publication workflow"
msgstr "Workflow de publication"
-#: src/pyams_content/shared/common/zmi/security.py:168
+#: src/pyams_content/shared/common/zmi/security.py:167
#, python-format
msgid "Edit contributor restrictions for « {0} »"
msgstr "Gérer les paramètres d'intervention de « {0} »"
-#: src/pyams_content/shared/common/zmi/security.py:360
+#: src/pyams_content/shared/common/zmi/security.py:353
#, python-format
msgid "Edit manager restrictions for « {0} »"
msgstr "Gérer les paramètres d'intervention de « {0} »"
-#: src/pyams_content/shared/common/zmi/security.py:407
+#: src/pyams_content/shared/common/zmi/security.py:400
msgid "Apply contents restrictions"
msgstr "Appliquer des restrictions d'accès"
-#: src/pyams_content/shared/common/zmi/security.py:409
+#: src/pyams_content/shared/common/zmi/security.py:402
msgid ""
"You can specify which contents this manager will be able to manage. If you "
"specify several criteria, the manager will be able to manage contents for "
@@ -2559,9 +2647,10 @@
#: src/pyams_content/shared/common/zmi/templates/check-input.pt:34
#: src/pyams_content/shared/common/zmi/templates/preview-input.pt:34
-#: src/pyams_content/shared/common/interfaces/types.py:39
+#: src/pyams_content/shared/common/interfaces/types.py:40
#: src/pyams_content/shared/form/zmi/field.py:159
-#: src/pyams_content/shared/form/interfaces/__init__.py:61
+#: src/pyams_content/shared/form/interfaces/__init__.py:62
+#: src/pyams_content/features/menu/zmi/__init__.py:208
msgid "Label"
msgstr "Libellé"
@@ -2570,18 +2659,18 @@
msgid "Audit"
msgstr "Audit"
-#: src/pyams_content/shared/common/zmi/templates/dashboard.pt:28
-#: src/pyams_content/root/zmi/templates/dashboard.pt:28
+#: src/pyams_content/shared/common/zmi/templates/dashboard.pt:29
+#: src/pyams_content/root/zmi/templates/dashboard.pt:29
msgid "Quick search..."
msgstr "Recherche rapide..."
-#: src/pyams_content/shared/common/zmi/templates/dashboard.pt:33
-#: src/pyams_content/root/zmi/templates/dashboard.pt:33
+#: src/pyams_content/shared/common/zmi/templates/dashboard.pt:35
+#: src/pyams_content/root/zmi/templates/dashboard.pt:35
msgid "Advanced search..."
msgstr "Recherche avancée..."
-#: src/pyams_content/shared/common/zmi/templates/dashboard.pt:46
-#: src/pyams_content/root/zmi/templates/dashboard.pt:46
+#: src/pyams_content/shared/common/zmi/templates/dashboard.pt:49
+#: src/pyams_content/root/zmi/templates/dashboard.pt:49
msgid "You are not actually concerned by any content."
msgstr "Vous n'êtes actuellement concerné par aucun contenu."
@@ -2788,36 +2877,48 @@
msgid "This content is already retired and not visible."
msgstr "Ce contenu est déjà retiré et n'est plus visible des internautes."
-#: src/pyams_content/shared/common/interfaces/types.py:35
+#: src/pyams_content/shared/common/portlet/content/__init__.py:44
+msgid "Context content"
+msgstr "Contenu partagé"
+
+#: src/pyams_content/shared/common/portlet/content/zmi/preview.pt:2
+msgid "This is where the content will be displayed!!"
+msgstr "C'est ici que seront affichés les éléments du contenu."
+
+#: src/pyams_content/shared/common/portlet/content/skin/__init__.py:36
+msgid "Default content renderer"
+msgstr "Par défaut"
+
+#: src/pyams_content/shared/common/interfaces/types.py:36
#: src/pyams_content/shared/form/zmi/field.py:148
msgid "Name"
msgstr "Nom"
-#: src/pyams_content/shared/common/interfaces/types.py:36
+#: src/pyams_content/shared/common/interfaces/types.py:37
msgid "Name of this data type; must be unique between all data types"
msgstr "Nom de ce type de donnée ; doit être unique entre tous les types"
-#: src/pyams_content/shared/common/interfaces/types.py:42
+#: src/pyams_content/shared/common/interfaces/types.py:43
msgid "Navigation label"
msgstr "Libellé de navigation"
-#: src/pyams_content/shared/common/interfaces/types.py:43
+#: src/pyams_content/shared/common/interfaces/types.py:44
msgid "Label used for navigation entries"
msgstr "Libellé utilisé pour les entrées de navigation"
-#: src/pyams_content/shared/common/interfaces/types.py:46
+#: src/pyams_content/shared/common/interfaces/types.py:47
msgid "Tab-folder label"
msgstr "Libellé d'un l'onglet"
-#: src/pyams_content/shared/common/interfaces/types.py:47
+#: src/pyams_content/shared/common/interfaces/types.py:48
msgid "Label used to include into tab folder"
msgstr "Libellé utilisé pour l'affichage du type sous la forme d'un onglet"
-#: src/pyams_content/shared/common/interfaces/types.py:50
+#: src/pyams_content/shared/common/interfaces/types.py:51
msgid "'See also' label"
msgstr "Libellé 'À voir aussi'"
-#: src/pyams_content/shared/common/interfaces/types.py:51
+#: src/pyams_content/shared/common/interfaces/types.py:52
msgid ""
"This label can be used when contents of this type will be displayed in a "
"'See also' entries block"
@@ -2825,47 +2926,47 @@
"Ce libellé peut être utilisé lorsque des contenus de ce type sont affichés "
"sous la forme d'un bloc 'À voir aussi'"
-#: src/pyams_content/shared/common/interfaces/types.py:55
+#: src/pyams_content/shared/common/interfaces/types.py:56
msgid "'Single value' label"
msgstr "Libellé 'Valeur unique'"
-#: src/pyams_content/shared/common/interfaces/types.py:56
+#: src/pyams_content/shared/common/interfaces/types.py:57
msgid "Label given to this type when a single value is displayed"
msgstr "Libellé utilisé pour ce type lorsqu'une seule valeur est affichée"
-#: src/pyams_content/shared/common/interfaces/types.py:59
+#: src/pyams_content/shared/common/interfaces/types.py:60
msgid "'Link to list' label"
msgstr "Libellé 'Lien vers une liste'"
-#: src/pyams_content/shared/common/interfaces/types.py:60
+#: src/pyams_content/shared/common/interfaces/types.py:61
msgid "Label used to display a link to a list of items of this type"
msgstr ""
"Libellé utilisé lorsque l'on crée un lien vers uns liste de contenus de ce "
"type"
-#: src/pyams_content/shared/common/interfaces/types.py:63
+#: src/pyams_content/shared/common/interfaces/types.py:64
msgid "Next content label"
msgstr "Libellé du contenu suivant"
-#: src/pyams_content/shared/common/interfaces/types.py:64
+#: src/pyams_content/shared/common/interfaces/types.py:65
msgid "Label used to announce next date for this type"
msgstr ""
"Libellé utilisé pour afficher la prochaine date d'un événement pour ce type"
-#: src/pyams_content/shared/common/interfaces/types.py:68
+#: src/pyams_content/shared/common/interfaces/types.py:69
msgid "Image associated to this data type"
msgstr "Image associée à ce type"
-#: src/pyams_content/shared/common/interfaces/types.py:81
+#: src/pyams_content/shared/common/interfaces/types.py:82
msgid "Field names"
msgstr "Champs associés"
-#: src/pyams_content/shared/common/interfaces/types.py:82
+#: src/pyams_content/shared/common/interfaces/types.py:83
msgid "List of fields associated with this data type"
msgstr "Liste des champs de saisie associés à ce type"
#: src/pyams_content/shared/common/interfaces/__init__.py:46
-#: src/pyams_content/root/interfaces/__init__.py:40
+#: src/pyams_content/root/interfaces/__init__.py:43
msgid "Webmasters"
msgstr "Webmestres"
@@ -2889,12 +2990,12 @@
"responsables à certains contenus"
#: src/pyams_content/shared/common/interfaces/__init__.py:57
-#: src/pyams_content/shared/common/interfaces/__init__.py:174
+#: src/pyams_content/shared/common/interfaces/__init__.py:187
msgid "Managers"
msgstr "Responsables"
#: src/pyams_content/shared/common/interfaces/__init__.py:58
-#: src/pyams_content/shared/common/interfaces/__init__.py:175
+#: src/pyams_content/shared/common/interfaces/__init__.py:188
msgid ""
"Managers can handle main operations in tool's workflow, like publish or "
"retire contents"
@@ -2904,7 +3005,7 @@
"restrictions qui leur sont imposées"
#: src/pyams_content/shared/common/interfaces/__init__.py:63
-#: src/pyams_content/shared/common/interfaces/__init__.py:180
+#: src/pyams_content/shared/common/interfaces/__init__.py:193
msgid "Contributors"
msgstr "Contributeurs"
@@ -2912,19 +3013,29 @@
msgid "Contributors are users which are allowed to create new contents"
msgstr "Les contributeurs sont autorisés à créer de nouveaux contenus"
-#: src/pyams_content/shared/common/interfaces/__init__.py:90
+#: src/pyams_content/shared/common/interfaces/__init__.py:68
+#: src/pyams_content/shared/common/interfaces/__init__.py:199
+msgid "Designers"
+msgstr "Designers"
+
+#: src/pyams_content/shared/common/interfaces/__init__.py:69
+#: src/pyams_content/shared/common/interfaces/__init__.py:200
+msgid "Designers are users which are allowed to manage presentation templates"
+msgstr "Les designers sont autorisés à configurer les modèles de présentation"
+
+#: src/pyams_content/shared/common/interfaces/__init__.py:95
msgid "Workflow name"
msgstr "Nom du workflow"
-#: src/pyams_content/shared/common/interfaces/__init__.py:91
+#: src/pyams_content/shared/common/interfaces/__init__.py:96
msgid "Name of workflow utility used to manage tool contents"
msgstr "Nom du workflow qui gère le cycle de vie des contenus de cet outil"
-#: src/pyams_content/shared/common/interfaces/__init__.py:115
+#: src/pyams_content/shared/common/interfaces/__init__.py:124
msgid "Content URL"
msgstr "URL du contenu"
-#: src/pyams_content/shared/common/interfaces/__init__.py:116
+#: src/pyams_content/shared/common/interfaces/__init__.py:125
msgid ""
"URL used to access this content; this is important for SEO and should "
"include most important words describing content; spaces and underscores will "
@@ -2938,11 +3049,11 @@
"d'union, les lettres accentuées par leur équivalent sans accent, et les mots "
"de moins de trois lettres sont supprimés."
-#: src/pyams_content/shared/common/interfaces/__init__.py:121
+#: src/pyams_content/shared/common/interfaces/__init__.py:130
msgid "Version creator"
msgstr "À l'origine de cette version"
-#: src/pyams_content/shared/common/interfaces/__init__.py:122
+#: src/pyams_content/shared/common/interfaces/__init__.py:131
msgid ""
"Name of content's version creator. The creator of the first version is also "
"it's owner."
@@ -2950,39 +3061,39 @@
"Nom du créateur de cette version. Le créateur de la première version d'un "
"contenu est aussi son propriétaire."
-#: src/pyams_content/shared/common/interfaces/__init__.py:126
+#: src/pyams_content/shared/common/interfaces/__init__.py:135
msgid "First owner"
msgstr "Premier propriétaire"
-#: src/pyams_content/shared/common/interfaces/__init__.py:127
+#: src/pyams_content/shared/common/interfaces/__init__.py:136
msgid "Name of content's first version owner"
msgstr "Nom de l'utilisateur ayant créé la première version"
-#: src/pyams_content/shared/common/interfaces/__init__.py:131
+#: src/pyams_content/shared/common/interfaces/__init__.py:140
msgid "Version creation"
msgstr "Date de création"
-#: src/pyams_content/shared/common/interfaces/__init__.py:134
+#: src/pyams_content/shared/common/interfaces/__init__.py:143
msgid "Version modifiers"
msgstr "Intervenants"
-#: src/pyams_content/shared/common/interfaces/__init__.py:135
+#: src/pyams_content/shared/common/interfaces/__init__.py:144
msgid "List of principals who modified this content"
msgstr "Liste des utilisateurs qui sont intervenus sur cette version"
-#: src/pyams_content/shared/common/interfaces/__init__.py:138
+#: src/pyams_content/shared/common/interfaces/__init__.py:147
msgid "Last modifier"
msgstr "Dernier intervenant"
-#: src/pyams_content/shared/common/interfaces/__init__.py:139
+#: src/pyams_content/shared/common/interfaces/__init__.py:148
msgid "Last principal who modified this content"
msgstr "Dernier utilisateur étant intervenu sur ce contenu"
-#: src/pyams_content/shared/common/interfaces/__init__.py:142
+#: src/pyams_content/shared/common/interfaces/__init__.py:151
msgid "Last update"
msgstr "Dernière modification"
-#: src/pyams_content/shared/common/interfaces/__init__.py:146
+#: src/pyams_content/shared/common/interfaces/__init__.py:155
msgid ""
"The content's description is 'hidden' into HTML's page headers; but it can "
"be seen, for example, in some search engines results as content's description"
@@ -2991,33 +3102,33 @@
"mais on peut la retrouver, par exemple, dans les listes de résultats des "
"moteurs de recherche"
-#: src/pyams_content/shared/common/interfaces/__init__.py:151
+#: src/pyams_content/shared/common/interfaces/__init__.py:160
msgid "Keywords"
msgstr "Mots-clés"
-#: src/pyams_content/shared/common/interfaces/__init__.py:152
+#: src/pyams_content/shared/common/interfaces/__init__.py:161
msgid "They will be included into HTML pages metadata"
msgstr "Ces mots-clés seront intégrés dans les métadonnées des pages HTML"
-#: src/pyams_content/shared/common/interfaces/__init__.py:155
-#: src/pyams_content/shared/site/zmi/folder.py:76
+#: src/pyams_content/shared/common/interfaces/__init__.py:164
+#: src/pyams_content/shared/site/zmi/folder.py:78
#: src/pyams_content/shared/site/interfaces/__init__.py:66
msgid "Notepad"
msgstr "Bloc-notes"
-#: src/pyams_content/shared/common/interfaces/__init__.py:156
-#: src/pyams_content/shared/site/zmi/folder.py:77
+#: src/pyams_content/shared/common/interfaces/__init__.py:165
+#: src/pyams_content/shared/site/zmi/folder.py:79
#: src/pyams_content/shared/site/interfaces/__init__.py:67
msgid "Internal information to be known about this content"
msgstr ""
"Pour prendre note d'informations internes utiles ou importantes à propos de "
"ce contenu ; ces notes ne seront pas publiées sur internet."
-#: src/pyams_content/shared/common/interfaces/__init__.py:167
+#: src/pyams_content/shared/common/interfaces/__init__.py:180
msgid "Content owner"
msgstr "Propriétaire"
-#: src/pyams_content/shared/common/interfaces/__init__.py:168
+#: src/pyams_content/shared/common/interfaces/__init__.py:181
msgid ""
"The owner is the creator of content's first version, except if it was "
"transferred afterwards to another owner"
@@ -3026,7 +3137,7 @@
"lorsque cette propriété a été transférée à un autre utilisateur après coup. "
"Les contenus archivés ne sont plus transférables."
-#: src/pyams_content/shared/common/interfaces/__init__.py:181
+#: src/pyams_content/shared/common/interfaces/__init__.py:194
msgid ""
"Contributors are users which are allowed to update this content in addition "
"to it's owner"
@@ -3034,11 +3145,11 @@
"Les contributeurs sont autorisés, en plus du propriétaire, à modifier ce "
"contenu"
-#: src/pyams_content/shared/common/interfaces/__init__.py:186
+#: src/pyams_content/shared/common/interfaces/__init__.py:204
msgid "Readers"
msgstr "Relecteurs"
-#: src/pyams_content/shared/common/interfaces/__init__.py:187
+#: src/pyams_content/shared/common/interfaces/__init__.py:205
msgid ""
"Readers are users which are asked to verify and comment contents before they "
"are published"
@@ -3046,22 +3157,27 @@
"Les relecteurs sont des utilisateurs qui sont sollicités pour vérifier et "
"commenter un contenu avant sa publication"
-#: src/pyams_content/shared/common/interfaces/__init__.py:192
+#: src/pyams_content/shared/common/interfaces/__init__.py:210
msgid "Guests"
msgstr "Invités"
-#: src/pyams_content/shared/common/interfaces/__init__.py:193
+#: src/pyams_content/shared/common/interfaces/__init__.py:211
msgid ""
"Guests are users which are allowed to view contents with restricted access"
msgstr ""
"Les invités sont autorisés à consulter des contenus dont l'accès a été "
"restreint"
-#: src/pyams_content/shared/common/interfaces/__init__.py:213
+#: src/pyams_content/shared/common/interfaces/__init__.py:231
msgid "Principal ID"
msgstr "ID utilisateur"
-#: src/pyams_content/shared/common/interfaces/__init__.py:253
+#: src/pyams_content/shared/common/interfaces/__init__.py:270
+#: src/pyams_content/shared/common/interfaces/__init__.py:295
+msgid "Publication checks"
+msgstr "Activer le tunnel de publication"
+
+#: src/pyams_content/shared/common/interfaces/__init__.py:271
msgid ""
"If 'yes', this contributor will have to confirm that contents have been "
"previewed and checked before asking for publication"
@@ -3069,7 +3185,7 @@
"Si 'oui', ce contributeur devra confirmer qu'il a bien prévisualisé et "
"audité chaque contenu avant de pouvoir effectuer une demande de publication"
-#: src/pyams_content/shared/common/interfaces/__init__.py:278
+#: src/pyams_content/shared/common/interfaces/__init__.py:296
msgid ""
"If 'yes', this manager will have to confirm that contents have been "
"previewed and checked before publishing a content"
@@ -3077,11 +3193,11 @@
"Si 'oui', ce responsable devra confirmer qu'il a bien prévisualisé et audité "
"chaque contenu avant de pouvoir effectuer une publication"
-#: src/pyams_content/shared/common/interfaces/__init__.py:283
+#: src/pyams_content/shared/common/interfaces/__init__.py:301
msgid "Restricted contents"
msgstr "Accès restreints"
-#: src/pyams_content/shared/common/interfaces/__init__.py:284
+#: src/pyams_content/shared/common/interfaces/__init__.py:302
msgid ""
"If 'yes', this manager will get restricted access to manage contents based "
"on selected settings"
@@ -3089,11 +3205,11 @@
"Si 'oui', ce responsable n'aura qu'un accès restreint à certains contenus en "
"fonction de paramètres spécifiques"
-#: src/pyams_content/shared/common/interfaces/__init__.py:289
+#: src/pyams_content/shared/common/interfaces/__init__.py:307
msgid "Selected owners"
msgstr "Propriétaires"
-#: src/pyams_content/shared/common/interfaces/__init__.py:290
+#: src/pyams_content/shared/common/interfaces/__init__.py:308
msgid "Manager will have access to contents owned by these principals"
msgstr ""
"Le responsable n'aura accès qu'aux contenus dont ces utilisateurs sont "
@@ -3182,7 +3298,7 @@
msgstr "Champs de saisie"
#: src/pyams_content/shared/form/zmi/field.py:170
-#: src/pyams_content/shared/form/interfaces/__init__.py:56
+#: src/pyams_content/shared/form/interfaces/__init__.py:57
msgid "Field type"
msgstr "Type de champ"
@@ -3191,11 +3307,11 @@
msgstr "Liste des champs du formulaire"
#: src/pyams_content/shared/form/zmi/field.py:226
-#: src/pyams_content/shared/form/zmi/field.py:237
+#: src/pyams_content/shared/form/zmi/field.py:239
msgid "Add form field"
msgstr "Ajouter un champ"
-#: src/pyams_content/shared/form/zmi/field.py:285
+#: src/pyams_content/shared/form/zmi/field.py:281
msgid "Edit form field properties"
msgstr "Propriétés du champ"
@@ -3207,153 +3323,153 @@
msgid "No currently defined form field."
msgstr "Ce formulaire ne comporte aucun champ."
-#: src/pyams_content/shared/form/zmi/field.py:262
+#: src/pyams_content/shared/form/zmi/field.py:266
msgid "Specified name is already used!"
msgstr "Le nom indiqué pour ce champ est déjà utilisé !"
-#: src/pyams_content/shared/form/interfaces/__init__.py:34
+#: src/pyams_content/shared/form/interfaces/__init__.py:35
msgid "Form"
msgstr "Formulaire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:52
+#: src/pyams_content/shared/form/interfaces/__init__.py:53
msgid "Field name"
msgstr "Nom du champ"
-#: src/pyams_content/shared/form/interfaces/__init__.py:53
+#: src/pyams_content/shared/form/interfaces/__init__.py:54
msgid "Field internal name; must be unique for a given form"
msgstr ""
"Nom interne du champ ; ce nom doit être unique pour un formulaire donné"
-#: src/pyams_content/shared/form/interfaces/__init__.py:57
+#: src/pyams_content/shared/form/interfaces/__init__.py:58
msgid "Selected field type"
msgstr "Type de champ proposé à l'internaute"
-#: src/pyams_content/shared/form/interfaces/__init__.py:62
+#: src/pyams_content/shared/form/interfaces/__init__.py:63
msgid "User field label"
msgstr "Libellé affiché à l'internaute"
-#: src/pyams_content/shared/form/interfaces/__init__.py:66
+#: src/pyams_content/shared/form/interfaces/__init__.py:67
msgid "Field description can be displayed as hint"
msgstr ""
"Description du champ, qui pourra être affichée sous la forme d'une info-bulle"
-#: src/pyams_content/shared/form/interfaces/__init__.py:69
+#: src/pyams_content/shared/form/interfaces/__init__.py:70
msgid "Placeholder"
msgstr "Espace réservé"
-#: src/pyams_content/shared/form/interfaces/__init__.py:70
+#: src/pyams_content/shared/form/interfaces/__init__.py:71
msgid "Some field types like textline can display a placeholder"
msgstr ""
"Certains champs tels que les zones de texte peuvent afficher ce texte tant "
"qu'aucune valeur n'y a été saisie"
-#: src/pyams_content/shared/form/interfaces/__init__.py:73
+#: src/pyams_content/shared/form/interfaces/__init__.py:74
msgid "Optional values"
msgstr "Liste de valeurs"
-#: src/pyams_content/shared/form/interfaces/__init__.py:74
+#: src/pyams_content/shared/form/interfaces/__init__.py:75
msgid "List of available values (for 'choice' and 'list' field types)"
msgstr ""
"Liste des valeurs disponibles (pour les champs de types 'Sélection simple' "
"ou 'Sélection multiple')"
-#: src/pyams_content/shared/form/interfaces/__init__.py:77
+#: src/pyams_content/shared/form/interfaces/__init__.py:78
msgid "Default value"
msgstr "Valeur par défaut"
-#: src/pyams_content/shared/form/interfaces/__init__.py:78
+#: src/pyams_content/shared/form/interfaces/__init__.py:79
msgid "Give default value if field type can use it"
msgstr ""
"Donner la valeur par défaut du champ ; attention, tous les types de champs "
"ne peuvent pas utiliser une valeur par défaut !"
-#: src/pyams_content/shared/form/interfaces/__init__.py:81
+#: src/pyams_content/shared/form/interfaces/__init__.py:82
msgid "Required?"
msgstr "Obligatoire ?"
-#: src/pyams_content/shared/form/interfaces/__init__.py:82
+#: src/pyams_content/shared/form/interfaces/__init__.py:83
msgid "Select 'yes' to set field as mandatory"
msgstr "Sélectionnez 'oui' pour que la saisie de ce champ soit obligatoire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:87
+#: src/pyams_content/shared/form/interfaces/__init__.py:88
msgid "Select 'no' to hide given field..."
msgstr "Sélectionnez 'non' pour masquer ce champ"
-#: src/pyams_content/shared/form/interfaces/__init__.py:121
+#: src/pyams_content/shared/form/interfaces/__init__.py:122
msgid "Form title"
msgstr "Titre du formulaire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:124
+#: src/pyams_content/shared/form/interfaces/__init__.py:125
msgid "Form header"
msgstr "En-tête du formulaire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:127
+#: src/pyams_content/shared/form/interfaces/__init__.py:128
msgid "Form handler"
msgstr "Gestionnaire du formulaire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:128
+#: src/pyams_content/shared/form/interfaces/__init__.py:129
msgid "Select how form data is transmitted"
msgstr ""
"Le gestionnaire sélectionné détermine la façon dont les données saisies par "
"les internautes seront stockées ou envoyées"
-#: src/pyams_content/shared/form/interfaces/__init__.py:131
+#: src/pyams_content/shared/form/interfaces/__init__.py:132
msgid "Authenticated only?"
msgstr "Authentification requise ?"
-#: src/pyams_content/shared/form/interfaces/__init__.py:132
+#: src/pyams_content/shared/form/interfaces/__init__.py:133
msgid "If 'yes', only authenticated users will be able to see and submit form"
msgstr ""
"Si 'oui', seuls les utilisateurs authentifiés pourront saisir des données "
"dans le formulaire et les soumettre"
-#: src/pyams_content/shared/form/interfaces/__init__.py:136
+#: src/pyams_content/shared/form/interfaces/__init__.py:137
msgid "Use captcha?"
msgstr "Ajouter un captcha ?"
-#: src/pyams_content/shared/form/interfaces/__init__.py:137
+#: src/pyams_content/shared/form/interfaces/__init__.py:138
msgid "If 'yes', a captcha will be added automatically to the form"
msgstr "Si 'oui', un captcha sera ajouté automatiquement au formulaire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:141
+#: src/pyams_content/shared/form/interfaces/__init__.py:142
msgid "Submit label"
msgstr "Libellé de soumission"
-#: src/pyams_content/shared/form/interfaces/__init__.py:142
+#: src/pyams_content/shared/form/interfaces/__init__.py:143
msgid "Label of form submit button"
msgstr "Libellé du bouton de soumission du formulaire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:179
+#: src/pyams_content/shared/form/interfaces/__init__.py:180
msgid "Source address"
msgstr "Adresse source"
-#: src/pyams_content/shared/form/interfaces/__init__.py:180
+#: src/pyams_content/shared/form/interfaces/__init__.py:181
msgid "Mail address from which form data is sent"
msgstr "Adresse de messagerie émettrice des données"
-#: src/pyams_content/shared/form/interfaces/__init__.py:183
-msgid "Source name"
-msgstr "Nom de la source"
-
#: src/pyams_content/shared/form/interfaces/__init__.py:184
+msgid "Source name"
+msgstr "Nom de la source"
+
+#: src/pyams_content/shared/form/interfaces/__init__.py:185
msgid "Name of mail data sender"
msgstr "Nom de l'émetteur des données"
-#: src/pyams_content/shared/form/interfaces/__init__.py:187
+#: src/pyams_content/shared/form/interfaces/__init__.py:188
msgid "Recipient address"
msgstr "Adresse de destination"
-#: src/pyams_content/shared/form/interfaces/__init__.py:188
+#: src/pyams_content/shared/form/interfaces/__init__.py:189
msgid "Mail address to which form data is sent"
msgstr ""
"Adresse d'envoi des données; vous pouvez indiquer plusieurs adresses en les "
"séparant par des point-virgules"
-#: src/pyams_content/shared/form/interfaces/__init__.py:191
+#: src/pyams_content/shared/form/interfaces/__init__.py:192
msgid "Recipient name"
msgstr "Nom du destinataire"
-#: src/pyams_content/shared/form/interfaces/__init__.py:192
+#: src/pyams_content/shared/form/interfaces/__init__.py:193
msgid "Name of data recipient"
msgstr "Nom du destinataire des messages"
@@ -3371,7 +3487,7 @@
msgid "News topic « {title} »"
msgstr "Actualité « {title} »"
-#: src/pyams_content/shared/news/interfaces/__init__.py:28
+#: src/pyams_content/shared/news/interfaces/__init__.py:29
msgid "News topic"
msgstr "Actualité"
@@ -3397,7 +3513,7 @@
msgid "View themes settings"
msgstr "Paramétrage des thèmes de la vue"
-#: src/pyams_content/shared/view/zmi/reference.py:53
+#: src/pyams_content/shared/view/zmi/reference.py:52
msgid "References..."
msgstr "Références"
@@ -3405,17 +3521,7 @@
msgid "View internal references settings"
msgstr "Références internes de la vue"
-#: src/pyams_content/shared/view/zmi/templates/render.pt:2
-msgid "View result items"
-msgstr "Contenus extraits par la vue"
-
-#: src/pyams_content/shared/view/zmi/templates/render.pt:3
-msgid "WARNING: items displayed in this preview are out of context!!"
-msgstr ""
-"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:56
+#: src/pyams_content/shared/view/portlet/__init__.py:58
msgid "View items"
msgstr "Contenu d'une vue"
@@ -3432,7 +3538,7 @@
msgstr "Vue"
#: src/pyams_content/shared/view/interfaces/__init__.py:40
-#: src/pyams_content/interfaces/__init__.py:111
+#: src/pyams_content/interfaces/__init__.py:113
#: src/pyams_content/features/review/interfaces.py:74
msgid "Creation date"
msgstr "Date de création"
@@ -3511,17 +3617,27 @@
"Indique comment les références internes indiquées seront intégrées à la "
"liste des résultats"
-#: src/pyams_content/shared/view/interfaces/__init__.py:171
+#: src/pyams_content/shared/view/interfaces/__init__.py:164
+msgid "Exclude context?"
+msgstr "Exclure le contexte ?"
+
+#: src/pyams_content/shared/view/interfaces/__init__.py:165
+msgid "If 'yes', context will be excluded from results list"
+msgstr ""
+"Si 'oui', le contexte d'application de la vue sera automatiquement exclus de "
+"la liste des résultats"
+
+#: src/pyams_content/shared/view/interfaces/__init__.py:176
msgid "Select context themes?"
msgstr "Thèmes du contexte ?"
-#: src/pyams_content/shared/view/interfaces/__init__.py:172
+#: src/pyams_content/shared/view/interfaces/__init__.py:177
msgid "If 'yes', themes will be extracted from context"
msgstr ""
"Si 'oui', les thèmes associés au contexte d'application de la vue seront "
"automatiquement sélectionnés"
-#: src/pyams_content/shared/view/interfaces/__init__.py:176
+#: src/pyams_content/shared/view/interfaces/__init__.py:181
msgid "Other terms"
msgstr "Autres thèmes"
@@ -3547,12 +3663,12 @@
msgid "Image map..."
msgstr "Image cliquable"
-#: src/pyams_content/shared/imagemap/zmi/paragraph.py:65
+#: src/pyams_content/shared/imagemap/zmi/paragraph.py:67
msgid "Add new image map"
msgstr "Ajout d'une image cliquable"
-#: src/pyams_content/shared/imagemap/zmi/paragraph.py:97
-#: src/pyams_content/shared/logo/zmi/paragraph.py:96
+#: src/pyams_content/shared/imagemap/zmi/paragraph.py:94
+#: src/pyams_content/shared/logo/zmi/paragraph.py:93
msgid "Edit paragraph properties"
msgstr "Propriétés de l'image cliquable"
@@ -3612,15 +3728,15 @@
msgid "Bad query object_name parameter value!"
msgstr "Valeur incorrecte du paramètre object_name !"
-#: src/pyams_content/shared/imagemap/zmi/area.py:46
+#: src/pyams_content/shared/imagemap/zmi/area.py:47
msgid "Add image area"
msgstr "Ajouter une zone"
-#: src/pyams_content/shared/imagemap/zmi/area.py:64
+#: src/pyams_content/shared/imagemap/zmi/area.py:66
msgid "Add new image area"
msgstr "Ajout d'une zone cliquable"
-#: src/pyams_content/shared/imagemap/zmi/area.py:108
+#: src/pyams_content/shared/imagemap/zmi/area.py:107
msgid "Edit image map properties"
msgstr "Propriétés de l'image"
@@ -3668,7 +3784,7 @@
msgid "Image map template"
msgstr "Mode de rendu"
-#: src/pyams_content/shared/site/folder.py:58
+#: src/pyams_content/shared/site/folder.py:59
msgid "Site folder"
msgstr "Rubrique"
@@ -3676,39 +3792,44 @@
msgid "Content link"
msgstr "Contenu lié"
-#: src/pyams_content/shared/site/zmi/folder.py:59
+#: src/pyams_content/shared/site/manager.py:68
+#: src/pyams_content/shared/site/zmi/manager.py:125
+msgid "Site manager"
+msgstr "Site"
+
+#: src/pyams_content/shared/site/zmi/folder.py:61
msgid "Add site folder..."
msgstr "Ajouter une rubrique"
-#: src/pyams_content/shared/site/zmi/folder.py:90
+#: src/pyams_content/shared/site/zmi/folder.py:93
msgid "Add site folder"
msgstr "Ajout d'une rubrique"
-#: src/pyams_content/shared/site/zmi/folder.py:166
+#: src/pyams_content/shared/site/zmi/folder.py:162
msgid "Site folder management"
msgstr "Gérer cette rubrique"
-#: src/pyams_content/shared/site/zmi/folder.py:177
+#: src/pyams_content/shared/site/zmi/folder.py:190
msgid "Site folder properties"
msgstr "Propriétés de la rubrique"
-#: src/pyams_content/shared/site/zmi/folder.py:69
-#: src/pyams_content/interfaces/__init__.py:100
+#: src/pyams_content/shared/site/zmi/folder.py:71
+#: src/pyams_content/interfaces/__init__.py:102
msgid "Visible label used to display content"
msgstr "Le titre présenté aux internautes"
-#: src/pyams_content/shared/site/zmi/folder.py:72
+#: src/pyams_content/shared/site/zmi/folder.py:74
#: src/pyams_content/shared/site/zmi/__init__.py:72
-#: src/pyams_content/shared/site/zmi/link.py:67
+#: src/pyams_content/shared/site/zmi/link.py:66
msgid "Parent"
msgstr "Niveau parent"
-#: src/pyams_content/shared/site/zmi/folder.py:73
-#: src/pyams_content/shared/site/zmi/link.py:68
+#: src/pyams_content/shared/site/zmi/folder.py:75
+#: src/pyams_content/shared/site/zmi/link.py:67
msgid "Folder's parent"
msgstr "Niveau de rattachement de cette rubrique"
-#: src/pyams_content/shared/site/zmi/folder.py:150
+#: src/pyams_content/shared/site/zmi/folder.py:155
msgid "You must provide a folder name for default server language!"
msgstr ""
"Vous devez fournir un nom pour ce dossier pour la langue par défaut du "
@@ -3722,7 +3843,7 @@
msgid "Add topic..."
msgstr "Ajouter un article"
-#: src/pyams_content/shared/site/zmi/__init__.py:84
+#: src/pyams_content/shared/site/zmi/__init__.py:86
msgid "Add topic"
msgstr "Ajout d'un article"
@@ -3730,7 +3851,7 @@
msgid "Topic's parent"
msgstr "Niveau parent"
-#: src/pyams_content/shared/site/zmi/link.py:58
+#: src/pyams_content/shared/site/zmi/link.py:57
msgid "Rent content..."
msgstr "Lier un contenu"
@@ -3738,87 +3859,83 @@
msgid "Rent existing content"
msgstr "Lier un contenu existant"
-#: src/pyams_content/shared/site/zmi/link.py:141
+#: src/pyams_content/shared/site/zmi/link.py:135
msgid "Edit content link properties"
msgstr "Propriétés du lien"
#: src/pyams_content/shared/site/zmi/container.py:106
#: src/pyams_content/shared/site/zmi/container.py:118
-#: src/pyams_content/shared/blog/zmi/manager.py:160
-#: src/pyams_content/shared/blog/zmi/manager.py:172
+#: src/pyams_content/shared/blog/zmi/manager.py:155
+#: src/pyams_content/shared/blog/zmi/manager.py:167
msgid "Publication dates..."
msgstr "Dates de publication"
-#: src/pyams_content/shared/site/zmi/container.py:131
-#: src/pyams_content/shared/blog/zmi/manager.py:185
+#: src/pyams_content/shared/site/zmi/container.py:132
+#: src/pyams_content/shared/blog/zmi/manager.py:181
msgid "Update publication dates"
msgstr "Dates de publication"
-#: src/pyams_content/shared/site/zmi/container.py:183
-#: src/pyams_content/shared/site/zmi/container.py:193
+#: src/pyams_content/shared/site/zmi/container.py:178
+#: src/pyams_content/shared/site/zmi/container.py:188
#: src/pyams_content/root/zmi/sites.py:68
msgid "Site tree"
msgstr "Arborescence du site"
-#: src/pyams_content/shared/site/zmi/container.py:312
-#: src/pyams_content/shared/site/zmi/container.py:162
+#: src/pyams_content/shared/site/zmi/container.py:307
+#: src/pyams_content/shared/site/zmi/container.py:156
msgid "Visible element?"
msgstr "Élément visible ?"
-#: src/pyams_content/shared/site/zmi/container.py:313
+#: src/pyams_content/shared/site/zmi/container.py:308
msgid "Switch element visibility"
msgstr "Cliquez pour rendre l'élément visible ou non"
-#: src/pyams_content/shared/site/zmi/container.py:374
+#: src/pyams_content/shared/site/zmi/container.py:369
msgid "Folders and topics"
msgstr "Rubriquage"
-#: src/pyams_content/shared/site/zmi/container.py:410
-#: src/pyams_content/root/zmi/__init__.py:798
+#: src/pyams_content/shared/site/zmi/container.py:405
+#: src/pyams_content/root/zmi/__init__.py:817
msgid "Content"
msgstr "Contenu"
-#: src/pyams_content/shared/site/zmi/container.py:506
+#: src/pyams_content/shared/site/zmi/container.py:501
msgid "Delete site item"
msgstr "Supprimer ce contenu"
-#: src/pyams_content/shared/site/zmi/container.py:383
+#: src/pyams_content/shared/site/zmi/container.py:378
msgid "Click to open/close all folders"
msgstr "Afficher/masquer toutes les rubriques"
-#: src/pyams_content/shared/site/zmi/container.py:399
+#: src/pyams_content/shared/site/zmi/container.py:394
msgid "Click to show/hide inner folders"
msgstr "Cliquer pour afficher ou cache les sous-niveaux"
-#: src/pyams_content/shared/site/zmi/container.py:269
+#: src/pyams_content/shared/site/zmi/container.py:264
msgid "Can't reparent object to one of it's children. Reloading..."
msgstr ""
"Impossible de déplacer une rubrique dans l'une de ses sous-rubriques ou "
"contenus ! Rechargement de la page..."
-#: src/pyams_content/shared/site/zmi/manager.py:58
+#: src/pyams_content/shared/site/zmi/manager.py:57
msgid "Site management"
msgstr "Gérer ce site"
-#: src/pyams_content/shared/site/zmi/manager.py:88
-#: src/pyams_content/shared/site/zmi/manager.py:100
+#: src/pyams_content/shared/site/zmi/manager.py:112
+#: src/pyams_content/shared/site/zmi/manager.py:126
msgid "Add site manager"
msgstr "Ajouter un site"
-#: src/pyams_content/shared/site/zmi/manager.py:99
-msgid "Site manager"
-msgstr "Site"
-
-#: src/pyams_content/shared/site/zmi/manager.py:131
-#: src/pyams_content/shared/blog/zmi/manager.py:126
+#: src/pyams_content/shared/site/zmi/manager.py:156
+#: src/pyams_content/shared/blog/zmi/manager.py:127
msgid "You must provide a short name for default server language!"
msgstr "Vous devez fournir un nom court pour la langue par défaut du serveur !"
-#: src/pyams_content/shared/site/zmi/manager.py:135
+#: src/pyams_content/shared/site/zmi/manager.py:160
msgid "Specified site manager name is already used!"
msgstr "Le nom indiqué pour ce site existe déjà !"
-#: src/pyams_content/shared/site/zmi/manager.py:139
+#: src/pyams_content/shared/site/zmi/manager.py:164
msgid "A site manager is already registered with this name!!"
msgstr "Un site est déjà inscrit dans le registre avec ce nom !"
@@ -3876,11 +3993,11 @@
msgid "no URL defined"
msgstr "aucune URL définie"
-#: src/pyams_content/shared/logo/zmi/paragraph.py:53
+#: src/pyams_content/shared/logo/zmi/paragraph.py:54
msgid "Logos..."
msgstr "Logos"
-#: src/pyams_content/shared/logo/zmi/paragraph.py:64
+#: src/pyams_content/shared/logo/zmi/paragraph.py:67
msgid "Add new logos paragraph"
msgstr "Ajout d'une sélection de logos"
@@ -3941,19 +4058,19 @@
msgstr "Gérer ce blog"
#: src/pyams_content/shared/blog/zmi/manager.py:83
-#: src/pyams_content/shared/blog/zmi/manager.py:95
+#: src/pyams_content/shared/blog/zmi/manager.py:97
msgid "Add blog manager"
msgstr "Ajouter un blog"
-#: src/pyams_content/shared/blog/zmi/manager.py:94
+#: src/pyams_content/shared/blog/zmi/manager.py:96
msgid "Blog manager"
msgstr "Blog"
-#: src/pyams_content/shared/blog/zmi/manager.py:130
+#: src/pyams_content/shared/blog/zmi/manager.py:131
msgid "Specified blog manager name is already used!"
msgstr "Le nom indiqué pour ce blog existe déjà !"
-#: src/pyams_content/shared/blog/zmi/manager.py:134
+#: src/pyams_content/shared/blog/zmi/manager.py:135
msgid "A blog manager is already registered with this name!!"
msgstr "Un blog est déjà inscrit dans le registre avec ce nom !"
@@ -3981,6 +4098,10 @@
msgid "Default length used for inner tables and dashboards"
msgstr "Longueur par défaut des tableaux internes et des tableaux de bord"
+#: src/pyams_content/root/__init__.py:67
+msgid "Site root"
+msgstr "Racine du site"
+
#: src/pyams_content/root/zmi/sites.py:78
msgid "Blogs and shared sites"
msgstr "Blogs et sites partagés"
@@ -4005,7 +4126,7 @@
msgid "Content types"
msgstr "Types de contenus"
-#: src/pyams_content/root/zmi/__init__.py:77
+#: src/pyams_content/root/zmi/__init__.py:78
msgid "Home"
msgstr "Accueil"
@@ -4017,19 +4138,19 @@
msgid "SEARCH - Between all contents"
msgstr "RECHERCHE - Tous contenus confondus"
-#: src/pyams_content/root/interfaces/__init__.py:36
+#: src/pyams_content/root/interfaces/__init__.py:39
msgid "Site managers"
msgstr "Administrateurs"
-#: src/pyams_content/root/interfaces/__init__.py:44
+#: src/pyams_content/root/interfaces/__init__.py:47
msgid "Templates managers"
msgstr "Designers"
-#: src/pyams_content/root/interfaces/__init__.py:48
+#: src/pyams_content/root/interfaces/__init__.py:51
msgid "Operators group"
msgstr "Groupe des opérateurs"
-#: src/pyams_content/root/interfaces/__init__.py:49
+#: src/pyams_content/root/interfaces/__init__.py:52
msgid "Name of group containing all roles owners"
msgstr ""
"Tous les utilisateurs auxquels sera attribué un rôle seront placés dans ce "
@@ -4355,11 +4476,11 @@
msgstr ""
"Retrait automatique des contenus après la date de fin de publication :\n"
-#: src/pyams_content/workflow/zmi/task.py:43
+#: src/pyams_content/workflow/zmi/task.py:42
msgid "Add content archiver task..."
msgstr "Ajouter une tâche d'archivage automatique"
-#: src/pyams_content/workflow/zmi/task.py:54
+#: src/pyams_content/workflow/zmi/task.py:55
msgid "Add automatic content archiver"
msgstr "Ajout d'une tâche d'archivage automatique"
@@ -4388,18 +4509,23 @@
msgstr "Clé unique"
#: src/pyams_content/interfaces/__init__.py:96
-msgid "WARNING: this key can't be modified after creation!!!"
-msgstr "ATTENTION : cette clé ne pourra plus être modifiée !!!"
-
-#: src/pyams_content/interfaces/__init__.py:103
+msgid ""
+"WARNING: this key can't be modified after creation!!! Spaces, uppercase "
+"letters ou accentuated characters will be replaced automatically."
+msgstr ""
+"ATTENTION : cette clé ne pourra plus être modifiée après sa création. Les "
+"espaces, les majuscules, les lettres accentuées et les caractères spéciaux "
+"seront remplacées automatiquement."
+
+#: src/pyams_content/interfaces/__init__.py:105
msgid "Short name"
msgstr "Fil d'Ariane"
-#: src/pyams_content/interfaces/__init__.py:104
+#: src/pyams_content/interfaces/__init__.py:106
msgid "Short name used in breadcrumbs"
msgstr "Libellé utilisé dans le fil d'Ariane"
-#: src/pyams_content/interfaces/__init__.py:115
+#: src/pyams_content/interfaces/__init__.py:117
msgid "Modification date"
msgstr "Dernière modification apportée"
@@ -4420,11 +4546,11 @@
msgid "Properties..."
msgstr "Propriétés"
-#: src/pyams_content/reference/zmi/table.py:156
+#: src/pyams_content/reference/zmi/table.py:157
msgid "Edit table properties"
msgstr "Propriétés de la table"
-#: src/pyams_content/reference/zmi/table.py:173
+#: src/pyams_content/reference/zmi/table.py:167
msgid "Table management"
msgstr "Gérer cette table"
@@ -4432,11 +4558,16 @@
msgid "References"
msgstr "Tables de réf."
+#: src/pyams_content/reference/pictograms/zmi/__init__.py:169
+#: src/pyams_content/reference/pictograms/zmi/widget.py:55
+msgid "Default header: --"
+msgstr "En-tête par défaut : --"
+
#: src/pyams_content/reference/pictograms/zmi/manager.py:51
msgid "Pictograms selection..."
msgstr "Sélection de pictogrammes"
-#: src/pyams_content/reference/pictograms/zmi/manager.py:62
+#: src/pyams_content/reference/pictograms/zmi/manager.py:63
#: src/pyams_content/reference/pictograms/zmi/templates/manager-selection.pt:34
#: src/pyams_content/reference/pictograms/interfaces/__init__.py:73
msgid "Selected pictograms"
@@ -4451,6 +4582,10 @@
msgid "Display pictogram properties"
msgstr "Propriétés du pictogramme"
+#: src/pyams_content/reference/pictograms/zmi/templates/pictogram-header.pt:6
+msgid "Default header: ${header}"
+msgstr "En-tête par défaut : ${header}"
+
#: src/pyams_content/reference/pictograms/interfaces/__init__.py:45
msgid "Pictogram content"
msgstr "Utilisez le bouton \"Parcourir\" pour modifier le contenu de l'image"
@@ -4468,7 +4603,7 @@
msgid "List of selected pictograms which will be available to shared contents"
msgstr "Liste des pictogrammes proposés dans les contenus partagés"
-#: src/pyams_content/features/renderer/zmi/__init__.py:72
+#: src/pyams_content/features/renderer/zmi/__init__.py:70
#: src/pyams_content/features/renderer/zmi/templates/renderer-input.pt:4
msgid "Edit renderer properties"
msgstr "Propriétés du mode de rendu"
@@ -4548,7 +4683,7 @@
#. Default: Heading
#: src/pyams_content/features/alert/interfaces.py:65
-#: src/pyams_content/features/alert/zmi/container.py:158
+#: src/pyams_content/features/alert/zmi/container.py:157
msgid "alert-header"
msgstr "En-tête"
@@ -4557,7 +4692,7 @@
msgstr "En-tête de l'alerte (« Alerte », « Important », « Prudence »...)"
#: src/pyams_content/features/alert/interfaces.py:69
-#: src/pyams_content/features/alert/zmi/container.py:170
+#: src/pyams_content/features/alert/zmi/container.py:169
msgid "Message"
msgstr "Message"
@@ -4607,7 +4742,7 @@
"donné, l'alerte apparaîtra à nouveau. Si aucun intervalle n'est indiqué, "
"l'alerte s'affichera en permanence."
-#: src/pyams_content/features/alert/zmi/__init__.py:46
+#: src/pyams_content/features/alert/zmi/__init__.py:45
msgid "Add alert"
msgstr "Ajouter une alerte"
@@ -4615,7 +4750,7 @@
msgid "Add new alert"
msgstr "Ajout d'une alerte"
-#: src/pyams_content/features/alert/zmi/__init__.py:85
+#: src/pyams_content/features/alert/zmi/__init__.py:79
msgid "Edit alert properties"
msgstr "Propriétés de l'alerte"
@@ -4623,31 +4758,106 @@
msgid "Alerts"
msgstr "Alertes"
-#: src/pyams_content/features/alert/zmi/container.py:192
+#: src/pyams_content/features/alert/zmi/container.py:191
msgid "Alert list"
msgstr "Liste des alertes"
-#: src/pyams_content/features/alert/zmi/container.py:91
+#: src/pyams_content/features/alert/zmi/container.py:90
msgid "No currently defined alert."
msgstr "Aucune alerte n'est définie actuellement."
-#: src/pyams_content/features/footer/zmi/__init__.py:56
+#: src/pyams_content/features/menu/zmi/__init__.py:81
+msgid "Add menu..."
+msgstr "Ajouter un menu"
+
+#: src/pyams_content/features/menu/zmi/__init__.py:92
+msgid "Add new menu"
+msgstr "Ajout d'un menu"
+
+#: src/pyams_content/features/menu/zmi/__init__.py:123
+msgid "Edit menu properties"
+msgstr "Propriétés du menu"
+
+#: src/pyams_content/features/menu/zmi/__init__.py:110
+msgid "Menu was correctly added."
+msgstr "Le menu a été ajouté."
+
+#: src/pyams_content/features/menu/zmi/__init__.py:388
+msgid "Link was correctly added."
+msgstr "Le lien a été ajouté."
+
+#: src/pyams_content/features/menu/zmi/templates/menu-name-cell.pt:7
+msgid "Click to see menu items"
+msgstr "Montrer ou cacher les éléments du menu"
+
+#: src/pyams_content/features/menu/portlet/navigation/simple.py:68
+msgid "Simple navigation"
+msgstr "Navigation à un niveau"
+
+#: src/pyams_content/features/menu/portlet/navigation/double.py:68
+msgid "Double navigation"
+msgstr "Navigation à deux niveaux"
+
+#: src/pyams_content/features/menu/portlet/navigation/zmi/simple.py:70
+msgid "Navigation links"
+msgstr "Liens de navigation"
+
+#: src/pyams_content/features/menu/portlet/navigation/zmi/double.py:70
+msgid "Navigation menus"
+msgstr "Menus de navigation"
+
+#: src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt:13
+msgid "Link has no illustration"
+msgstr "Le lien n'a pas d'illustration"
+
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:32
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:32
+msgid "Portlet main title"
+msgstr "Titre du composant"
+
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:35
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:35
+msgid "Subtitle"
+msgstr "Sous-titre"
+
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:36
+#: src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:36
+msgid "Portlet subtitle"
+msgstr "Sous-titre du composant"
+
+#: src/pyams_content/features/menu/interfaces/__init__.py:63
+msgid "Menu title"
+msgstr "Libellé"
+
+#: src/pyams_content/features/menu/interfaces/__init__.py:64
+msgid "Displayed menu label"
+msgstr "Libellé du menu"
+
+#: src/pyams_content/features/footer/zmi/__init__.py:60
msgid "Page footer"
msgstr "Pied de pages"
-#: src/pyams_content/features/footer/zmi/__init__.py:74
+#: src/pyams_content/features/footer/zmi/__init__.py:78
msgid "Edit footer settings"
msgstr "Paramétrage des pieds de pages"
-#: src/pyams_content/features/footer/zmi/__init__.py:172
+#: src/pyams_content/features/footer/zmi/__init__.py:152
+msgid ""
+"WARNING: Footer properties are saved automatically when changing inherit "
+"mode!!"
+msgstr ""
+"ATTENTION : les propriétés du pied de page sont enregistrées automatiquement "
+"lorsque vous modifiez le mode d'héritage !!"
+
+#: src/pyams_content/features/footer/zmi/__init__.py:220
msgid "Footer renderer settings"
msgstr "Propriétés du mode de rendu"
-#: src/pyams_content/features/footer/zmi/__init__.py:101
+#: src/pyams_content/features/footer/zmi/__init__.py:107
msgid "Don't inherit parent footer"
msgstr "Ne pas hériter du pied de pages du parent"
-#: src/pyams_content/features/footer/skin/__init__.py:49
+#: src/pyams_content/features/footer/skin/__init__.py:53
msgid "Hidden footer"
msgstr "Ne pas afficher de pied de pages"
@@ -4659,17 +4869,17 @@
msgid "Presentation template used for this footer"
msgstr "Mode de rendu utilisé par ce pied de page"
-#: src/pyams_content/features/review/__init__.py:180
+#: src/pyams_content/features/review/__init__.py:181
#, python-format
msgid "Request comment: {comment}"
msgstr "Commentaire joint : {comment}"
-#: src/pyams_content/features/review/__init__.py:210
+#: src/pyams_content/features/review/__init__.py:211
#, python-format
msgid "A new comment was added on content « {0} »"
msgstr "Un nouveau commentaire a été ajouté pour le contenu « {0} »"
-#: src/pyams_content/features/review/__init__.py:167
+#: src/pyams_content/features/review/__init__.py:168
#, python-format
msgid "[{service_name}] A content review is requested"
msgstr "[{service_name}] Demande de relecture"
@@ -4714,15 +4924,15 @@
msgid "Ask for review..."
msgstr "Demander une relecture"
-#: src/pyams_content/features/review/zmi/__init__.py:99
+#: src/pyams_content/features/review/zmi/__init__.py:100
msgid "Content review request"
msgstr "Demande de relecture"
-#: src/pyams_content/features/review/zmi/__init__.py:172
+#: src/pyams_content/features/review/zmi/__init__.py:166
msgid "Comments"
msgstr "Commentaires"
-#: src/pyams_content/features/review/zmi/__init__.py:192
+#: src/pyams_content/features/review/zmi/__init__.py:186
msgid "Review comments"
msgstr "Commentaires associés à cette version"
@@ -4763,16 +4973,16 @@
msgid "Ask for content review"
msgstr "Demander la relecture"
-#: src/pyams_content/features/review/zmi/__init__.py:153
+#: src/pyams_content/features/review/zmi/__init__.py:147
msgid "Request successful. No new notification have been sent"
msgstr ""
"Votre demande a été transmise. Aucune nouvelle notification n'a été envoyée."
-#: src/pyams_content/features/review/zmi/__init__.py:266
+#: src/pyams_content/features/review/zmi/__init__.py:260
msgid "Message is mandatory!"
msgstr "Un commentaire est obligatoire !"
-#: src/pyams_content/features/review/zmi/__init__.py:141
+#: src/pyams_content/features/review/zmi/__init__.py:135
#, python-format
msgid "Request successful. {count} new notification(s) have been sent"
msgstr "Votre demande a été transmise. {count} notification(s) envoyée(s)."
@@ -4855,26 +5065,48 @@
msgid "Thank you."
msgstr "Merci."
-#: src/pyams_content/features/header/zmi/__init__.py:62
+#: src/pyams_content/features/header/zmi/__init__.py:66
msgid "Page header"
msgstr "En-tête de pages"
-#: src/pyams_content/features/header/zmi/__init__.py:80
+#: src/pyams_content/features/header/zmi/__init__.py:84
msgid "Edit header settings"
msgstr "Paramétrage des en-têtes de pages"
-#: src/pyams_content/features/header/zmi/__init__.py:178
+#: src/pyams_content/features/header/zmi/__init__.py:161
+msgid ""
+"WARNING: Header properties are saved automatically when changing inherit "
+"mode!!"
+msgstr ""
+"ATTENTION : les propriétés de l'en-tête sont enregistrées automatiquement "
+"lorsque vous modifiez le mode d'héritage !!"
+
+#: src/pyams_content/features/header/zmi/__init__.py:229
msgid "Header renderer settings"
msgstr "Propriétés du mode de rendu"
-#: src/pyams_content/features/header/zmi/__init__.py:107
+#: src/pyams_content/features/header/zmi/__init__.py:113
msgid "Don't inherit parent header"
msgstr "Ne pas hériter de l'en-tête de pages du parent"
-#: src/pyams_content/features/header/skin/__init__.py:49
+#: src/pyams_content/features/header/skin/__init__.py:53
msgid "Hidden header"
msgstr "Ne pas afficher d'en-tête de pages"
+#~ msgid "WARNING: this key can't be modified after creation!!!"
+#~ msgstr "ATTENTION : cette clé ne pourra plus être modifiée !!!"
+
+#~ msgid "Links"
+#~ msgstr "Liens"
+
+#~ msgid "View result items"
+#~ msgstr "Contenus extraits par la vue"
+
+#~ msgid "WARNING: items displayed in this preview are out of context!!"
+#~ msgstr ""
+#~ "ATTENTION : les résultats affichés dans cet aperçu ne tiennent pas compte "
+#~ "du contexte pouvant être paramétré dans la vue !!!"
+
#~ msgid "Milestones paragraph"
#~ msgstr "Chronologie"
@@ -4908,9 +5140,6 @@
#~ msgid "Check content..."
#~ msgstr "Auditer le contenu"
-#~ msgid "Simple list view"
-#~ msgstr "Vue simple d'une liste d'éléments"
-
#~ msgid "Paragraphs types..."
#~ msgstr "Types de paragraphes"
@@ -4978,9 +5207,6 @@
#~ "Ce formulaire vous permet d'effectuer la sélection des pictogrammes qui "
#~ "seront disponibles pour être intégrés dans les contenus partagés."
-#~ msgid "Default gallery renderer"
-#~ msgstr "Galerie par défaut"
-
#~ msgid "Add medias gallery..."
#~ msgstr "Galerie de médias"
@@ -5069,9 +5295,6 @@
#~ msgid "The content « {0} » has been archived"
#~ msgstr "Le contenu « {0} » a été archivé"
-#~ msgid "Add comment..."
-#~ msgstr "Ajouter un commentaire"
-
#~ msgid "Publication settings"
#~ msgstr "Dates de publication et de retrait"
@@ -5109,9 +5332,6 @@
#~ msgid "Image title"
#~ msgstr "Légende de l'image"
-#~ msgid "Links"
-#~ msgstr "Liens"
-
#~ msgid "Paragraph title"
#~ msgstr "Titre du paragraphe"
--- a/src/pyams_content/locales/pyams_content.pot Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/locales/pyams_content.pot Wed Jun 27 16:42:01 2018 +0200
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-06-06 13:20+0200\n"
+"POT-Creation-Date: 2018-06-26 14:52+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"
@@ -49,31 +49,31 @@
msgid "Webmaster (role)"
msgstr ""
-#: ./src/pyams_content/__init__.py:62
+#: ./src/pyams_content/__init__.py:64
msgid "Pilot (role)"
msgstr ""
-#: ./src/pyams_content/__init__.py:70
+#: ./src/pyams_content/__init__.py:74
msgid "Manager (role)"
msgstr ""
-#: ./src/pyams_content/__init__.py:77
+#: ./src/pyams_content/__init__.py:83
msgid "Owner (role)"
msgstr ""
-#: ./src/pyams_content/__init__.py:82
+#: ./src/pyams_content/__init__.py:88
msgid "Contributor (role)"
msgstr ""
-#: ./src/pyams_content/__init__.py:90
+#: ./src/pyams_content/__init__.py:99
msgid "Reader (role)"
msgstr ""
-#: ./src/pyams_content/__init__.py:96
+#: ./src/pyams_content/__init__.py:109
msgid "Operator (role)"
msgstr ""
-#: ./src/pyams_content/__init__.py:100
+#: ./src/pyams_content/__init__.py:114
msgid "Guest user (role)"
msgstr ""
@@ -81,25 +81,25 @@
msgid "Gallery"
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/file.py:58
+#: ./src/pyams_content/component/gallery/zmi/file.py:57
#: ./src/pyams_content/component/gallery/zmi/file.py:69
-#: ./src/pyams_content/component/gallery/zmi/paragraph.py:174
+#: ./src/pyams_content/component/gallery/zmi/paragraph.py:164
msgid "Add media(s)"
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/file.py:189
+#: ./src/pyams_content/component/gallery/zmi/file.py:184
msgid "Update media properties"
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/file.py:249
+#: ./src/pyams_content/component/gallery/zmi/file.py:238
msgid "Remove media..."
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/file.py:154
+#: ./src/pyams_content/component/gallery/zmi/file.py:148
msgid "Show/hide media"
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/file.py:216
+#: ./src/pyams_content/component/gallery/zmi/file.py:211
msgid "Audio content"
msgstr ""
@@ -107,19 +107,19 @@
msgid "Medias gallery..."
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/paragraph.py:67
+#: ./src/pyams_content/component/gallery/zmi/paragraph.py:69
msgid "Add new gallery"
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/paragraph.py:99
+#: ./src/pyams_content/component/gallery/zmi/paragraph.py:96
msgid "Edit gallery properties"
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/__init__.py:62
+#: ./src/pyams_content/component/gallery/zmi/__init__.py:63
msgid "Update gallery properties"
msgstr ""
-#: ./src/pyams_content/component/gallery/zmi/__init__.py:101
+#: ./src/pyams_content/component/gallery/zmi/__init__.py:95
msgid "Update gallery contents"
msgstr ""
@@ -134,8 +134,8 @@
#: ./src/pyams_content/component/gallery/zmi/interfaces.py:40
#: ./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/illustration/interfaces/__init__.py:68
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:52
#: ./src/pyams_content/component/paragraph/interfaces/audio.py:48
#: ./src/pyams_content/component/paragraph/interfaces/verbatim.py:44
#: ./src/pyams_content/component/video/interfaces/__init__.py:52
@@ -145,7 +145,7 @@
#: ./src/pyams_content/component/gallery/zmi/interfaces.py:41
#: ./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:53
#: ./src/pyams_content/component/paragraph/interfaces/audio.py:49
#: ./src/pyams_content/component/video/interfaces/__init__.py:53
msgid "Name of document's author"
@@ -177,24 +177,26 @@
msgstr ""
#: ./src/pyams_content/component/gallery/interfaces/__init__.py:47
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:41
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:77
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:46
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:105
msgid "Image or video data"
msgstr ""
#: ./src/pyams_content/component/gallery/interfaces/__init__.py:48
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:42
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:78
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:47
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:106
msgid "Image or video content"
msgstr ""
#: ./src/pyams_content/component/gallery/interfaces/__init__.py:51
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:45
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:53
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:45
+#: ./src/pyams_content/component/video/interfaces/__init__.py:75
msgid "Legend"
msgstr ""
#: ./src/pyams_content/component/gallery/interfaces/__init__.py:54
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:48
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:56
#: ./src/pyams_content/reference/pictograms/interfaces/__init__.py:48
msgid "Accessibility title"
msgstr ""
@@ -206,13 +208,13 @@
#: ./src/pyams_content/component/gallery/interfaces/__init__.py:58
#: ./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/illustration/interfaces/__init__.py:64
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:48
#: ./src/pyams_content/component/paragraph/interfaces/audio.py:44
-#: ./src/pyams_content/component/links/interfaces/__init__.py:37
+#: ./src/pyams_content/component/links/interfaces/__init__.py:39
#: ./src/pyams_content/component/video/interfaces/__init__.py:48
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:145
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:65
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:154
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:66
msgid "Description"
msgstr ""
@@ -263,17 +265,20 @@
msgstr ""
#: ./src/pyams_content/component/gallery/interfaces/__init__.py:94
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:246
-#: ./src/pyams_content/component/paragraph/zmi/container.py:224
+#: ./src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:31
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:231
+#: ./src/pyams_content/component/paragraph/zmi/container.py:223
#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:45
-#: ./src/pyams_content/component/links/zmi/reverse.py:71
+#: ./src/pyams_content/component/links/zmi/reverse.py:73
#: ./src/pyams_content/shared/common/zmi/dashboard.py:109
#: ./src/pyams_content/shared/common/zmi/templates/advanced-search.pt:188
#: ./src/pyams_content/shared/imagemap/zmi/container.py:123
-#: ./src/pyams_content/shared/site/zmi/folder.py:68
+#: ./src/pyams_content/shared/site/zmi/folder.py:70
#: ./src/pyams_content/root/zmi/templates/advanced-search.pt:188
-#: ./src/pyams_content/interfaces/__init__.py:99
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:165
+#: ./src/pyams_content/interfaces/__init__.py:101
+#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:150
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:31
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:31
msgid "Title"
msgstr ""
@@ -325,59 +330,59 @@
msgid "Add external file"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:101
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:103
msgid "Add new external file"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:141
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:138
msgid "Update file properties"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:181
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:171
msgid "Images"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:196
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:186
msgid "Add image"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:208
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:200
msgid "Add new image"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:244
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:231
msgid "Update image properties"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:283
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:264
msgid "Videos"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:298
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:279
msgid "Add video"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:310
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:293
msgid "Add new video"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:339
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:317
msgid "Update video properties"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:371
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:343
msgid "Audios files"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:386
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:358
msgid "Add audio file"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:398
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:372
msgid "Add new audio file"
msgstr ""
-#: ./src/pyams_content/component/extfile/zmi/__init__.py:427
+#: ./src/pyams_content/component/extfile/zmi/__init__.py:396
msgid "Update audio file properties"
msgstr ""
@@ -386,7 +391,7 @@
msgstr ""
#: ./src/pyams_content/component/extfile/interfaces/__init__.py:36
-#: ./src/pyams_content/component/links/interfaces/__init__.py:33
+#: ./src/pyams_content/component/links/interfaces/__init__.py:35
#: ./src/pyams_content/shared/imagemap/interfaces/__init__.py:54
#: ./src/pyams_content/shared/site/interfaces/__init__.py:113
msgid "Alternate title"
@@ -397,14 +402,14 @@
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:49
#: ./src/pyams_content/component/paragraph/interfaces/audio.py:45
#: ./src/pyams_content/component/video/interfaces/__init__.py:49
msgid "File description displayed by front-office template"
msgstr ""
#: ./src/pyams_content/component/extfile/interfaces/__init__.py:48
-#: ./src/pyams_content/component/links/interfaces/__init__.py:59
+#: ./src/pyams_content/component/links/interfaces/__init__.py:68
msgid "Language"
msgstr ""
@@ -438,7 +443,7 @@
msgstr ""
#: ./src/pyams_content/component/extfile/interfaces/__init__.py:81
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:52
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:41
msgid "Video data"
msgstr ""
@@ -451,43 +456,155 @@
msgid "Audio file content"
msgstr ""
-#: ./src/pyams_content/component/illustration/__init__.py:132
-#: ./src/pyams_content/component/illustration/zmi/__init__.py:54
-#: ./src/pyams_content/component/illustration/zmi/__init__.py:81
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:71
+#: ./src/pyams_content/component/keynumber/__init__.py:189
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:198
+#: ./src/pyams_content/component/keynumber/portlet/zmi/__init__.py:79
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:29
+msgid "Key numbers"
+msgstr ""
+
+#. Default: Header
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:146
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:44
+msgid "key-number-label"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:158
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:49
+msgid "Number"
+msgstr ""
+
+#. Default: Unit
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:167
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:53
+msgid "key-number-unit"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:179
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:57
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:267
+#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:58
+msgid "Associated text"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:217
+msgid "Add keynumber"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:229
+msgid "Add new keynumber"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:258
+msgid "Edit keynumber properties"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/zmi/__init__.py:244
+msgid "Key number was correctly added"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/portlet/__init__.py:71
+msgid "Key Numbers"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/portlet/zmi/__init__.py:102
+#: ./src/pyams_content/component/keynumber/portlet/zmi/templates/keynumber-preview.pt:22
+msgid "Associated links"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/portlet/zmi/templates/keynumber-preview.pt:27
+#: ./src/pyams_content/features/menu/portlet/navigation/zmi/templates/double-preview.pt:12
+#: ./src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt:9
+msgid "Link target is not published!"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:32
+msgid "Portlet title"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:35
+msgid "Teaser"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/portlet/interfaces/__init__.py:36
+msgid "Short text displayed above key numbers"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:39
+#: ./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/association/interfaces/__init__.py:42
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:87
+#: ./src/pyams_content/shared/site/interfaces/__init__.py:117
+#: ./src/pyams_content/features/alert/interfaces.py:54
+#: ./src/pyams_content/features/menu/interfaces/__init__.py:58
+msgid "Visible?"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:40
+msgid "Is this key number visible in front-office?"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:45
+msgid ""
+"Small text to be displayed above number (according to selected renderer)"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:50
+msgid "Key number value"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:54
+msgid "Displayed unit"
+msgstr ""
+
+#: ./src/pyams_content/component/keynumber/interfaces/__init__.py:58
+msgid "The way this text will be rendered depends on presentation template"
+msgstr ""
+
+#: ./src/pyams_content/component/illustration/__init__.py:177
+#: ./src/pyams_content/component/illustration/zmi/paragraph.py:168
+#: ./src/pyams_content/component/illustration/zmi/__init__.py:56
+#: ./src/pyams_content/component/illustration/zmi/__init__.py:100
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:99
msgid "Illustration"
msgstr ""
-#: ./src/pyams_content/component/illustration/zmi/paragraph.py:57
+#: ./src/pyams_content/component/illustration/zmi/paragraph.py:60
msgid "Illustration..."
msgstr ""
-#: ./src/pyams_content/component/illustration/zmi/paragraph.py:68
+#: ./src/pyams_content/component/illustration/zmi/paragraph.py:73
msgid "Add new illustration"
msgstr ""
-#: ./src/pyams_content/component/illustration/zmi/paragraph.py:102
+#: ./src/pyams_content/component/illustration/zmi/paragraph.py:103
msgid "Edit illustration properties"
msgstr ""
-#: ./src/pyams_content/component/illustration/zmi/__init__.py:83
+#: ./src/pyams_content/component/illustration/zmi/__init__.py:155
+msgid "Navigation link illustration"
+msgstr ""
+
+#: ./src/pyams_content/component/illustration/zmi/__init__.py:102
msgid "Header illustration"
msgstr ""
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:49
-#: ./src/pyams_content/reference/pictograms/interfaces/__init__.py:49
-msgid "Alternate title used to describe image content"
-msgstr ""
-
#: ./src/pyams_content/component/illustration/interfaces/__init__.py:57
+#: ./src/pyams_content/reference/pictograms/interfaces/__init__.py:49
+msgid "Alternate title used to describe image content"
+msgstr ""
+
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:69
msgid "Name of picture's author"
msgstr ""
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:60
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:72
msgid "Illustration template"
msgstr ""
-#: ./src/pyams_content/component/illustration/interfaces/__init__.py:61
+#: ./src/pyams_content/component/illustration/interfaces/__init__.py:73
msgid "Presentation template used for illustration"
msgstr ""
@@ -507,7 +624,7 @@
msgid "no visible paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/pictogram.py:134
+#: ./src/pyams_content/component/paragraph/pictogram.py:135
msgid "Selected pictogram is missing"
msgstr ""
@@ -515,62 +632,62 @@
msgid "Milestones..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:88
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:90
msgid "Add new milestone paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:120
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:117
msgid "Edit milestone paragraph properties"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:258
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:243
#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:49
msgid "Associated label"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:270
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:255
#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:53
msgid "Anchor"
msgstr ""
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:284
+#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:76
+msgid "Milestones"
+msgstr ""
+
#: ./src/pyams_content/component/paragraph/zmi/milestone.py:299
-#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:76
-msgid "Milestones"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:314
msgid "Add milestone"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:325
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:312
msgid "Add new milestone"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:358
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:339
msgid "Edit milestone properties"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:347
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:327
msgid "Milestone was correctly added"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/milestone.py:285
+#: ./src/pyams_content/component/paragraph/zmi/milestone.py:270
msgid "(missing paragraph)"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:50
+#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:51
msgid "Key points..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:61
+#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:64
msgid "Add new key points paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:93
+#: ./src/pyams_content/component/paragraph/zmi/keypoint.py:91
msgid "Edit key points paragraph properties"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:66
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:65
msgid "Content block types..."
msgstr ""
@@ -578,7 +695,7 @@
msgid "Content block types"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:96
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:89
msgid ""
"You can define which types of paragraphs are allowed in this container.\n"
"\n"
@@ -587,228 +704,174 @@
"NOTICE: removing types from allowed types list will have no effect on already created contents!"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:214
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:207
#: ./src/pyams_content/shared/common/zmi/templates/preview-input.pt:39
#: ./src/pyams_content/features/preview/zmi/__init__.py:45
msgid "Preview"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:219
-#: ./src/pyams_content/shared/common/zmi/workflow.py:125
-#: ./src/pyams_content/shared/common/zmi/workflow.py:217
-#: ./src/pyams_content/shared/common/zmi/workflow.py:262
-#: ./src/pyams_content/shared/common/zmi/workflow.py:321
-#: ./src/pyams_content/shared/common/zmi/workflow.py:415
-#: ./src/pyams_content/shared/common/zmi/workflow.py:476
-#: ./src/pyams_content/shared/common/zmi/workflow.py:521
-#: ./src/pyams_content/shared/common/zmi/workflow.py:567
-#: ./src/pyams_content/shared/common/zmi/workflow.py:615
-#: ./src/pyams_content/shared/common/zmi/workflow.py:660
-#: ./src/pyams_content/shared/common/zmi/workflow.py:706
-#: ./src/pyams_content/shared/common/zmi/workflow.py:762
-#: ./src/pyams_content/shared/common/zmi/__init__.py:276
-#: ./src/pyams_content/shared/common/zmi/owner.py:74
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:212
+#: ./src/pyams_content/shared/common/zmi/workflow.py:122
+#: ./src/pyams_content/shared/common/zmi/workflow.py:209
+#: ./src/pyams_content/shared/common/zmi/workflow.py:249
+#: ./src/pyams_content/shared/common/zmi/workflow.py:303
+#: ./src/pyams_content/shared/common/zmi/workflow.py:392
+#: ./src/pyams_content/shared/common/zmi/workflow.py:448
+#: ./src/pyams_content/shared/common/zmi/workflow.py:488
+#: ./src/pyams_content/shared/common/zmi/workflow.py:529
+#: ./src/pyams_content/shared/common/zmi/workflow.py:572
+#: ./src/pyams_content/shared/common/zmi/workflow.py:612
+#: ./src/pyams_content/shared/common/zmi/workflow.py:653
+#: ./src/pyams_content/shared/common/zmi/workflow.py:704
+#: ./src/pyams_content/shared/common/zmi/__init__.py:275
+#: ./src/pyams_content/shared/common/zmi/owner.py:73
#: ./src/pyams_content/features/review/zmi/__init__.py:90
msgid "Cancel"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:221
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:214
msgid "Submit"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/__init__.py:202
+#: ./src/pyams_content/component/paragraph/zmi/__init__.py:195
msgid "Paragraph was correctly added."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/video.py:54
+#: ./src/pyams_content/component/paragraph/zmi/video.py:53
msgid "Video paragraph..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/video.py:65
+#: ./src/pyams_content/component/paragraph/zmi/video.py:66
msgid "Add new video paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/video.py:112
-#: ./src/pyams_content/component/video/zmi/paragraph.py:209
+#: ./src/pyams_content/component/paragraph/zmi/video.py:94
+#: ./src/pyams_content/component/video/zmi/paragraph.py:192
msgid "Edit video properties"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/video.py:83
-#: ./src/pyams_content/component/paragraph/zmi/video.py:133
-#: ./src/pyams_content/component/paragraph/zmi/audio.py:83
-#: ./src/pyams_content/component/paragraph/zmi/audio.py:133
-#: ./src/pyams_content/component/video/zmi/paragraph.py:103
-#: ./src/pyams_content/component/video/zmi/paragraph.py:238
-msgid "HTML content"
-msgstr ""
-
#: ./src/pyams_content/component/paragraph/zmi/container.py:74
msgid "Contents..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:240
+#: ./src/pyams_content/component/paragraph/zmi/container.py:239
msgid "Show/hide all paragraphs"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:288
-#: ./src/pyams_content/component/paragraph/zmi/container.py:297
-#: ./src/pyams_content/component/paragraph/zmi/container.py:310
+#: ./src/pyams_content/component/paragraph/zmi/container.py:287
+#: ./src/pyams_content/component/paragraph/zmi/container.py:296
+#: ./src/pyams_content/component/paragraph/zmi/container.py:309
msgid "Content blocks"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:367
+#: ./src/pyams_content/component/paragraph/zmi/container.py:366
msgid "Links and attachments..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:379
+#: ./src/pyams_content/component/paragraph/zmi/container.py:378
msgid "Content blocks links and attachments"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:127
+#: ./src/pyams_content/component/paragraph/zmi/container.py:126
msgid "No currently defined paragraph."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:249
+#: ./src/pyams_content/component/paragraph/zmi/container.py:248
msgid "Click to open/close all paragraphs editors"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:262
+#: ./src/pyams_content/component/paragraph/zmi/container.py:261
msgid "Click to open/close paragraph editor"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/container.py:133
+#: ./src/pyams_content/component/paragraph/zmi/container.py:132
msgid "Check allowed paragraph types to be able to create new paragraphs."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:83
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:82
msgid "Pictograms..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:94
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:95
msgid "Add new pictogram paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:126
+#: ./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:268
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:252
msgid "pictogram-item-header"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:283
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:263
-#: ./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:305
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:289
#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:80
msgid "Pictograms"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:320
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:62
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:304
+#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:59
msgid "Add pictogram"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:331
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:73
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:317
+#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:71
msgid "Add new pictogram"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:393
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:103
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:359
+#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:95
msgid "Edit pictogram properties"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:374
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:339
msgid "Pictogram was correctly added"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:384
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:448
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:349
+#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:387
msgid "You must select a pictogram!"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:347
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:186
-msgid "Default header: --"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/pictogram.py:414
-#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:190
-#, python-format
-msgid "Default header: {0}"
-msgstr ""
-
#: ./src/pyams_content/component/paragraph/zmi/audio.py:54
msgid "Audio paragraph..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/audio.py:65
+#: ./src/pyams_content/component/paragraph/zmi/audio.py:67
msgid "Add new audio paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/audio.py:112
+#: ./src/pyams_content/component/paragraph/zmi/audio.py:108
msgid "Edit audio properties"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:76
+#: ./src/pyams_content/component/paragraph/zmi/audio.py:84
+#: ./src/pyams_content/component/paragraph/zmi/audio.py:128
+msgid "HTML content"
+msgstr ""
+
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:55
msgid "Key numbers..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:87
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:68
msgid "Add new key number paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:119
+#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:96
msgid "Edit key number paragraph properties"
msgstr ""
-#: ./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:251
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:49
-msgid "key-number-label"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:282
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:76
-msgid "Key numbers"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:297
-msgid "Add keynumber"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:308
-msgid "Add new keynumber"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:341
-msgid "Edit keynumber properties"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/zmi/keynumber.py:330
-msgid "Key number was correctly added"
-msgstr ""
-
#: ./src/pyams_content/component/paragraph/zmi/frame.py:84
msgid "Framed text..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/frame.py:96
+#: ./src/pyams_content/component/paragraph/zmi/frame.py:98
msgid "Add new framed text paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/frame.py:132
+#: ./src/pyams_content/component/paragraph/zmi/frame.py:129
msgid "Edit framed text paragraph properties"
msgstr ""
@@ -816,11 +879,11 @@
msgid "Verbatim..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:67
+#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:69
msgid "Add new verbatim paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:99
+#: ./src/pyams_content/component/paragraph/zmi/verbatim.py:96
msgid "Edit verbatim paragraph properties"
msgstr ""
@@ -828,23 +891,23 @@
msgid "Raw HTML..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/html.py:87
+#: ./src/pyams_content/component/paragraph/zmi/html.py:89
msgid "Add new raw HTML paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/html.py:122
+#: ./src/pyams_content/component/paragraph/zmi/html.py:119
msgid "Edit raw HTML paragraph properties"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/html.py:174
+#: ./src/pyams_content/component/paragraph/zmi/html.py:159
msgid "Rich text..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/html.py:185
+#: ./src/pyams_content/component/paragraph/zmi/html.py:172
msgid "Add new rich text paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/html.py:220
+#: ./src/pyams_content/component/paragraph/zmi/html.py:202
msgid "Edit rich text paragraph properties"
msgstr ""
@@ -852,11 +915,11 @@
msgid "Contact card..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/contact.py:64
+#: ./src/pyams_content/component/paragraph/zmi/contact.py:66
msgid "Add new contact card"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/contact.py:97
+#: ./src/pyams_content/component/paragraph/zmi/contact.py:94
msgid "Edit contact card properties"
msgstr ""
@@ -864,25 +927,14 @@
msgid "Header..."
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/header.py:61
+#: ./src/pyams_content/component/paragraph/zmi/header.py:63
msgid "Add new header paragraph"
msgstr ""
-#: ./src/pyams_content/component/paragraph/zmi/header.py:93
+#: ./src/pyams_content/component/paragraph/zmi/header.py:90
msgid "Edit header paragraph properties"
msgstr ""
-#: ./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:117
-#: ./src/pyams_content/features/alert/interfaces.py:54
-msgid "Visible?"
-msgstr ""
-
#: ./src/pyams_content/component/paragraph/interfaces/milestone.py:41
msgid "Is this milestone visible in front-office?"
msgstr ""
@@ -947,8 +999,8 @@
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
+#: ./src/pyams_content/shared/common/zmi/types.py:169
+#: ./src/pyams_content/shared/common/zmi/types.py:380
msgid "Default paragraphs"
msgstr ""
@@ -956,14 +1008,7 @@
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/audio.py:41
-#: ./src/pyams_content/component/paragraph/interfaces/html.py:63
-#: ./src/pyams_content/component/video/interfaces/__init__.py:75
-msgid "Body"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/video.py:53
+#: ./src/pyams_content/component/paragraph/interfaces/video.py:42
msgid "Video file content"
msgstr ""
@@ -982,7 +1027,8 @@
msgstr ""
#: ./src/pyams_content/component/paragraph/interfaces/pictogram.py:46
-#: ./src/pyams_content/shared/common/interfaces/types.py:67
+#: ./src/pyams_content/component/links/interfaces/__init__.py:43
+#: ./src/pyams_content/shared/common/interfaces/types.py:68
#: ./src/pyams_content/features/alert/interfaces.py:79
msgid "Pictogram"
msgstr ""
@@ -1018,6 +1064,11 @@
msgid "Audio"
msgstr ""
+#: ./src/pyams_content/component/paragraph/interfaces/audio.py:41
+#: ./src/pyams_content/component/paragraph/interfaces/html.py:63
+msgid "Body"
+msgstr ""
+
#: ./src/pyams_content/component/paragraph/interfaces/audio.py:56
msgid "Audio template"
msgstr ""
@@ -1026,28 +1077,11 @@
msgid "Presentation template used for this audio file"
msgstr ""
-#: ./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:46
-msgid "Key number value"
-msgstr ""
-
-#: ./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:55
-msgid "The way this text will be rendered depends on presentation template"
-msgstr ""
-
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:83
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:36
msgid "Key numbers template"
msgstr ""
-#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:84
+#: ./src/pyams_content/component/paragraph/interfaces/keynumber.py:37
msgid "Presentation template used for key numbers"
msgstr ""
@@ -1203,8 +1237,8 @@
msgid "no defined theme"
msgstr ""
-#: ./src/pyams_content/component/theme/zmi/__init__.py:52
-#: ./src/pyams_content/shared/view/zmi/theme.py:49
+#: ./src/pyams_content/component/theme/zmi/__init__.py:51
+#: ./src/pyams_content/shared/view/zmi/theme.py:48
msgid "Themes..."
msgstr ""
@@ -1212,7 +1246,7 @@
msgid "Content themes"
msgstr ""
-#: ./src/pyams_content/component/theme/zmi/manager.py:46
+#: ./src/pyams_content/component/theme/zmi/manager.py:45
msgid "Themes settings..."
msgstr ""
@@ -1222,20 +1256,20 @@
#: ./src/pyams_content/component/association/container.py:88
#: ./src/pyams_content/component/association/zmi/__init__.py:296
-#: ./src/pyams_content/component/association/interfaces/__init__.py:86
+#: ./src/pyams_content/component/association/interfaces/__init__.py:90
msgid "Associations"
msgstr ""
#: ./src/pyams_content/component/association/zmi/paragraph.py:54
-#: ./src/pyams_content/component/association/zmi/__init__.py:95
+#: ./src/pyams_content/component/association/zmi/__init__.py:96
msgid "Associations..."
msgstr ""
-#: ./src/pyams_content/component/association/zmi/paragraph.py:65
+#: ./src/pyams_content/component/association/zmi/paragraph.py:67
msgid "Add new association paragraph"
msgstr ""
-#: ./src/pyams_content/component/association/zmi/paragraph.py:97
+#: ./src/pyams_content/component/association/zmi/paragraph.py:93
msgid "Edit association paragraph properties"
msgstr ""
@@ -1256,129 +1290,134 @@
msgid "Associations list"
msgstr ""
-#: ./src/pyams_content/component/association/zmi/__init__.py:65
+#: ./src/pyams_content/component/association/zmi/__init__.py:66
msgid "Association was correctly added."
msgstr ""
#: ./src/pyams_content/component/association/interfaces/__init__.py:43
+#: ./src/pyams_content/features/menu/interfaces/__init__.py:59
msgid "Is this item visible in front-office?"
msgstr ""
-#: ./src/pyams_content/component/association/interfaces/__init__.py:93
+#: ./src/pyams_content/component/association/interfaces/__init__.py:97
msgid "Associations template"
msgstr ""
-#: ./src/pyams_content/component/association/interfaces/__init__.py:94
+#: ./src/pyams_content/component/association/interfaces/__init__.py:98
msgid "Presentation template used for associations"
msgstr ""
-#: ./src/pyams_content/component/links/__init__.py:104
+#: ./src/pyams_content/component/links/__init__.py:125
msgid "Internal link"
msgstr ""
-#: ./src/pyams_content/component/links/__init__.py:186
+#: ./src/pyams_content/component/links/__init__.py:207
msgid "External link"
msgstr ""
-#: ./src/pyams_content/component/links/__init__.py:239
+#: ./src/pyams_content/component/links/__init__.py:260
msgid "Mailto link"
msgstr ""
-#: ./src/pyams_content/component/links/__init__.py:173
+#: ./src/pyams_content/component/links/__init__.py:194
msgid "target is not published"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:57
+#: ./src/pyams_content/component/links/zmi/__init__.py:60
msgid "Internal links"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:72
+#: ./src/pyams_content/component/links/zmi/__init__.py:75
msgid "Add internal link"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:84
+#: ./src/pyams_content/component/links/zmi/__init__.py:89
msgid "Add new internal link"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:122
+#: ./src/pyams_content/component/links/zmi/__init__.py:125
msgid "Edit internal link properties"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:160
+#: ./src/pyams_content/component/links/zmi/__init__.py:159
msgid "External links"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:175
+#: ./src/pyams_content/component/links/zmi/__init__.py:174
msgid "Add external link"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:187
+#: ./src/pyams_content/component/links/zmi/__init__.py:188
msgid "Add new external link"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:225
+#: ./src/pyams_content/component/links/zmi/__init__.py:224
msgid "Edit external link properties"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:263
+#: ./src/pyams_content/component/links/zmi/__init__.py:258
msgid "Mailto links"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:278
+#: ./src/pyams_content/component/links/zmi/__init__.py:273
msgid "Add mailto link"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:290
+#: ./src/pyams_content/component/links/zmi/__init__.py:287
msgid "Add new mailto link"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/__init__.py:328
+#: ./src/pyams_content/component/links/zmi/__init__.py:323
msgid "Edit mailto link properties"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/reverse.py:55
+#: ./src/pyams_content/component/links/zmi/reverse.py:57
msgid "Reverse links"
msgstr ""
-#: ./src/pyams_content/component/links/zmi/reverse.py:64
+#: ./src/pyams_content/component/links/zmi/reverse.py:66
msgid "Content's internal links"
msgstr ""
-#: ./src/pyams_content/component/links/interfaces/__init__.py:34
+#: ./src/pyams_content/component/links/interfaces/__init__.py:36
msgid "Link title, as shown in front-office"
msgstr ""
-#: ./src/pyams_content/component/links/interfaces/__init__.py:38
+#: ./src/pyams_content/component/links/interfaces/__init__.py:40
msgid "Link description displayed by front-office template"
msgstr ""
-#: ./src/pyams_content/component/links/interfaces/__init__.py:55
+#: ./src/pyams_content/component/links/interfaces/__init__.py:44
+msgid "Name of the pictogram associated with this link"
+msgstr ""
+
+#: ./src/pyams_content/component/links/interfaces/__init__.py:64
#: ./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/component/links/interfaces/__init__.py:65
#: ./src/pyams_content/shared/logo/interfaces/__init__.py:51
msgid "URL used to access external resource"
msgstr ""
-#: ./src/pyams_content/component/links/interfaces/__init__.py:60
-msgid "Language used in this remote resource"
-msgstr ""
-
-#: ./src/pyams_content/component/links/interfaces/__init__.py:68
-msgid "Target address"
-msgstr ""
-
#: ./src/pyams_content/component/links/interfaces/__init__.py:69
+msgid "Language used in this remote resource"
+msgstr ""
+
+#: ./src/pyams_content/component/links/interfaces/__init__.py:77
+msgid "Target address"
+msgstr ""
+
+#: ./src/pyams_content/component/links/interfaces/__init__.py:78
msgid "Target email address"
msgstr ""
-#: ./src/pyams_content/component/links/interfaces/__init__.py:72
+#: ./src/pyams_content/component/links/interfaces/__init__.py:81
msgid "Address name"
msgstr ""
-#: ./src/pyams_content/component/links/interfaces/__init__.py:73
+#: ./src/pyams_content/component/links/interfaces/__init__.py:82
msgid "Address as displayed in address book"
msgstr ""
@@ -1623,24 +1662,24 @@
msgid "Youtube settings"
msgstr ""
-#: ./src/pyams_content/component/video/zmi/paragraph.py:61
+#: ./src/pyams_content/component/video/zmi/paragraph.py:62
msgid "External video..."
msgstr ""
-#: ./src/pyams_content/component/video/zmi/paragraph.py:72
+#: ./src/pyams_content/component/video/zmi/paragraph.py:75
msgid "Add new external video..."
msgstr ""
-#: ./src/pyams_content/component/video/zmi/paragraph.py:145
+#: ./src/pyams_content/component/video/zmi/paragraph.py:126
msgid "Video provider is required"
msgstr ""
-#: ./src/pyams_content/component/video/zmi/paragraph.py:194
-#: ./src/pyams_content/component/video/zmi/paragraph.py:259
+#: ./src/pyams_content/component/video/zmi/paragraph.py:175
+#: ./src/pyams_content/component/video/zmi/paragraph.py:229
msgid "Video provider settings"
msgstr ""
-#: ./src/pyams_content/component/video/zmi/paragraph.py:174
+#: ./src/pyams_content/component/video/zmi/paragraph.py:155
msgid "Other settings"
msgstr ""
@@ -1652,19 +1691,19 @@
msgid "Name of external platform providing selected video"
msgstr ""
-#: ./src/pyams_content/shared/common/__init__.py:237
-#: ./src/pyams_content/shared/common/zmi/properties.py:72
-#: ./src/pyams_content/shared/common/zmi/manager.py:97
+#: ./src/pyams_content/shared/common/__init__.py:240
+#: ./src/pyams_content/shared/common/zmi/properties.py:70
+#: ./src/pyams_content/shared/common/zmi/manager.py:96
msgid "Properties"
msgstr ""
-#: ./src/pyams_content/shared/common/__init__.py:147
-#: ./src/pyams_content/shared/common/__init__.py:155
+#: ./src/pyams_content/shared/common/__init__.py:150
+#: ./src/pyams_content/shared/common/__init__.py:158
#, python-format
msgid "{date} by {principal}"
msgstr ""
-#: ./src/pyams_content/shared/common/__init__.py:260
+#: ./src/pyams_content/shared/common/__init__.py:263
#, python-format
msgid "title length should be between 40 and 66 characters ({length} actually)"
msgstr ""
@@ -1717,11 +1756,11 @@
msgid "Modified before..."
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/properties.py:62
+#: ./src/pyams_content/shared/common/zmi/properties.py:60
msgid "Composition"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/properties.py:83
+#: ./src/pyams_content/shared/common/zmi/properties.py:82
msgid "Content properties"
msgstr ""
@@ -1733,40 +1772,40 @@
msgid "Data type label"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:183
-#: ./src/pyams_content/shared/common/zmi/types.py:411
+#: ./src/pyams_content/shared/common/zmi/types.py:185
+#: ./src/pyams_content/shared/common/zmi/types.py:396
msgid "Default associations"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:211
+#: ./src/pyams_content/shared/common/zmi/types.py:213
msgid "Content data types"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:234
+#: ./src/pyams_content/shared/common/zmi/types.py:236
msgid "Add data type"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:245
+#: ./src/pyams_content/shared/common/zmi/types.py:248
msgid "Add new data type"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:291
+#: ./src/pyams_content/shared/common/zmi/types.py:285
msgid "Data type properties"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:374
+#: ./src/pyams_content/shared/common/zmi/types.py:359
msgid "Subtype label"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:455
+#: ./src/pyams_content/shared/common/zmi/types.py:440
msgid "Add subtype"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:466
+#: ./src/pyams_content/shared/common/zmi/types.py:452
msgid "Add new subtype"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:518
+#: ./src/pyams_content/shared/common/zmi/types.py:498
msgid "Data subtype properties"
msgstr ""
@@ -1774,70 +1813,70 @@
msgid "No currently defined data type."
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:273
+#: ./src/pyams_content/shared/common/zmi/types.py:275
msgid "Specified type name is already used!"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:494
-msgid "Specified subtype name is already used!"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/zmi/types.py:505
+#: ./src/pyams_content/shared/common/zmi/types.py:474
msgid "Subtype was correctly added."
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/types.py:155
+#: ./src/pyams_content/shared/common/zmi/types.py:488
+msgid "Specified subtype name is already used!"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/types.py:157
msgid "Click to see subtypes"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:907
+#: ./src/pyams_content/shared/common/zmi/workflow.py:844
msgid "Prior checks"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:126
+#: ./src/pyams_content/shared/common/zmi/workflow.py:123
msgid "Request publication"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:218
+#: ./src/pyams_content/shared/common/zmi/workflow.py:210
#: ./src/pyams_content/workflow/__init__.py:315
msgid "Cancel publication request"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:263
+#: ./src/pyams_content/shared/common/zmi/workflow.py:250
msgid "Refuse publication request"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:322
+#: ./src/pyams_content/shared/common/zmi/workflow.py:304
#: ./src/pyams_content/workflow/basic.py:196
msgid "Publish"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:416
+#: ./src/pyams_content/shared/common/zmi/workflow.py:393
msgid "Request retire"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:477
+#: ./src/pyams_content/shared/common/zmi/workflow.py:449
msgid "Cancel retire request"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:522
+#: ./src/pyams_content/shared/common/zmi/workflow.py:489
msgid "Retire"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:568
+#: ./src/pyams_content/shared/common/zmi/workflow.py:530
#: ./src/pyams_content/workflow/__init__.py:436
msgid "Request archive"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:616
+#: ./src/pyams_content/shared/common/zmi/workflow.py:573
msgid "Cancel archive request"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:661
+#: ./src/pyams_content/shared/common/zmi/workflow.py:613
msgid "Archive"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:707
+#: ./src/pyams_content/shared/common/zmi/workflow.py:654
#: ./src/pyams_content/workflow/__init__.py:501
#: ./src/pyams_content/workflow/__init__.py:513
#: ./src/pyams_content/workflow/__init__.py:525
@@ -1848,50 +1887,50 @@
msgid "Create new version"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:763
+#: ./src/pyams_content/shared/common/zmi/workflow.py:705
#: ./src/pyams_content/workflow/__init__.py:561
#: ./src/pyams_content/workflow/basic.py:248
msgid "Delete version"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:853
+#: ./src/pyams_content/shared/common/zmi/workflow.py:790
msgid "Previewed content?"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:857
+#: ./src/pyams_content/shared/common/zmi/workflow.py:794
msgid "Verified content?"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:188
-#: ./src/pyams_content/shared/common/zmi/workflow.py:385
+#: ./src/pyams_content/shared/common/zmi/workflow.py:180
+#: ./src/pyams_content/shared/common/zmi/workflow.py:362
msgid "Publication start date is required"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:291
-#: ./src/pyams_content/shared/common/zmi/workflow.py:447
+#: ./src/pyams_content/shared/common/zmi/workflow.py:273
+#: ./src/pyams_content/shared/common/zmi/workflow.py:419
msgid "A comment is required"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:786
+#: ./src/pyams_content/shared/common/zmi/workflow.py:729
msgid "Delete content"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:795
+#: ./src/pyams_content/shared/common/zmi/workflow.py:738
msgid "Delete definitively"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:923
+#: ./src/pyams_content/shared/common/zmi/workflow.py:860
msgid ""
"You must confirm that you previewed and checked this content before "
"requesting publication!!"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:90
+#: ./src/pyams_content/shared/common/zmi/workflow.py:87
#, python-format
msgid "{state} | by {principal}"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/workflow.py:86
+#: ./src/pyams_content/shared/common/zmi/workflow.py:83
#: ./src/pyams_content/workflow/__init__.py:648
#: ./src/pyams_content/workflow/__init__.py:619
#: ./src/pyams_content/workflow/basic.py:315
@@ -1900,7 +1939,7 @@
msgid "{state} {date}"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/__init__.py:266
+#: ./src/pyams_content/shared/common/zmi/__init__.py:265
msgid "Duplicate content..."
msgstr ""
@@ -1908,20 +1947,20 @@
msgid "Duplicate content"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/__init__.py:85
+#: ./src/pyams_content/shared/common/zmi/__init__.py:84
msgid "This title can be modified afterwards"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/__init__.py:277
+#: ./src/pyams_content/shared/common/zmi/__init__.py:276
msgid "Duplicate this content"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/__init__.py:338
+#: ./src/pyams_content/shared/common/zmi/__init__.py:337
#, python-format
msgid "Clone created from version {source} of {oid} (in « {state} » state)"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/__init__.py:389
+#: ./src/pyams_content/shared/common/zmi/__init__.py:382
msgid "Created or modified in this version"
msgstr ""
@@ -1972,39 +2011,39 @@
msgid "Shared tool properties"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/manager.py:132
+#: ./src/pyams_content/shared/common/zmi/manager.py:125
msgid "WARNING"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/manager.py:134
+#: ./src/pyams_content/shared/common/zmi/manager.py:127
msgid ""
"Workflow shouldn't be modified if this tool already contains any shared "
"content!"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/manager.py:157
+#: ./src/pyams_content/shared/common/zmi/manager.py:150
msgid "Languages"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/manager.py:168
+#: ./src/pyams_content/shared/common/zmi/manager.py:162
msgid "Content languages"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/manager.py:185
+#: ./src/pyams_content/shared/common/zmi/manager.py:172
msgid ""
"Tool languages are used to translate own tool properties, and newly created "
"contents will propose these languages by default"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/manager.py:81
+#: ./src/pyams_content/shared/common/zmi/manager.py:80
msgid "Content management"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/manager.py:83
+#: ./src/pyams_content/shared/common/zmi/manager.py:82
msgid "Tool management"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/owner.py:51
+#: ./src/pyams_content/shared/common/zmi/owner.py:50
msgid "Change owner..."
msgstr ""
@@ -2012,38 +2051,75 @@
msgid "Change content's owner"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/owner.py:132
+#: ./src/pyams_content/shared/common/zmi/owner.py:125
msgid ""
"All versions of this content which are not archived will be transferred to "
"newly selected owner"
msgstr ""
+#: ./src/pyams_content/shared/common/zmi/owner.py:60
+msgid "New owner"
+msgstr ""
+
#: ./src/pyams_content/shared/common/zmi/owner.py:61
-msgid "New owner"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/zmi/owner.py:62
msgid "The selected user will become the new content's owner"
msgstr ""
+#: ./src/pyams_content/shared/common/zmi/owner.py:63
+msgid "Keep previous owner as contributor"
+msgstr ""
+
#: ./src/pyams_content/shared/common/zmi/owner.py:64
-msgid "Keep previous owner as contributor"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/zmi/owner.py:65
msgid "If 'yes', the previous owner will still be able to modify this content"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/owner.py:75
+#: ./src/pyams_content/shared/common/zmi/owner.py:74
msgid "Change owner"
msgstr ""
+#: ./src/pyams_content/shared/common/zmi/rename.py:62
+msgid "Change URL..."
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/rename.py:79
+msgid "Change item URL"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/rename.py:86
+msgid "Item URL part"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/rename.py:87
+msgid "URL part used to access this content"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/rename.py:121
+msgid "You must provide an URL for this item!"
+msgstr ""
+
#: ./src/pyams_content/shared/common/zmi/site.py:38
#, python-format
msgid ""
"SEARCH - Between all contents published into « {site} »"
msgstr ""
+#: ./src/pyams_content/shared/common/zmi/portal.py:46
+msgid "Edit default template properties"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/portal.py:56
+msgid ""
+"**This form allows you to select shared content default template.**\n"
+"\n"
+"If you choose to use a shared template, you can only adjust settings of each portlet individually but can't change portlets list or page configuration.\n"
+"\n"
+"If you use a local template, you can define a whole custom configuration but the template definition can't be reused anywhere..."
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/portal.py:72
+msgid "Override tool default template"
+msgstr ""
+
#: ./src/pyams_content/shared/common/zmi/dashboard.py:134
msgid "Unique ID"
msgstr ""
@@ -2061,7 +2137,7 @@
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:273
-#: ./src/pyams_content/root/zmi/__init__.py:91
+#: ./src/pyams_content/root/zmi/__init__.py:110
msgid "Dashboard"
msgstr ""
@@ -2070,55 +2146,55 @@
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:329
-#: ./src/pyams_content/root/zmi/__init__.py:140
+#: ./src/pyams_content/root/zmi/__init__.py:159
#, python-format
msgid "MANAGER - {0} content waiting for your action"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:330
-#: ./src/pyams_content/root/zmi/__init__.py:141
+#: ./src/pyams_content/root/zmi/__init__.py:160
#, python-format
msgid "MANAGER - {0} contents waiting for your action"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:370
-#: ./src/pyams_content/root/zmi/__init__.py:184
+#: ./src/pyams_content/root/zmi/__init__.py:203
#, python-format
msgid "CONTRIBUTOR - {0} content waiting for action"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:371
-#: ./src/pyams_content/root/zmi/__init__.py:185
+#: ./src/pyams_content/root/zmi/__init__.py:204
#, python-format
msgid "CONTRIBUTOR - {0} contents waiting for action"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:402
-#: ./src/pyams_content/root/zmi/__init__.py:219
+#: ./src/pyams_content/root/zmi/__init__.py:238
#, python-format
msgid "CONTRIBUTOR - {0} modified content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:443
-#: ./src/pyams_content/root/zmi/__init__.py:262
+#: ./src/pyams_content/root/zmi/__init__.py:281
msgid "My contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:458
#: ./src/pyams_content/shared/common/zmi/templates/dashboard.pt:8
-#: ./src/pyams_content/root/zmi/__init__.py:277
+#: ./src/pyams_content/root/zmi/__init__.py:296
#: ./src/pyams_content/root/zmi/templates/dashboard.pt:8
msgid "My favorites"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:467
-#: ./src/pyams_content/root/zmi/__init__.py:286
+#: ./src/pyams_content/root/zmi/__init__.py:305
#, python-format
msgid "CONTRIBUTOR - {0} favorite"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:468
-#: ./src/pyams_content/root/zmi/__init__.py:287
+#: ./src/pyams_content/root/zmi/__init__.py:306
#, python-format
msgid "CONTRIBUTOR - {0} favorites"
msgstr ""
@@ -2129,188 +2205,188 @@
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:543
-#: ./src/pyams_content/root/zmi/__init__.py:325
+#: ./src/pyams_content/root/zmi/__init__.py:344
msgid "Your favorites"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:556
-#: ./src/pyams_content/root/zmi/__init__.py:338
+#: ./src/pyams_content/root/zmi/__init__.py:357
msgid "My preparations"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:565
-#: ./src/pyams_content/root/zmi/__init__.py:347
+#: ./src/pyams_content/root/zmi/__init__.py:366
#, python-format
msgid "CONTRIBUTOR - {0} prepared content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:566
-#: ./src/pyams_content/root/zmi/__init__.py:348
+#: ./src/pyams_content/root/zmi/__init__.py:367
#, python-format
msgid "CONTRIBUTOR - {0} prepared contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:605
-#: ./src/pyams_content/root/zmi/__init__.py:386
+#: ./src/pyams_content/root/zmi/__init__.py:405
msgid "Your prepared contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:618
-#: ./src/pyams_content/root/zmi/__init__.py:399
+#: ./src/pyams_content/root/zmi/__init__.py:418
msgid "My submissions"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:627
-#: ./src/pyams_content/root/zmi/__init__.py:408
+#: ./src/pyams_content/root/zmi/__init__.py:427
#, python-format
msgid "CONTRIBUTOR - {0} submitted content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:628
-#: ./src/pyams_content/root/zmi/__init__.py:409
+#: ./src/pyams_content/root/zmi/__init__.py:428
#, python-format
msgid "CONTRIBUTOR - {0} submitted contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:667
-#: ./src/pyams_content/root/zmi/__init__.py:447
+#: ./src/pyams_content/root/zmi/__init__.py:466
msgid "Your submitted contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:680
-#: ./src/pyams_content/root/zmi/__init__.py:460
+#: ./src/pyams_content/root/zmi/__init__.py:479
msgid "My publications"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:689
-#: ./src/pyams_content/root/zmi/__init__.py:469
+#: ./src/pyams_content/root/zmi/__init__.py:488
#, python-format
msgid "CONTRIBUTOR - {0} published content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:690
-#: ./src/pyams_content/root/zmi/__init__.py:470
+#: ./src/pyams_content/root/zmi/__init__.py:489
#, python-format
msgid "CONTRIBUTOR - {0} published contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:729
-#: ./src/pyams_content/root/zmi/__init__.py:508
+#: ./src/pyams_content/root/zmi/__init__.py:527
msgid "Your published contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:742
-#: ./src/pyams_content/root/zmi/__init__.py:521
+#: ./src/pyams_content/root/zmi/__init__.py:540
msgid "My retired contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:751
-#: ./src/pyams_content/root/zmi/__init__.py:530
+#: ./src/pyams_content/root/zmi/__init__.py:549
#, python-format
msgid "CONTRIBUTOR - {0} retired content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:752
-#: ./src/pyams_content/root/zmi/__init__.py:531
+#: ./src/pyams_content/root/zmi/__init__.py:550
#, python-format
msgid "CONTRIBUTOR - {0} retired contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:792
-#: ./src/pyams_content/root/zmi/__init__.py:570
+#: ./src/pyams_content/root/zmi/__init__.py:589
msgid "Your retired contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:805
-#: ./src/pyams_content/root/zmi/__init__.py:583
+#: ./src/pyams_content/root/zmi/__init__.py:602
msgid "My archived contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:814
-#: ./src/pyams_content/root/zmi/__init__.py:592
+#: ./src/pyams_content/root/zmi/__init__.py:611
#, python-format
msgid "CONTRIBUTOR - {0} archived content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:815
-#: ./src/pyams_content/root/zmi/__init__.py:593
+#: ./src/pyams_content/root/zmi/__init__.py:612
#, python-format
msgid "CONTRIBUTOR - {0} archived contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:861
-#: ./src/pyams_content/root/zmi/__init__.py:638
+#: ./src/pyams_content/root/zmi/__init__.py:657
msgid "Your archived contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:875
-#: ./src/pyams_content/root/zmi/__init__.py:652
+#: ./src/pyams_content/root/zmi/__init__.py:671
msgid "Other interventions"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:890
-#: ./src/pyams_content/root/zmi/__init__.py:667
+#: ./src/pyams_content/root/zmi/__init__.py:686
msgid "Last publications"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:899
-#: ./src/pyams_content/root/zmi/__init__.py:676
+#: ./src/pyams_content/root/zmi/__init__.py:695
#, python-format
msgid "CONTRIBUTORS - {0} published content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:945
-#: ./src/pyams_content/root/zmi/__init__.py:721
+#: ./src/pyams_content/root/zmi/__init__.py:740
msgid "Last published contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:958
-#: ./src/pyams_content/root/zmi/__init__.py:734
+#: ./src/pyams_content/root/zmi/__init__.py:753
msgid "Last updates"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:967
-#: ./src/pyams_content/root/zmi/__init__.py:743
+#: ./src/pyams_content/root/zmi/__init__.py:762
#, python-format
msgid "CONTRIBUTORS - {0} updated content"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:1012
-#: ./src/pyams_content/root/zmi/__init__.py:787
+#: ./src/pyams_content/root/zmi/__init__.py:806
msgid "Last updated contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:407
-#: ./src/pyams_content/root/zmi/__init__.py:224
+#: ./src/pyams_content/root/zmi/__init__.py:243
#, python-format
msgid "CONTRIBUTOR - {0} modified contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:409
-#: ./src/pyams_content/root/zmi/__init__.py:226
+#: ./src/pyams_content/root/zmi/__init__.py:245
#, python-format
msgid "CONTRIBUTOR - Last {0} modified contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:904
-#: ./src/pyams_content/root/zmi/__init__.py:681
+#: ./src/pyams_content/root/zmi/__init__.py:700
#, python-format
msgid "CONTRIBUTORS - Last {0} published contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:906
-#: ./src/pyams_content/root/zmi/__init__.py:683
+#: ./src/pyams_content/root/zmi/__init__.py:702
msgid "CONTRIBUTORS - Last published contents (in the limit of 50)"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:972
-#: ./src/pyams_content/root/zmi/__init__.py:748
+#: ./src/pyams_content/root/zmi/__init__.py:767
#, python-format
msgid "CONTRIBUTORS - Last {0} updated contents"
msgstr ""
#: ./src/pyams_content/shared/common/zmi/dashboard.py:974
-#: ./src/pyams_content/root/zmi/__init__.py:750
+#: ./src/pyams_content/root/zmi/__init__.py:769
msgid "CONTRIBUTORS - Last updated contents (in the limit of 50)"
msgstr ""
@@ -2324,64 +2400,62 @@
msgid "Content publication start date is not passed yet"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:65
+#: ./src/pyams_content/shared/common/zmi/security.py:64
msgid "Contributors restrictions"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:74
+#: ./src/pyams_content/shared/common/zmi/security.py:73
msgid "Content contributors restrictions"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:108
+#: ./src/pyams_content/shared/common/zmi/security.py:107
msgid "Contributor name"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:119
-#: ./src/pyams_content/shared/common/zmi/security.py:277
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:252
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:277
-msgid "Publication checks"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/zmi/security.py:225
+#: ./src/pyams_content/shared/common/zmi/security.py:118
+#: ./src/pyams_content/shared/common/zmi/security.py:270
+msgid "Activated publication checks?"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/zmi/security.py:218
msgid "Managers restrictions"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:234
+#: ./src/pyams_content/shared/common/zmi/security.py:227
msgid "Content managers restrictions"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:266
+#: ./src/pyams_content/shared/common/zmi/security.py:259
msgid "Manager name"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:294
+#: ./src/pyams_content/shared/common/zmi/security.py:287
msgid "Restricted"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:311
+#: ./src/pyams_content/shared/common/zmi/security.py:304
msgid "Owners"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:401
+#: ./src/pyams_content/shared/common/zmi/security.py:394
msgid "Publication workflow"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:168
+#: ./src/pyams_content/shared/common/zmi/security.py:167
#, python-format
msgid "Edit contributor restrictions for « {0} »"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:360
+#: ./src/pyams_content/shared/common/zmi/security.py:353
#, python-format
msgid "Edit manager restrictions for « {0} »"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:407
+#: ./src/pyams_content/shared/common/zmi/security.py:400
msgid "Apply contents restrictions"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/security.py:409
+#: ./src/pyams_content/shared/common/zmi/security.py:402
msgid ""
"You can specify which contents this manager will be able to manage. If you "
"specify several criteria, the manager will be able to manage contents for "
@@ -2451,9 +2525,10 @@
#: ./src/pyams_content/shared/common/zmi/templates/check-input.pt:34
#: ./src/pyams_content/shared/common/zmi/templates/preview-input.pt:34
-#: ./src/pyams_content/shared/common/interfaces/types.py:39
+#: ./src/pyams_content/shared/common/interfaces/types.py:40
#: ./src/pyams_content/shared/form/zmi/field.py:159
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:61
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:62
+#: ./src/pyams_content/features/menu/zmi/__init__.py:208
msgid "Label"
msgstr ""
@@ -2462,18 +2537,18 @@
msgid "Audit"
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/templates/dashboard.pt:28
-#: ./src/pyams_content/root/zmi/templates/dashboard.pt:28
+#: ./src/pyams_content/shared/common/zmi/templates/dashboard.pt:29
+#: ./src/pyams_content/root/zmi/templates/dashboard.pt:29
msgid "Quick search..."
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/templates/dashboard.pt:33
-#: ./src/pyams_content/root/zmi/templates/dashboard.pt:33
+#: ./src/pyams_content/shared/common/zmi/templates/dashboard.pt:35
+#: ./src/pyams_content/root/zmi/templates/dashboard.pt:35
msgid "Advanced search..."
msgstr ""
-#: ./src/pyams_content/shared/common/zmi/templates/dashboard.pt:46
-#: ./src/pyams_content/root/zmi/templates/dashboard.pt:46
+#: ./src/pyams_content/shared/common/zmi/templates/dashboard.pt:49
+#: ./src/pyams_content/root/zmi/templates/dashboard.pt:49
msgid "You are not actually concerned by any content."
msgstr ""
@@ -2645,79 +2720,91 @@
msgid "This content is already retired and not visible."
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:35
-#: ./src/pyams_content/shared/form/zmi/field.py:148
-msgid "Name"
+#: ./src/pyams_content/shared/common/portlet/content/__init__.py:44
+msgid "Context content"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/portlet/content/zmi/preview.pt:2
+msgid "This is where the content will be displayed!!"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/portlet/content/skin/__init__.py:36
+msgid "Default content renderer"
msgstr ""
#: ./src/pyams_content/shared/common/interfaces/types.py:36
+#: ./src/pyams_content/shared/form/zmi/field.py:148
+msgid "Name"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/types.py:37
msgid "Name of this data type; must be unique between all data types"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:42
-msgid "Navigation label"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/types.py:43
+msgid "Navigation label"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/types.py:44
msgid "Label used for navigation entries"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:46
-msgid "Tab-folder label"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/types.py:47
+msgid "Tab-folder label"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/types.py:48
msgid "Label used to include into tab folder"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:50
-msgid "'See also' label"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/types.py:51
+msgid "'See also' label"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/types.py:52
msgid ""
"This label can be used when contents of this type will be displayed in a 'See"
" also' entries block"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:55
+#: ./src/pyams_content/shared/common/interfaces/types.py:56
msgid "'Single value' label"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:56
+#: ./src/pyams_content/shared/common/interfaces/types.py:57
msgid "Label given to this type when a single value is displayed"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:59
-msgid "'Link to list' label"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/types.py:60
+msgid "'Link to list' label"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/types.py:61
msgid "Label used to display a link to a list of items of this type"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:63
-msgid "Next content label"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/types.py:64
+msgid "Next content label"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/types.py:65
msgid "Label used to announce next date for this type"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:68
+#: ./src/pyams_content/shared/common/interfaces/types.py:69
msgid "Image associated to this data type"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/types.py:81
-msgid "Field names"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/types.py:82
+msgid "Field names"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/types.py:83
msgid "List of fields associated with this data type"
msgstr ""
#: ./src/pyams_content/shared/common/interfaces/__init__.py:46
-#: ./src/pyams_content/root/interfaces/__init__.py:40
+#: ./src/pyams_content/root/interfaces/__init__.py:43
msgid "Webmasters"
msgstr ""
@@ -2736,19 +2823,19 @@
msgstr ""
#: ./src/pyams_content/shared/common/interfaces/__init__.py:57
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:174
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:187
msgid "Managers"
msgstr ""
#: ./src/pyams_content/shared/common/interfaces/__init__.py:58
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:175
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:188
msgid ""
"Managers can handle main operations in tool's workflow, like publish or "
"retire contents"
msgstr ""
#: ./src/pyams_content/shared/common/interfaces/__init__.py:63
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:180
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:193
msgid "Contributors"
msgstr ""
@@ -2756,159 +2843,174 @@
msgid "Contributors are users which are allowed to create new contents"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:90
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:68
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:199
+msgid "Designers"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:69
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:200
+msgid "Designers are users which are allowed to manage presentation templates"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:95
msgid "Workflow name"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:91
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:96
msgid "Name of workflow utility used to manage tool contents"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:115
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:124
msgid "Content URL"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:116
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:125
msgid ""
"URL used to access this content; this is important for SEO and should include"
" most important words describing content; spaces and underscores will be "
"automatically replaced by hyphens"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:121
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:130
msgid "Version creator"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:122
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:131
msgid ""
"Name of content's version creator. The creator of the first version is also "
"it's owner."
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:126
-msgid "First owner"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:127
-msgid "Name of content's first version owner"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:131
-msgid "Version creation"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:134
-msgid "Version modifiers"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/__init__.py:135
+msgid "First owner"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:136
+msgid "Name of content's first version owner"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:140
+msgid "Version creation"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:143
+msgid "Version modifiers"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:144
msgid "List of principals who modified this content"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:138
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:147
msgid "Last modifier"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:139
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:148
msgid "Last principal who modified this content"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:142
-msgid "Last update"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:146
-msgid ""
-"The content's description is 'hidden' into HTML's page headers; but it can be"
-" seen, for example, in some search engines results as content's description"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/__init__.py:151
-msgid "Keywords"
-msgstr ""
-
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:152
-msgid "They will be included into HTML pages metadata"
+msgid "Last update"
msgstr ""
#: ./src/pyams_content/shared/common/interfaces/__init__.py:155
-#: ./src/pyams_content/shared/site/zmi/folder.py:76
+msgid ""
+"The content's description is 'hidden' into HTML's page headers; but it can be"
+" seen, for example, in some search engines results as content's description"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:160
+msgid "Keywords"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:161
+msgid "They will be included into HTML pages metadata"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:164
+#: ./src/pyams_content/shared/site/zmi/folder.py:78
#: ./src/pyams_content/shared/site/interfaces/__init__.py:66
msgid "Notepad"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:156
-#: ./src/pyams_content/shared/site/zmi/folder.py:77
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:165
+#: ./src/pyams_content/shared/site/zmi/folder.py:79
#: ./src/pyams_content/shared/site/interfaces/__init__.py:67
msgid "Internal information to be known about this content"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:167
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:180
msgid "Content owner"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:168
-msgid ""
-"The owner is the creator of content's first version, except if it was "
-"transferred afterwards to another owner"
-msgstr ""
-
#: ./src/pyams_content/shared/common/interfaces/__init__.py:181
msgid ""
+"The owner is the creator of content's first version, except if it was "
+"transferred afterwards to another owner"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:194
+msgid ""
"Contributors are users which are allowed to update this content in addition "
"to it's owner"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:186
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:204
msgid "Readers"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:187
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:205
msgid ""
"Readers are users which are asked to verify and comment contents before they "
"are published"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:192
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:210
msgid "Guests"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:193
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:211
msgid ""
"Guests are users which are allowed to view contents with restricted access"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:213
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:231
msgid "Principal ID"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:253
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:270
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:295
+msgid "Publication checks"
+msgstr ""
+
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:271
msgid ""
"If 'yes', this contributor will have to confirm that contents have been "
"previewed and checked before asking for publication"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:278
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:296
msgid ""
"If 'yes', this manager will have to confirm that contents have been previewed"
" and checked before publishing a content"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:283
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:301
msgid "Restricted contents"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:284
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:302
msgid ""
"If 'yes', this manager will get restricted access to manage contents based on"
" selected settings"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:289
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:307
msgid "Selected owners"
msgstr ""
-#: ./src/pyams_content/shared/common/interfaces/__init__.py:290
+#: ./src/pyams_content/shared/common/interfaces/__init__.py:308
msgid "Manager will have access to contents owned by these principals"
msgstr ""
@@ -2995,7 +3097,7 @@
msgstr ""
#: ./src/pyams_content/shared/form/zmi/field.py:170
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:56
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:57
msgid "Field type"
msgstr ""
@@ -3004,11 +3106,11 @@
msgstr ""
#: ./src/pyams_content/shared/form/zmi/field.py:226
-#: ./src/pyams_content/shared/form/zmi/field.py:237
+#: ./src/pyams_content/shared/form/zmi/field.py:239
msgid "Add form field"
msgstr ""
-#: ./src/pyams_content/shared/form/zmi/field.py:285
+#: ./src/pyams_content/shared/form/zmi/field.py:281
msgid "Edit form field properties"
msgstr ""
@@ -3020,139 +3122,139 @@
msgid "No currently defined form field."
msgstr ""
-#: ./src/pyams_content/shared/form/zmi/field.py:262
+#: ./src/pyams_content/shared/form/zmi/field.py:266
msgid "Specified name is already used!"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:34
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:35
msgid "Form"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:52
-msgid "Field name"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:53
+msgid "Field name"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:54
msgid "Field internal name; must be unique for a given form"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:57
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:58
msgid "Selected field type"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:62
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:63
msgid "User field label"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:66
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:67
msgid "Field description can be displayed as hint"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:69
-msgid "Placeholder"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:70
+msgid "Placeholder"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:71
msgid "Some field types like textline can display a placeholder"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:73
-msgid "Optional values"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:74
+msgid "Optional values"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:75
msgid "List of available values (for 'choice' and 'list' field types)"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:77
-msgid "Default value"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:78
+msgid "Default value"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:79
msgid "Give default value if field type can use it"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:81
-msgid "Required?"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:82
+msgid "Required?"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:83
msgid "Select 'yes' to set field as mandatory"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:87
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:88
msgid "Select 'no' to hide given field..."
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:121
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:122
msgid "Form title"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:124
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:125
msgid "Form header"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:127
-msgid "Form handler"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:128
+msgid "Form handler"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:129
msgid "Select how form data is transmitted"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:131
-msgid "Authenticated only?"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:132
+msgid "Authenticated only?"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:133
msgid "If 'yes', only authenticated users will be able to see and submit form"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:136
-msgid "Use captcha?"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:137
+msgid "Use captcha?"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:138
msgid "If 'yes', a captcha will be added automatically to the form"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:141
-msgid "Submit label"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:142
+msgid "Submit label"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:143
msgid "Label of form submit button"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:179
-msgid "Source address"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:180
+msgid "Source address"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:181
msgid "Mail address from which form data is sent"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:183
-msgid "Source name"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:184
+msgid "Source name"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:185
msgid "Name of mail data sender"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:187
-msgid "Recipient address"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:188
+msgid "Recipient address"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:189
msgid "Mail address to which form data is sent"
msgstr ""
-#: ./src/pyams_content/shared/form/interfaces/__init__.py:191
-msgid "Recipient name"
-msgstr ""
-
#: ./src/pyams_content/shared/form/interfaces/__init__.py:192
+msgid "Recipient name"
+msgstr ""
+
+#: ./src/pyams_content/shared/form/interfaces/__init__.py:193
msgid "Name of data recipient"
msgstr ""
@@ -3170,7 +3272,7 @@
msgid "News topic « {title} »"
msgstr ""
-#: ./src/pyams_content/shared/news/interfaces/__init__.py:28
+#: ./src/pyams_content/shared/news/interfaces/__init__.py:29
msgid "News topic"
msgstr ""
@@ -3196,7 +3298,7 @@
msgid "View themes settings"
msgstr ""
-#: ./src/pyams_content/shared/view/zmi/reference.py:53
+#: ./src/pyams_content/shared/view/zmi/reference.py:52
msgid "References..."
msgstr ""
@@ -3204,15 +3306,7 @@
msgid "View internal references settings"
msgstr ""
-#: ./src/pyams_content/shared/view/zmi/templates/render.pt:2
-msgid "View result items"
-msgstr ""
-
-#: ./src/pyams_content/shared/view/zmi/templates/render.pt:3
-msgid "WARNING: items displayed in this preview are out of context!!"
-msgstr ""
-
-#: ./src/pyams_content/shared/view/portlet/__init__.py:56
+#: ./src/pyams_content/shared/view/portlet/__init__.py:58
msgid "View items"
msgstr ""
@@ -3229,7 +3323,7 @@
msgstr ""
#: ./src/pyams_content/shared/view/interfaces/__init__.py:40
-#: ./src/pyams_content/interfaces/__init__.py:111
+#: ./src/pyams_content/interfaces/__init__.py:113
#: ./src/pyams_content/features/review/interfaces.py:74
msgid "Creation date"
msgstr ""
@@ -3302,15 +3396,23 @@
msgid "Specify how selected references are included into view results"
msgstr ""
-#: ./src/pyams_content/shared/view/interfaces/__init__.py:171
-msgid "Select context themes?"
-msgstr ""
-
-#: ./src/pyams_content/shared/view/interfaces/__init__.py:172
-msgid "If 'yes', themes will be extracted from context"
+#: ./src/pyams_content/shared/view/interfaces/__init__.py:164
+msgid "Exclude context?"
+msgstr ""
+
+#: ./src/pyams_content/shared/view/interfaces/__init__.py:165
+msgid "If 'yes', context will be excluded from results list"
msgstr ""
#: ./src/pyams_content/shared/view/interfaces/__init__.py:176
+msgid "Select context themes?"
+msgstr ""
+
+#: ./src/pyams_content/shared/view/interfaces/__init__.py:177
+msgid "If 'yes', themes will be extracted from context"
+msgstr ""
+
+#: ./src/pyams_content/shared/view/interfaces/__init__.py:181
msgid "Other terms"
msgstr ""
@@ -3336,12 +3438,12 @@
msgid "Image map..."
msgstr ""
-#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:65
+#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:67
msgid "Add new image map"
msgstr ""
-#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:97
-#: ./src/pyams_content/shared/logo/zmi/paragraph.py:96
+#: ./src/pyams_content/shared/imagemap/zmi/paragraph.py:94
+#: ./src/pyams_content/shared/logo/zmi/paragraph.py:93
msgid "Edit paragraph properties"
msgstr ""
@@ -3401,15 +3503,15 @@
msgid "Bad query object_name parameter value!"
msgstr ""
-#: ./src/pyams_content/shared/imagemap/zmi/area.py:46
+#: ./src/pyams_content/shared/imagemap/zmi/area.py:47
msgid "Add image area"
msgstr ""
-#: ./src/pyams_content/shared/imagemap/zmi/area.py:64
+#: ./src/pyams_content/shared/imagemap/zmi/area.py:66
msgid "Add new image area"
msgstr ""
-#: ./src/pyams_content/shared/imagemap/zmi/area.py:108
+#: ./src/pyams_content/shared/imagemap/zmi/area.py:107
msgid "Edit image map properties"
msgstr ""
@@ -3455,7 +3557,7 @@
msgid "Image map template"
msgstr ""
-#: ./src/pyams_content/shared/site/folder.py:58
+#: ./src/pyams_content/shared/site/folder.py:59
msgid "Site folder"
msgstr ""
@@ -3463,39 +3565,44 @@
msgid "Content link"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:59
+#: ./src/pyams_content/shared/site/manager.py:68
+#: ./src/pyams_content/shared/site/zmi/manager.py:125
+msgid "Site manager"
+msgstr ""
+
+#: ./src/pyams_content/shared/site/zmi/folder.py:61
msgid "Add site folder..."
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:90
+#: ./src/pyams_content/shared/site/zmi/folder.py:93
msgid "Add site folder"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:166
+#: ./src/pyams_content/shared/site/zmi/folder.py:162
msgid "Site folder management"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:177
+#: ./src/pyams_content/shared/site/zmi/folder.py:190
msgid "Site folder properties"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:69
-#: ./src/pyams_content/interfaces/__init__.py:100
+#: ./src/pyams_content/shared/site/zmi/folder.py:71
+#: ./src/pyams_content/interfaces/__init__.py:102
msgid "Visible label used to display content"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:72
+#: ./src/pyams_content/shared/site/zmi/folder.py:74
#: ./src/pyams_content/shared/site/zmi/__init__.py:72
-#: ./src/pyams_content/shared/site/zmi/link.py:67
+#: ./src/pyams_content/shared/site/zmi/link.py:66
msgid "Parent"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:73
-#: ./src/pyams_content/shared/site/zmi/link.py:68
+#: ./src/pyams_content/shared/site/zmi/folder.py:75
+#: ./src/pyams_content/shared/site/zmi/link.py:67
msgid "Folder's parent"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/folder.py:150
+#: ./src/pyams_content/shared/site/zmi/folder.py:155
msgid "You must provide a folder name for default server language!"
msgstr ""
@@ -3507,7 +3614,7 @@
msgid "Add topic..."
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/__init__.py:84
+#: ./src/pyams_content/shared/site/zmi/__init__.py:86
msgid "Add topic"
msgstr ""
@@ -3515,7 +3622,7 @@
msgid "Topic's parent"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/link.py:58
+#: ./src/pyams_content/shared/site/zmi/link.py:57
msgid "Rent content..."
msgstr ""
@@ -3523,85 +3630,81 @@
msgid "Rent existing content"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/link.py:141
+#: ./src/pyams_content/shared/site/zmi/link.py:135
msgid "Edit content link properties"
msgstr ""
#: ./src/pyams_content/shared/site/zmi/container.py:106
#: ./src/pyams_content/shared/site/zmi/container.py:118
-#: ./src/pyams_content/shared/blog/zmi/manager.py:160
-#: ./src/pyams_content/shared/blog/zmi/manager.py:172
+#: ./src/pyams_content/shared/blog/zmi/manager.py:155
+#: ./src/pyams_content/shared/blog/zmi/manager.py:167
msgid "Publication dates..."
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:131
-#: ./src/pyams_content/shared/blog/zmi/manager.py:185
+#: ./src/pyams_content/shared/site/zmi/container.py:132
+#: ./src/pyams_content/shared/blog/zmi/manager.py:181
msgid "Update publication dates"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:183
-#: ./src/pyams_content/shared/site/zmi/container.py:193
+#: ./src/pyams_content/shared/site/zmi/container.py:178
+#: ./src/pyams_content/shared/site/zmi/container.py:188
#: ./src/pyams_content/root/zmi/sites.py:68
msgid "Site tree"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:312
-#: ./src/pyams_content/shared/site/zmi/container.py:162
+#: ./src/pyams_content/shared/site/zmi/container.py:307
+#: ./src/pyams_content/shared/site/zmi/container.py:156
msgid "Visible element?"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:313
+#: ./src/pyams_content/shared/site/zmi/container.py:308
msgid "Switch element visibility"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:374
+#: ./src/pyams_content/shared/site/zmi/container.py:369
msgid "Folders and topics"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:410
-#: ./src/pyams_content/root/zmi/__init__.py:798
+#: ./src/pyams_content/shared/site/zmi/container.py:405
+#: ./src/pyams_content/root/zmi/__init__.py:817
msgid "Content"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:506
+#: ./src/pyams_content/shared/site/zmi/container.py:501
msgid "Delete site item"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:383
+#: ./src/pyams_content/shared/site/zmi/container.py:378
msgid "Click to open/close all folders"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:399
+#: ./src/pyams_content/shared/site/zmi/container.py:394
msgid "Click to show/hide inner folders"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/container.py:269
+#: ./src/pyams_content/shared/site/zmi/container.py:264
msgid "Can't reparent object to one of it's children. Reloading..."
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/manager.py:58
+#: ./src/pyams_content/shared/site/zmi/manager.py:57
msgid "Site management"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/manager.py:88
-#: ./src/pyams_content/shared/site/zmi/manager.py:100
+#: ./src/pyams_content/shared/site/zmi/manager.py:112
+#: ./src/pyams_content/shared/site/zmi/manager.py:126
msgid "Add site manager"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/manager.py:99
-msgid "Site manager"
-msgstr ""
-
-#: ./src/pyams_content/shared/site/zmi/manager.py:131
-#: ./src/pyams_content/shared/blog/zmi/manager.py:126
+#: ./src/pyams_content/shared/site/zmi/manager.py:156
+#: ./src/pyams_content/shared/blog/zmi/manager.py:127
msgid "You must provide a short name for default server language!"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/manager.py:135
+#: ./src/pyams_content/shared/site/zmi/manager.py:160
msgid "Specified site manager name is already used!"
msgstr ""
-#: ./src/pyams_content/shared/site/zmi/manager.py:139
+#: ./src/pyams_content/shared/site/zmi/manager.py:164
msgid "A site manager is already registered with this name!!"
msgstr ""
@@ -3655,11 +3758,11 @@
msgid "no URL defined"
msgstr ""
-#: ./src/pyams_content/shared/logo/zmi/paragraph.py:53
+#: ./src/pyams_content/shared/logo/zmi/paragraph.py:54
msgid "Logos..."
msgstr ""
-#: ./src/pyams_content/shared/logo/zmi/paragraph.py:64
+#: ./src/pyams_content/shared/logo/zmi/paragraph.py:67
msgid "Add new logos paragraph"
msgstr ""
@@ -3720,19 +3823,19 @@
msgstr ""
#: ./src/pyams_content/shared/blog/zmi/manager.py:83
-#: ./src/pyams_content/shared/blog/zmi/manager.py:95
+#: ./src/pyams_content/shared/blog/zmi/manager.py:97
msgid "Add blog manager"
msgstr ""
-#: ./src/pyams_content/shared/blog/zmi/manager.py:94
+#: ./src/pyams_content/shared/blog/zmi/manager.py:96
msgid "Blog manager"
msgstr ""
-#: ./src/pyams_content/shared/blog/zmi/manager.py:130
+#: ./src/pyams_content/shared/blog/zmi/manager.py:131
msgid "Specified blog manager name is already used!"
msgstr ""
-#: ./src/pyams_content/shared/blog/zmi/manager.py:134
+#: ./src/pyams_content/shared/blog/zmi/manager.py:135
msgid "A blog manager is already registered with this name!!"
msgstr ""
@@ -3760,6 +3863,10 @@
msgid "Default length used for inner tables and dashboards"
msgstr ""
+#: ./src/pyams_content/root/__init__.py:67
+msgid "Site root"
+msgstr ""
+
#: ./src/pyams_content/root/zmi/sites.py:78
msgid "Blogs and shared sites"
msgstr ""
@@ -3784,7 +3891,7 @@
msgid "Content types"
msgstr ""
-#: ./src/pyams_content/root/zmi/__init__.py:77
+#: ./src/pyams_content/root/zmi/__init__.py:78
msgid "Home"
msgstr ""
@@ -3796,19 +3903,19 @@
msgid "SEARCH - Between all contents"
msgstr ""
-#: ./src/pyams_content/root/interfaces/__init__.py:36
+#: ./src/pyams_content/root/interfaces/__init__.py:39
msgid "Site managers"
msgstr ""
-#: ./src/pyams_content/root/interfaces/__init__.py:44
+#: ./src/pyams_content/root/interfaces/__init__.py:47
msgid "Templates managers"
msgstr ""
-#: ./src/pyams_content/root/interfaces/__init__.py:48
+#: ./src/pyams_content/root/interfaces/__init__.py:51
msgid "Operators group"
msgstr ""
-#: ./src/pyams_content/root/interfaces/__init__.py:49
+#: ./src/pyams_content/root/interfaces/__init__.py:52
msgid "Name of group containing all roles owners"
msgstr ""
@@ -4129,11 +4236,11 @@
msgid "Automatic contents withdrawal:\n"
msgstr ""
-#: ./src/pyams_content/workflow/zmi/task.py:43
+#: ./src/pyams_content/workflow/zmi/task.py:42
msgid "Add content archiver task..."
msgstr ""
-#: ./src/pyams_content/workflow/zmi/task.py:54
+#: ./src/pyams_content/workflow/zmi/task.py:55
msgid "Add automatic content archiver"
msgstr ""
@@ -4162,18 +4269,20 @@
msgstr ""
#: ./src/pyams_content/interfaces/__init__.py:96
-msgid "WARNING: this key can't be modified after creation!!!"
-msgstr ""
-
-#: ./src/pyams_content/interfaces/__init__.py:103
+msgid ""
+"WARNING: this key can't be modified after creation!!! Spaces, uppercase "
+"letters ou accentuated characters will be replaced automatically."
+msgstr ""
+
+#: ./src/pyams_content/interfaces/__init__.py:105
msgid "Short name"
msgstr ""
-#: ./src/pyams_content/interfaces/__init__.py:104
+#: ./src/pyams_content/interfaces/__init__.py:106
msgid "Short name used in breadcrumbs"
msgstr ""
-#: ./src/pyams_content/interfaces/__init__.py:115
+#: ./src/pyams_content/interfaces/__init__.py:117
msgid "Modification date"
msgstr ""
@@ -4194,11 +4303,11 @@
msgid "Properties..."
msgstr ""
-#: ./src/pyams_content/reference/zmi/table.py:156
+#: ./src/pyams_content/reference/zmi/table.py:157
msgid "Edit table properties"
msgstr ""
-#: ./src/pyams_content/reference/zmi/table.py:173
+#: ./src/pyams_content/reference/zmi/table.py:167
msgid "Table management"
msgstr ""
@@ -4206,11 +4315,16 @@
msgid "References"
msgstr ""
+#: ./src/pyams_content/reference/pictograms/zmi/__init__.py:169
+#: ./src/pyams_content/reference/pictograms/zmi/widget.py:55
+msgid "Default header: --"
+msgstr ""
+
#: ./src/pyams_content/reference/pictograms/zmi/manager.py:51
msgid "Pictograms selection..."
msgstr ""
-#: ./src/pyams_content/reference/pictograms/zmi/manager.py:62
+#: ./src/pyams_content/reference/pictograms/zmi/manager.py:63
#: ./src/pyams_content/reference/pictograms/zmi/templates/manager-selection.pt:34
#: ./src/pyams_content/reference/pictograms/interfaces/__init__.py:73
msgid "Selected pictograms"
@@ -4225,6 +4339,10 @@
msgid "Display pictogram properties"
msgstr ""
+#: ./src/pyams_content/reference/pictograms/zmi/templates/pictogram-header.pt:6
+msgid "Default header: ${header}"
+msgstr ""
+
#: ./src/pyams_content/reference/pictograms/interfaces/__init__.py:45
msgid "Pictogram content"
msgstr ""
@@ -4242,7 +4360,7 @@
msgid "List of selected pictograms which will be available to shared contents"
msgstr ""
-#: ./src/pyams_content/features/renderer/zmi/__init__.py:72
+#: ./src/pyams_content/features/renderer/zmi/__init__.py:70
#: ./src/pyams_content/features/renderer/zmi/templates/renderer-input.pt:4
msgid "Edit renderer properties"
msgstr ""
@@ -4322,7 +4440,7 @@
#. Default: Heading
#: ./src/pyams_content/features/alert/interfaces.py:65
-#: ./src/pyams_content/features/alert/zmi/container.py:158
+#: ./src/pyams_content/features/alert/zmi/container.py:157
msgid "alert-header"
msgstr ""
@@ -4331,7 +4449,7 @@
msgstr ""
#: ./src/pyams_content/features/alert/interfaces.py:69
-#: ./src/pyams_content/features/alert/zmi/container.py:170
+#: ./src/pyams_content/features/alert/zmi/container.py:169
msgid "Message"
msgstr ""
@@ -4371,7 +4489,7 @@
"set to 0 to always display the alert"
msgstr ""
-#: ./src/pyams_content/features/alert/zmi/__init__.py:46
+#: ./src/pyams_content/features/alert/zmi/__init__.py:45
msgid "Add alert"
msgstr ""
@@ -4379,7 +4497,7 @@
msgid "Add new alert"
msgstr ""
-#: ./src/pyams_content/features/alert/zmi/__init__.py:85
+#: ./src/pyams_content/features/alert/zmi/__init__.py:79
msgid "Edit alert properties"
msgstr ""
@@ -4387,31 +4505,104 @@
msgid "Alerts"
msgstr ""
-#: ./src/pyams_content/features/alert/zmi/container.py:192
+#: ./src/pyams_content/features/alert/zmi/container.py:191
msgid "Alert list"
msgstr ""
-#: ./src/pyams_content/features/alert/zmi/container.py:91
+#: ./src/pyams_content/features/alert/zmi/container.py:90
msgid "No currently defined alert."
msgstr ""
-#: ./src/pyams_content/features/footer/zmi/__init__.py:56
+#: ./src/pyams_content/features/menu/zmi/__init__.py:81
+msgid "Add menu..."
+msgstr ""
+
+#: ./src/pyams_content/features/menu/zmi/__init__.py:92
+msgid "Add new menu"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/zmi/__init__.py:123
+msgid "Edit menu properties"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/zmi/__init__.py:110
+msgid "Menu was correctly added."
+msgstr ""
+
+#: ./src/pyams_content/features/menu/zmi/__init__.py:388
+msgid "Link was correctly added."
+msgstr ""
+
+#: ./src/pyams_content/features/menu/zmi/templates/menu-name-cell.pt:7
+msgid "Click to see menu items"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/simple.py:68
+msgid "Simple navigation"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/double.py:68
+msgid "Double navigation"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/zmi/simple.py:70
+msgid "Navigation links"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/zmi/double.py:70
+msgid "Navigation menus"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/zmi/templates/simple-preview.pt:13
+msgid "Link has no illustration"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:32
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:32
+msgid "Portlet main title"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:35
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:35
+msgid "Subtitle"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/simple.py:36
+#: ./src/pyams_content/features/menu/portlet/navigation/interfaces/double.py:36
+msgid "Portlet subtitle"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/interfaces/__init__.py:63
+msgid "Menu title"
+msgstr ""
+
+#: ./src/pyams_content/features/menu/interfaces/__init__.py:64
+msgid "Displayed menu label"
+msgstr ""
+
+#: ./src/pyams_content/features/footer/zmi/__init__.py:60
msgid "Page footer"
msgstr ""
-#: ./src/pyams_content/features/footer/zmi/__init__.py:74
+#: ./src/pyams_content/features/footer/zmi/__init__.py:78
msgid "Edit footer settings"
msgstr ""
-#: ./src/pyams_content/features/footer/zmi/__init__.py:172
+#: ./src/pyams_content/features/footer/zmi/__init__.py:152
+msgid ""
+"WARNING: Footer properties are saved automatically when changing inherit "
+"mode!!"
+msgstr ""
+
+#: ./src/pyams_content/features/footer/zmi/__init__.py:220
msgid "Footer renderer settings"
msgstr ""
-#: ./src/pyams_content/features/footer/zmi/__init__.py:101
+#: ./src/pyams_content/features/footer/zmi/__init__.py:107
msgid "Don't inherit parent footer"
msgstr ""
-#: ./src/pyams_content/features/footer/skin/__init__.py:49
+#: ./src/pyams_content/features/footer/skin/__init__.py:53
msgid "Hidden footer"
msgstr ""
@@ -4423,17 +4614,17 @@
msgid "Presentation template used for this footer"
msgstr ""
-#: ./src/pyams_content/features/review/__init__.py:180
+#: ./src/pyams_content/features/review/__init__.py:181
#, python-format
msgid "Request comment: {comment}"
msgstr ""
-#: ./src/pyams_content/features/review/__init__.py:210
+#: ./src/pyams_content/features/review/__init__.py:211
#, python-format
msgid "A new comment was added on content « {0} »"
msgstr ""
-#: ./src/pyams_content/features/review/__init__.py:167
+#: ./src/pyams_content/features/review/__init__.py:168
#, python-format
msgid "[{service_name}] A content review is requested"
msgstr ""
@@ -4478,15 +4669,15 @@
msgid "Ask for review..."
msgstr ""
-#: ./src/pyams_content/features/review/zmi/__init__.py:99
+#: ./src/pyams_content/features/review/zmi/__init__.py:100
msgid "Content review request"
msgstr ""
-#: ./src/pyams_content/features/review/zmi/__init__.py:172
+#: ./src/pyams_content/features/review/zmi/__init__.py:166
msgid "Comments"
msgstr ""
-#: ./src/pyams_content/features/review/zmi/__init__.py:192
+#: ./src/pyams_content/features/review/zmi/__init__.py:186
msgid "Review comments"
msgstr ""
@@ -4521,15 +4712,15 @@
msgid "Ask for content review"
msgstr ""
-#: ./src/pyams_content/features/review/zmi/__init__.py:153
+#: ./src/pyams_content/features/review/zmi/__init__.py:147
msgid "Request successful. No new notification have been sent"
msgstr ""
-#: ./src/pyams_content/features/review/zmi/__init__.py:266
+#: ./src/pyams_content/features/review/zmi/__init__.py:260
msgid "Message is mandatory!"
msgstr ""
-#: ./src/pyams_content/features/review/zmi/__init__.py:141
+#: ./src/pyams_content/features/review/zmi/__init__.py:135
#, python-format
msgid "Request successful. {count} new notification(s) have been sent"
msgstr ""
@@ -4605,22 +4796,28 @@
msgid "Thank you."
msgstr ""
-#: ./src/pyams_content/features/header/zmi/__init__.py:62
+#: ./src/pyams_content/features/header/zmi/__init__.py:66
msgid "Page header"
msgstr ""
-#: ./src/pyams_content/features/header/zmi/__init__.py:80
+#: ./src/pyams_content/features/header/zmi/__init__.py:84
msgid "Edit header settings"
msgstr ""
-#: ./src/pyams_content/features/header/zmi/__init__.py:178
+#: ./src/pyams_content/features/header/zmi/__init__.py:161
+msgid ""
+"WARNING: Header properties are saved automatically when changing inherit "
+"mode!!"
+msgstr ""
+
+#: ./src/pyams_content/features/header/zmi/__init__.py:229
msgid "Header renderer settings"
msgstr ""
-#: ./src/pyams_content/features/header/zmi/__init__.py:107
+#: ./src/pyams_content/features/header/zmi/__init__.py:113
msgid "Don't inherit parent header"
msgstr ""
-#: ./src/pyams_content/features/header/skin/__init__.py:49
+#: ./src/pyams_content/features/header/skin/__init__.py:53
msgid "Hidden header"
msgstr ""
--- a/src/pyams_content/reference/pictograms/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/reference/pictograms/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -54,12 +54,16 @@
terms = []
table = query_utility(IPictogramTable)
if table is not None:
+ request = check_request()
target = get_parent(context, IPictogramManagerTarget)
if target is not None:
- request = check_request()
manager = IPictogramManager(target)
- pictograms = [table.get(name) for name in manager.selected_pictograms]
+ pictograms = [table.get(name) for name in manager.selected_pictograms or ()]
terms = [SimpleTerm(v.__name__,
title=II18n(v).query_attribute('title', request=request))
for v in pictograms if v is not None]
+ else:
+ terms = [SimpleTerm(v.__name__,
+ title=II18n(v).query_attribute('title', request=request))
+ for v in table.values()]
super(SelectedPictogramsVocabulary, self).__init__(terms)
--- a/src/pyams_content/reference/pictograms/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/reference/pictograms/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -14,9 +14,6 @@
# import standard library
-import sys
-
-from random import randint
from uuid import uuid4
# import interfaces
@@ -32,6 +29,7 @@
# import packages
from pyams_content.reference.pictograms import Pictogram
+from pyams_file.zmi.image import render_image
from pyams_form.form import AJAXAddForm, ajax_config
from pyams_i18n.column import I18nAttrColumn
from pyams_pagelet.pagelet import pagelet_config
@@ -40,10 +38,10 @@
from pyams_skin.viewlet.toolbar import ToolbarAction
from pyams_utils.adapter import adapter_config
from pyams_utils.traversing import get_parent
-from pyams_utils.url import absolute_url
from pyams_viewlet.viewlet import viewlet_config
from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
-from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest
+from pyramid.httpexceptions import HTTPNotFound
+from pyramid.renderers import render, render_to_response
from pyramid.response import Response
from pyramid.view import view_config
from z3c.form import field
@@ -141,8 +139,8 @@
def getValue(self, obj):
image = II18n(obj).query_attribute('image', request=self.request)
if image:
- timestamp = randint(0, sys.maxsize)
- return '<img src="{0}?_={1}" />'.format(absolute_url(image, self.request, '++thumb++32x32'), timestamp)
+ return render_image(image, 32, 32, timestamp=True)
+ return '--'
@adapter_config(name='name', context=(IPictogramTable, IAdminLayer, PictogramTableContentsTable), provides=IColumn)
@@ -163,16 +161,22 @@
@view_config(name='get-pictogram-header.html', context=IPictogramTable, request_type=IPyAMSLayer,
permission=VIEW_SYSTEM_PERMISSION)
-def get_pictogram_label(request):
- """Get alternate label associated with a given pictogram"""
+def get_pictogram_header_view(request):
+ """View used to get thumbnail and alternate label associated with a given pictogram"""
+ translate = request.localizer.translate
name = request.params.get('value')
- if not name:
- raise HTTPBadRequest()
- translate = request.localizer.translate
- if name == '--NOVALUE--':
+ if (not name) or (name == '--NOVALUE--'):
return Response(translate(_("Default header: --")))
pictogram = request.context.get(name)
if pictogram is None:
raise HTTPNotFound()
- return Response(translate(_("Default header: {0}")).format(
- II18n(pictogram).query_attribute('header', request=request) or '--'))
+ return render_to_response('templates/pictogram-header.pt', {
+ 'context': pictogram
+ }, request=request)
+
+
+def get_pictogram_header(pictogram, request=None):
+ """Get thumbnail and alternate label associated with a given pictogram"""
+ return render('templates/pictogram-header.pt', {
+ 'context': pictogram
+ }, request=request)
--- a/src/pyams_content/reference/pictograms/zmi/templates/manager-selection.pt Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/reference/pictograms/zmi/templates/manager-selection.pt Wed Jun 27 16:42:01 2018 +0200
@@ -22,9 +22,9 @@
</a>
</div>
<div class="width-50 text-center pull-left margin-right-10">
- <img tal:define="img i18n:pictogram.image"
- tal:condition="img"
- tal:attributes="src extension:absolute_url(img, '++thumb++48x48')" />
+ <tal:var define="img i18n:pictogram.image"
+ condition="img"
+ content="structure extension:thumbnail(img, 48, 48)" />
</div>
<span tal:content="i18n:pictogram.title">Title</span>
</div>
@@ -49,9 +49,9 @@
</a>
</div>
<div class="width-50 text-center pull-left margin-right-10">
- <img tal:define="img i18n:pictogram.image"
- tal:condition="img"
- tal:attributes="src extension:absolute_url(img, '++thumb++48x48')" />
+ <tal:var define="img i18n:pictogram.image"
+ condition="img"
+ content="structure extension:thumbnail(img, 48, 48)" />
</div>
<span tal:content="i18n:pictogram.title">Title</span>
</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/reference/pictograms/zmi/templates/pictogram-header.pt Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,9 @@
+<div class="padding-5" i18n:domain="pyams_content">
+ <tal:var define="image i18n:context.image"
+ condition="image"
+ content="structure extension:thumbnail(image, 32, 32)" />
+ <span class="padding-left-5" tal:define="header i18n:context.header"
+ i18n:translate="">Default header:
+ <strong i18n:name="header" tal:content="header or '--'" />
+ </span>
+</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/reference/pictograms/zmi/widget.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.reference.pictograms import IPictogramTable
+from pyams_utils.interfaces.data import IObjectData
+
+# import packages
+from pyams_content.reference.pictograms.zmi import get_pictogram_header
+from pyams_utils.registry import query_utility
+from pyams_utils.url import absolute_url
+from z3c.form.browser.select import SelectWidget
+from z3c.form.widget import FieldWidget
+from zope.interface import implementer
+
+from pyams_content import _
+
+
+@implementer(IObjectData)
+class PictogramSelectWidget(SelectWidget):
+ """Pictogram selection widget"""
+
+ pictograms = None
+ label_id = None
+ after_widget_notice = None
+
+ def update(self):
+ super(PictogramSelectWidget, self).update()
+ self.label_id = '{0}_header'.format(self.id)
+ self.pictograms = query_utility(IPictogramTable)
+ if self.value and (self.pictograms is not None):
+ pictogram = self.pictograms.get(self.value[0])
+ if pictogram is not None:
+ self.after_widget_notice = '<span id="{0}" class="text-info">{1}</span>'.format(
+ self.label_id,
+ get_pictogram_header(pictogram, self.request))
+ return
+ self.after_widget_notice = '<span id="{0}" class="text-info">{1}</span>'.format(
+ self.label_id,
+ self.request.localizer.translate(_("Default header: --")))
+
+ @property
+ def object_data(self):
+ return {
+ 'ams-change-handler': 'MyAMS.helpers.select2ChangeHelper',
+ 'ams-stop-propagation': 'true',
+ 'ams-select2-helper-type': 'html',
+ 'ams-select2-helper-url': absolute_url(self.pictograms, self.request, 'get-pictogram-header.html'),
+ 'ams-select2-helper-target': '#{0}'.format(self.label_id)
+ }
+
+
+def PictogramSelectFieldWidget(field, request):
+ return FieldWidget(field, PictogramSelectWidget(request))
--- a/src/pyams_content/root/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/root/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -27,10 +27,11 @@
from pyams_content.root.interfaces import ISiteRootRoles, ISiteRootConfiguration, ISiteRoot, \
ISiteRootToolsConfiguration, ISiteRootBackOfficeConfiguration
from pyams_form.interfaces.form import IFormContextPermissionChecker
-from pyams_portal.interfaces import IPortalContext
-from pyams_security.interfaces import IDefaultProtectionPolicy, IGrantedRoleEvent, ISecurityManager
+from pyams_portal.interfaces import IPortalContext, DESIGNER_ROLE
+from pyams_security.interfaces import IDefaultProtectionPolicy, IGrantedRoleEvent, ISecurityManager, SYSTEM_ADMIN_ROLE
+from pyams_skin.interfaces.configuration import IConfiguration, IBackOfficeConfiguration
from pyams_utils.interfaces import MANAGE_SYSTEM_PERMISSION
-from pyams_utils.interfaces.site import IConfigurationFactory, IBackOfficeConfigurationFactory, ISiteRootFactory
+from pyams_utils.interfaces.site import ISiteRootFactory
# import packages
from persistent import Persistent
@@ -39,26 +40,31 @@
from pyams_skin.configuration import Configuration, BackOfficeConfiguration
from pyams_skin.skin import UserSkinnableContent
from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
+from pyams_utils.factory import factory_config
from pyams_utils.registry import get_utility, utility_config
from pyams_utils.site import BaseSiteRoot
from pyams_utils.traversing import get_parent
from pyramid.events import subscriber
from zope.interface import implementer
+from pyams_content import _
+
@implementer(IDefaultProtectionPolicy, ISiteRoot, ISiteRootRoles, IPortalContext,
IIllustrationTarget, IHeaderTarget, IFooterTarget, IAlertTarget, IPreviewTarget)
class SiteRoot(ProtectedObject, BaseSiteRoot, UserSkinnableContent):
"""Main site root"""
- __roles__ = ('system.Manager', WEBMASTER_ROLE, OPERATOR_ROLE, 'pyams.TemplatesManager')
+ __roles__ = (SYSTEM_ADMIN_ROLE, WEBMASTER_ROLE, OPERATOR_ROLE, DESIGNER_ROLE)
roles_interface = ISiteRootRoles
managers = RolePrincipalsFieldProperty(ISiteRootRoles['managers'])
webmasters = RolePrincipalsFieldProperty(ISiteRootRoles['webmasters'])
operators = RolePrincipalsFieldProperty(ISiteRootRoles['operators'])
- templates_managers = RolePrincipalsFieldProperty(ISiteRootRoles['templates_managers'])
+ designers = RolePrincipalsFieldProperty(ISiteRootRoles['designers'])
+
+ content_name = _("Site root")
@utility_config(provides=ISiteRootFactory)
@@ -70,30 +76,22 @@
@implementer(ISiteRootConfiguration)
+@factory_config(provided=IConfiguration)
class SiteRootConfiguration(Configuration):
"""Site root configuration"""
-@adapter_config(context=ISiteRoot, provides=IConfigurationFactory)
-def site_root_configuration_factory(context):
- return SiteRootConfiguration
-
-
@implementer(ISiteRootBackOfficeConfiguration)
+@factory_config(provided=IBackOfficeConfiguration)
class SiteRootBackOfficeConfiguration(BackOfficeConfiguration):
"""Site root back-office configuration"""
-@adapter_config(context=ISiteRoot, provides=IBackOfficeConfigurationFactory)
-def site_root_back_office_configuration_factory(context):
- return SiteRootBackOfficeConfiguration
-
-
@subscriber(IGrantedRoleEvent)
def handle_granted_role(event):
"""Add principals to operators group when a role is granted"""
role_id = event.role_id
- if (role_id == 'pyams.Operator') or (not role_id.startswith('pyams.')):
+ if (role_id == OPERATOR_ROLE) or (not role_id.startswith('pyams.')):
return
root = get_parent(event.object, ISiteRoot)
if not root.operators:
--- a/src/pyams_content/root/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/root/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,6 +16,9 @@
# import standard library
# import interfaces
+from pyams_content.interfaces import WEBMASTER_ROLE, OPERATOR_ROLE
+from pyams_portal.interfaces import DESIGNER_ROLE
+from pyams_security.interfaces import SYSTEM_ADMIN_ROLE
from pyams_skin.interfaces.configuration import IConfiguration, IBackOfficeConfiguration
from pyams_utils.interfaces.site import ISiteRoot as ISiteRootBase
@@ -34,20 +37,20 @@
"""Main site roles"""
managers = PrincipalsSet(title=_("Site managers"),
- role_id='system.Manager',
+ role_id=SYSTEM_ADMIN_ROLE,
required=False)
webmasters = PrincipalsSet(title=_("Webmasters"),
- role_id='pyams.Webmaster',
+ role_id=WEBMASTER_ROLE,
required=False)
- templates_managers = PrincipalsSet(title=_("Templates managers"),
- role_id='pyams.TemplatesManager',
- required=False)
+ designers = PrincipalsSet(title=_("Templates managers"),
+ role_id=DESIGNER_ROLE,
+ required=False)
operators = Principal(title=_("Operators group"),
description=_("Name of group containing all roles owners"),
- role_id='pyams.Operator',
+ role_id=OPERATOR_ROLE,
required=False)
--- a/src/pyams_content/root/zmi/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/root/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -25,7 +25,8 @@
from pyams_content.skin.zmi.interfaces import IDashboardMenu, IMyDashboardMenu, IAllContentsMenu
from pyams_i18n.interfaces import II18n
from pyams_skin.interfaces import IInnerPage, IPageHeader
-from pyams_skin.interfaces.configuration import IBackOfficeConfiguration
+from pyams_skin.interfaces.configuration import IBackOfficeConfiguration, IConfiguration
+from pyams_skin.interfaces.container import ITableElementName, ITableElementEditor
from pyams_skin.interfaces.viewlet import IBreadcrumbItem
from pyams_skin.layer import IPyAMSLayer
from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
@@ -45,11 +46,11 @@
from pyams_pagelet.pagelet import pagelet_config
from pyams_skin.container import ContainerView
from pyams_skin.page import DefaultPageHeaderAdapter
-from pyams_skin.table import I18nColumn
+from pyams_skin.table import I18nColumn, DefaultElementEditorAdapter
from pyams_skin.viewlet.breadcrumb import BreadcrumbItem
from pyams_skin.viewlet.menu import MenuItem
from pyams_template.template import template_config
-from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
+from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter, ContextRequestAdapter
from pyams_utils.list import unique
from pyams_utils.registry import get_utility, get_all_utilities_registered_for
from pyams_viewlet.manager import viewletmanager_config
@@ -77,6 +78,24 @@
label = _("Home")
+@adapter_config(context=(ISiteRoot, IPyAMSLayer), provides=ITableElementName)
+class SiteRootTableElementNameAdapter(ContextRequestAdapter):
+ """Site root table element name adapter"""
+
+ @property
+ def name(self):
+ configuration = IConfiguration(self.context)
+ return II18n(configuration).query_attribute('short_title', request=self.request)
+
+
+@adapter_config(context=(ISiteRoot, IAdminLayer, Interface), provides=ITableElementEditor)
+class SiteRootTableElementEditorAdapter(DefaultElementEditorAdapter):
+ """Site root table element editor adapter"""
+
+ view_name = 'admin#site-tree.html'
+ modal_target = False
+
+
#
# Main dashboard menu
#
@@ -153,6 +172,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = Eq(catalog['parents'], intids.register(tool)) & \
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Any(catalog['workflow_state'], workflow.waiting_states)
params = params | query if params else query
return filter(self.check_access,
@@ -199,6 +219,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = Eq(catalog['parents'], intids.register(tool)) & \
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Any(catalog['workflow_state'], workflow.waiting_states) & \
Eq(catalog['workflow_principal'], self.request.principal.id)
params = params | query if params else query
@@ -360,6 +381,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = And(Eq(catalog['parents'], intids.register(tool)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Eq(catalog['workflow_state'], workflow.initial_state))
@@ -421,6 +443,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = And(Eq(catalog['parents'], intids.register(tool)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Any(catalog['workflow_state'], workflow.waiting_states))
@@ -482,6 +505,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = And(Eq(catalog['parents'], intids.register(tool)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Any(catalog['workflow_state'], workflow.published_states))
@@ -543,6 +567,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = And(Eq(catalog['parents'], intids.register(tool)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Any(catalog['workflow_state'], workflow.retired_states))
@@ -606,6 +631,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = And(Eq(catalog['parents'], intids.register(tool)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], principal_id),
Eq(catalog['role:contributor'], principal_id)),
Any(catalog['workflow_state'], workflow.archived_states))
@@ -695,6 +721,7 @@
for tool in get_all_utilities_registered_for(IBaseSharedTool):
workflow = IWorkflow(tool)
query = And(Eq(catalog['parents'], intids.register(tool)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Any(catalog['workflow_state'], workflow.published_states))
params = params | query if params else query
return unique(CatalogResultSet(CatalogQuery(catalog).query(params,
@@ -800,4 +827,7 @@
weight = 1
def getValue(self, obj):
- return self.request.localizer.translate(obj.content_name)
+ try:
+ return self.request.localizer.translate(obj.content_name)
+ except AttributeError:
+ return '--'
--- a/src/pyams_content/root/zmi/templates/dashboard.pt Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/root/zmi/templates/dashboard.pt Wed Jun 27 16:42:01 2018 +0200
@@ -25,7 +25,9 @@
<label class="input">
<button type="submit" class="icon-append fa fa-fw fa-search no-border no-padding"
data-ams-form-hide-loading="true"></button>
- <input type="text" name="query" placeholder="Quick search..." i18n:attributes="placeholder" />
+ <input type="text" name="query"
+ placeholder="Quick search..." i18n:attributes="placeholder"
+ data-ams-events-handlers='{"keyup": "MyAMS.helpers.clearSearchTarget"}' />
</label>
</div>
<div class="col-md-6">
@@ -36,7 +38,8 @@
</form>
</div>
</div>
- <div id="search_results" tal:define="global dashboard_length 0">
+ <div id="search_results"></div>
+ <tal:var define="global dashboard_length 0">
<tal:loop repeat="table view.tables">
<tal:if condition="table.values">
<tal:var content="structure table.render()" />
@@ -46,6 +49,6 @@
<div tal:condition="not:dashboard_length" class="alert alert-info" i18n:translate="">
You are not actually concerned by any content.
</div>
- </div>
+ </tal:var>
</div>
</div>
--- a/src/pyams_content/shared/blog/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/blog/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.illustration import IIllustrationTarget
+from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
from pyams_content.component.theme.interfaces import IThemesTarget
from pyams_content.features.preview.interfaces import IPreviewTarget
@@ -31,8 +31,8 @@
from zope.interface import implementer, provider
-@implementer(IWfBlogPost, IParagraphContainerTarget, IThemesTarget,
- IIllustrationTarget, IPreviewTarget, IReviewTarget)
+@implementer(IWfBlogPost, IParagraphContainerTarget, IThemesTarget, IIllustrationTarget,
+ ILinkIllustrationTarget, IPreviewTarget, IReviewTarget)
class WfBlogPost(WfSharedContent):
"""Base blog post"""
--- a/src/pyams_content/shared/blog/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/blog/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,8 +16,8 @@
# import standard library
# import interfaces
-from pyams_content.shared.common.interfaces import ISharedSite, IBaseSharedTool, IWfSharedContent, ISharedContent, \
- IDeletableElement
+from pyams_content.shared.common.interfaces import ISharedSite, IBaseSharedTool, ISharedContent, \
+ IDeletableElement, IWfSharedContentPortalContext
from pyams_sequence.interfaces import ISequentialIdTarget
from pyams_workflow.interfaces import IWorkflowPublicationSupport
from zope.container.interfaces import IContainer
@@ -33,7 +33,7 @@
BLOG_CONTENT_NAME = _("Blog post")
-class IWfBlogPost(IWfSharedContent):
+class IWfBlogPost(IWfSharedContentPortalContext):
"""Blog topic interface"""
--- a/src/pyams_content/shared/blog/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/blog/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.illustration import IIllustrationTarget
+from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget
from pyams_content.component.paragraph.interfaces import IParagraphFactorySettings
from pyams_content.component.theme.interfaces import IThemesManagerTarget
from pyams_content.features.footer.interfaces import IFooterTarget
@@ -27,7 +27,6 @@
from pyams_content.shared.blog.interfaces import IBlogManager, IBlogFolder, IBlogFolderFactory, IBlogManagerFactory
from pyams_content.shared.common.interfaces import ISharedContentFactory
from pyams_portal.interfaces import IPortalContext
-from zope.annotation.interfaces import IAttributeAnnotatable
from zope.component.interfaces import ISite
from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectRemovedEvent
@@ -55,7 +54,7 @@
@implementer(IBlogManager, IParagraphFactorySettings, IThemesManagerTarget, IPictogramManagerTarget,
- IIllustrationTarget, IPortalContext, IHeaderTarget, IFooterTarget, IPreviewTarget, IAttributeAnnotatable)
+ IIllustrationTarget, ILinkIllustrationTarget, IHeaderTarget, IFooterTarget, IPortalContext, IPreviewTarget)
class BlogManager(Folder, BaseSharedTool, UserSkinnableContent):
"""Nlog manager class"""
--- a/src/pyams_content/shared/blog/zmi/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/blog/zmi/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -186,6 +186,6 @@
def updateWidgets(self, prefix=None):
super(BlogManagerWorkflowPublicationEditForm, self).updateWidgets(prefix)
if 'publication_effective_date' in self.widgets:
- widget = self.widgets['publication_effective_date']
- if not widget.value:
- widget.value = tztime(datetime.utcnow()).strftime('%d/%m/%y %H:%M')
+ pub_info = IWorkflowPublicationInfo(self.context)
+ if pub_info.publication_effective_date is None:
+ self.widgets['publication_effective_date'].value = tztime(datetime.utcnow()).strftime('%d/%m/%y %H:%M')
--- a/src/pyams_content/shared/common/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -17,12 +17,14 @@
# import interfaces
from hypatia.interfaces import ICatalog
-from pyams_content.interfaces import IBaseContentInfo
+from pyams_content.interfaces import IBaseContentInfo, OWNER_ROLE, MANAGER_ROLE, CONTRIBUTOR_ROLE, READER_ROLE, \
+ GUEST_ROLE
from pyams_content.features.checker.interfaces import IContentChecker, MISSING_VALUE, MISSING_LANG_VALUE, ERROR_VALUE
from pyams_content.features.review.interfaces import IReviewComments
from pyams_content.shared.common.interfaces import IWfSharedContent, IWfSharedContentRoles, ISharedContent, \
IBaseSharedTool, ISharedSite, IWfSharedContentFactory
from pyams_i18n.interfaces import II18nManager, II18n
+from pyams_portal.interfaces import DESIGNER_ROLE
from pyams_security.interfaces import IDefaultProtectionPolicy
from pyams_sequence.interfaces import ISequentialIdTarget, ISequentialIdInfo
from pyams_utils.interfaces import VIEW_PERMISSION
@@ -113,12 +115,13 @@
class WfSharedContent(ProtectedObject, Persistent, Contained, I18nManagerMixin):
"""Shared data content class"""
- __roles__ = ('pyams.Owner', 'pyams.Manager', 'pyams.Contributors', 'pyams.Reader', 'pyams.Guest')
+ __roles__ = (OWNER_ROLE, MANAGER_ROLE, CONTRIBUTOR_ROLE, DESIGNER_ROLE, READER_ROLE, GUEST_ROLE)
roles_interface = IWfSharedContentRoles
owner = RolePrincipalsFieldProperty(IWfSharedContentRoles['owner'])
managers = RolePrincipalsFieldProperty(IWfSharedContentRoles['managers'])
contributors = RolePrincipalsFieldProperty(IWfSharedContentRoles['contributors'])
+ designers = RolePrincipalsFieldProperty(IWfSharedContentRoles['designers'])
readers = RolePrincipalsFieldProperty(IWfSharedContentRoles['readers'])
guests = RolePrincipalsFieldProperty(IWfSharedContentRoles['guests'])
--- a/src/pyams_content/shared/common/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -18,7 +18,7 @@
# import interfaces
from pyams_content.interfaces import IBaseContent, MANAGE_CONTENT_PERMISSION, OWNER_ROLE, MANAGER_ROLE, \
READER_ROLE, GUEST_ROLE, WEBMASTER_ROLE, PILOT_ROLE, CONTRIBUTOR_ROLE
-from pyams_content.root.interfaces import ISiteRoot
+from pyams_portal.interfaces import IPortalContext, DESIGNER_ROLE
from pyams_workflow.interfaces import IWorkflowManagedContent
from zope.container.interfaces import IContainer
@@ -65,17 +65,22 @@
role_id=CONTRIBUTOR_ROLE,
required=False)
+ designers = PrincipalsSet(title=_("Designers"),
+ description=_("Designers are users which are allowed to manage presentation templates"),
+ role_id=DESIGNER_ROLE,
+ required=False)
+
class ISharedSite(IBaseContent, IDeletableElement):
"""Shared site interface"""
- containers(ISiteRoot)
+ containers('pyams_content.root.interfaces.ISiteRoot')
class ISharedToolContainer(IBaseContent, IContainer):
"""Shared tools container"""
- containers(ISiteRoot)
+ containers('pyams_content.root.interfaces.ISiteRoot')
contains('.ISharedTool')
@@ -102,6 +107,10 @@
shared_content_factory = Attribute("Shared data factory")
+class ISharedToolPortalContext(ISharedTool, IPortalContext):
+ """Shared tool with portal context"""
+
+
class ISharedToolRoles(IBaseContentManagerRoles):
"""Shared tool roles"""
@@ -157,6 +166,10 @@
required=False)
+class IWfSharedContentPortalContext(IWfSharedContent, IPortalContext):
+ """Shared content with portal support"""
+
+
class IWfSharedContentFactory(Interface):
"""Shared content factory interface"""
@@ -180,9 +193,14 @@
contributors = PrincipalsSet(title=_("Contributors"),
description=_("Contributors are users which are allowed to update this content in "
"addition to it's owner"),
- role_id='pyams.Contributor',
+ role_id=CONTRIBUTOR_ROLE,
required=False)
+ designers = PrincipalsSet(title=_("Designers"),
+ description=_("Designers are users which are allowed to manage presentation templates"),
+ role_id=DESIGNER_ROLE,
+ required=False)
+
readers = PrincipalsSet(title=_("Readers"),
description=_("Readers are users which are asked to verify and comment contents before "
"they are published"),
--- a/src/pyams_content/shared/common/interfaces/types.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/interfaces/types.py Wed Jun 27 16:42:01 2018 +0200
@@ -17,6 +17,7 @@
# import interfaces
from pyams_content.shared.common.interfaces import ISharedTool
+from pyams_portal.interfaces import IPortalContext
from zope.container.interfaces import IContainer
from zope.location.interfaces import ILocation
@@ -100,3 +101,7 @@
"""Shared tool containing typed data"""
shared_content_types_fields = Attribute("Content fields interface")
+
+
+class ITypedSharedToolPortalContext(ITypedSharedTool, IPortalContext):
+ """Typed shared tool with portal context"""
--- a/src/pyams_content/shared/common/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,6 +19,7 @@
from pyams_content.interfaces import WEBMASTER_ROLE, PILOT_ROLE, MANAGER_ROLE, CONTRIBUTOR_ROLE
from pyams_content.shared.common.interfaces import ISharedToolContainer, IBaseSharedTool, ISharedTool, ISharedToolRoles, \
ISharedContentFactory
+from pyams_portal.interfaces import DESIGNER_ROLE
from pyams_security.interfaces import IDefaultProtectionPolicy
from pyams_workflow.interfaces import IWorkflow
from zope.annotation.interfaces import IAttributeAnnotatable
@@ -42,11 +43,11 @@
short_name = FieldProperty(ISharedToolContainer['short_name'])
-@implementer(IDefaultProtectionPolicy, IBaseSharedTool, ISharedToolRoles, IAttributeAnnotatable)
+@implementer(IDefaultProtectionPolicy, IBaseSharedTool, ISharedToolRoles)
class BaseSharedTool(ProtectedObject, I18nManagerMixin):
"""Base shared tool class"""
- __roles__ = (WEBMASTER_ROLE, PILOT_ROLE, MANAGER_ROLE, CONTRIBUTOR_ROLE)
+ __roles__ = (WEBMASTER_ROLE, PILOT_ROLE, MANAGER_ROLE, DESIGNER_ROLE, CONTRIBUTOR_ROLE)
roles_interface = ISharedToolRoles
@@ -54,6 +55,7 @@
pilots = RolePrincipalsFieldProperty(ISharedToolRoles['pilots'])
managers = RolePrincipalsFieldProperty(ISharedToolRoles['managers'])
contributors = RolePrincipalsFieldProperty(ISharedToolRoles['contributors'])
+ designers = RolePrincipalsFieldProperty(ISharedToolRoles['designers'])
title = FieldProperty(IBaseSharedTool['title'])
short_name = FieldProperty(IBaseSharedTool['short_name'])
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/portal.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common.interfaces import IBaseSharedTool, IWfSharedContentPortalContext
+from pyams_portal.interfaces import IPortalPage, PORTAL_PAGE_KEY
+
+# import packages
+from pyams_portal.page import PortalPage
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
+from pyams_utils.traversing import get_parent
+
+
+class SharedContentPortalPage(PortalPage):
+ """Shared content portal page"""
+
+ @property
+ def can_inherit(self):
+ return IPortalPage(self.parent).template is not None
+
+ @property
+ def parent(self):
+ return get_parent(self, IBaseSharedTool, allow_context=False)
+
+
+@adapter_config(context=IWfSharedContentPortalContext, provides=IPortalPage)
+def shared_content_portal_page_adapter(context):
+ """Shared content portal page adapter"""
+ return get_annotation_adapter(context, PORTAL_PAGE_KEY, SharedContentPortalPage)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/portlet/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+# import standard library
+
+# import interfaces
+
+# import packages
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/portlet/content/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common.portlet.content.interfaces import ISharedContentPortletSettings
+from pyams_utils.interfaces import VIEW_PERMISSION
+
+# import packages
+from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
+from pyams_utils.factory import factory_config
+from zope.interface import implementer
+
+from pyams_content import _
+
+
+SHARED_CONTENT_PORTLET_NAME = 'pyams_content.portlet.content'
+
+
+@implementer(ISharedContentPortletSettings)
+@factory_config(provided=ISharedContentPortletSettings)
+class SharedContentPortletSettings(PortletSettings):
+ """Shared content portlet persistent settings"""
+
+
+@portlet_config(permission=VIEW_PERMISSION)
+class SharedContentPortlet(Portlet):
+ """Shared content portlet"""
+
+ name = SHARED_CONTENT_PORTLET_NAME
+ label = _("Context content")
+
+ settings_factory = ISharedContentPortletSettings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/portlet/content/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_portal.interfaces import IPortletSettings
+
+# import packages
+
+
+class ISharedContentPortletSettings(IPortletSettings):
+ """Shared content portlet settings interface"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/portlet/content/skin/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common.portlet.content.interfaces import ISharedContentPortletSettings
+from pyams_content.features.renderer.interfaces import ISharedContentRenderer
+from pyams_portal.interfaces import IPortalContext, IPortletRenderer
+from pyams_skin.layer import IPyAMSLayer
+
+# import packages
+from pyams_portal.portlet import PortletRenderer
+from pyams_utils.adapter import adapter_config
+from zope.interface import Interface
+
+from pyams_content import _
+
+
+@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, ISharedContentPortletSettings),
+ provides=IPortletRenderer)
+class SharedContentPortletRenderer(PortletRenderer):
+ """Shared content portlet renderer"""
+
+ label = _("Default content renderer")
+
+ def __init__(self, context, request, view, settings):
+ super(SharedContentPortletRenderer, self).__init__(context, request, view, settings)
+ registry = self.request.registry
+ self.renderers = [adapter for name, adapter in sorted(registry.getAdapters((self.context, self.request),
+ ISharedContentRenderer),
+ key=lambda x: x[1].weight)]
+
+ def update(self):
+ super(SharedContentPortletRenderer, self).update()
+ [renderer.update() for renderer in self.renderers]
+
+ def render(self):
+ result = ''
+ for renderer in self.renderers:
+ if renderer is not None:
+ result += renderer.render()
+ return result
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/portlet/content/zmi/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common.portlet.content.interfaces import ISharedContentPortletSettings
+from pyams_pagelet.interfaces import IPagelet
+from pyams_portal.interfaces import IPortletPreviewer
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+
+# import packages
+from pyams_form.form import AJAXEditForm
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_portal.portlet import PortletPreviewer
+from pyams_portal.zmi.portlet import PortletSettingsEditor
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+from zope.interface import Interface
+
+
+@pagelet_config(name='properties.html', context=ISharedContentPortletSettings, layer=IPyAMSLayer,
+ permission=VIEW_SYSTEM_PERMISSION)
+class SharedContentPortletSettingsEditor(PortletSettingsEditor):
+ """Shared content portlet settings editor"""
+
+ settings = ISharedContentPortletSettings
+
+
+@adapter_config(name='properties.json', context=(ISharedContentPortletSettings, IPyAMSLayer), provides=IPagelet)
+class SharedContentPortletConfigurationAJAXEditor(AJAXEditForm, SharedContentPortletSettingsEditor):
+ """Shared content portlet settings editor, JSON renderer"""
+
+
+@adapter_config(context=(Interface, IPyAMSLayer, Interface, ISharedContentPortletSettings),
+ provides=IPortletPreviewer)
+@template_config(template='preview.pt', layer=IPyAMSLayer)
+class SharedContentPortletPreviewer(PortletPreviewer):
+ """Shared content portlet previewer"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/portlet/content/zmi/preview.pt Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,3 @@
+<tal:var define="settings view.settings" i18n:domain="pyams_content">
+ <span class="padding-5" i18n:translate="">This is where the content will be displayed!!</span>
+</tal:var>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/skin/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/skin/oid.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_sequence.interfaces import ISequentialIntIds
+from pyams_skin.layer import IPyAMSUserLayer
+from pyams_utils.interfaces.url import DISPLAY_CONTEXT
+from pyams_workflow.interfaces import IWorkflow, IWorkflowVersions
+from zope.traversing.interfaces import ITraversable
+
+# import packages
+from pyams_sequence.utility import get_reference_target
+from pyams_utils.adapter import adapter_config, ContextRequestAdapter
+from pyams_utils.registry import get_utility
+from pyramid.exceptions import NotFound
+from zope.interface import Interface
+
+
+@adapter_config(name='oid', context=(Interface, IPyAMSUserLayer), provides=ITraversable)
+class OidTraverser(ContextRequestAdapter):
+ """++oid++ traverser"""
+
+ def traverse(self, name, furtherpath=None):
+ if not name:
+ raise NotFound()
+ if '::' in name:
+ oid, label = name.split('::', 1)
+ else:
+ oid = name
+ sequence = get_utility(ISequentialIntIds)
+ reference = sequence.get_full_oid(oid)
+ target = get_reference_target(reference)
+ if target is not None:
+ workflow = IWorkflow(target, None)
+ if workflow is not None:
+ versions = IWorkflowVersions(target).get_versions(workflow.published_states, sort=True)
+ if versions:
+ target = versions[-1]
+ if target is not None:
+ self.request.annotations[DISPLAY_CONTEXT] = self.context
+ return target
+ raise NotFound()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/skin/url.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common import IWfSharedContent
+from pyams_sequence.interfaces import ISequentialIdInfo
+from pyams_skin.layer import IPyAMSUserLayer
+from pyams_utils.interfaces.url import IRelativeURL
+
+# import packages
+from pyams_utils.adapter import adapter_config, ContextRequestAdapter
+from pyams_utils.url import absolute_url
+
+
+@adapter_config(context=(IWfSharedContent, IPyAMSUserLayer), provides=IRelativeURL)
+class SharedContentRelativeUrlAdapter(ContextRequestAdapter):
+ """Shared content relative URL adapter"""
+
+ def get_url(self, display_context=None, view_name=None, query=None):
+ return absolute_url(display_context, self.request,
+ '++oid++{0}::{1}.html'.format(
+ ISequentialIdInfo(self.context).get_base_oid().strip(),
+ self.context.content_url))
--- a/src/pyams_content/shared/common/zmi/dashboard.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/dashboard.py Wed Jun 27 16:42:01 2018 +0200
@@ -340,6 +340,7 @@
catalog = get_utility(ICatalog)
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = Eq(catalog['parents'], intids.register(self.context)) & \
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Any(catalog['workflow_state'], workflow.waiting_states)
return filter(self.check_access,
unique(map(lambda x: sorted(IWorkflowVersions(x).get_versions(IWorkflowState(x).state),
@@ -383,6 +384,7 @@
catalog = get_utility(ICatalog)
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = Eq(catalog['parents'], intids.register(self.context)) & \
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Any(catalog['workflow_state'], workflow.waiting_states) & \
Eq(catalog['workflow_principal'], self.request.principal.id)
return unique(map(lambda x: sorted(IWorkflowVersions(x).get_versions(IWorkflowState(x).state),
@@ -576,6 +578,7 @@
catalog = get_utility(ICatalog)
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = And(Eq(catalog['parents'], intids.register(self.context)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Eq(catalog['workflow_state'], workflow.initial_state))
@@ -638,6 +641,7 @@
catalog = get_utility(ICatalog)
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = And(Eq(catalog['parents'], intids.register(self.context)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Any(catalog['workflow_state'], workflow.waiting_states))
@@ -700,6 +704,7 @@
catalog = get_utility(ICatalog)
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = And(Eq(catalog['parents'], intids.register(self.context)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Any(catalog['workflow_state'], workflow.published_states))
@@ -762,6 +767,7 @@
catalog = get_utility(ICatalog)
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = And(Eq(catalog['parents'], intids.register(self.context)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], self.request.principal.id),
Eq(catalog['role:contributor'], self.request.principal.id)),
Any(catalog['workflow_state'], workflow.retired_states))
@@ -826,6 +832,7 @@
principal_id = self.request.principal.id
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = And(Eq(catalog['parents'], intids.register(self.context)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Or(Eq(catalog['role:owner'], principal_id),
Eq(catalog['role:contributor'], principal_id)),
Any(catalog['workflow_state'], workflow.archived_states))
@@ -916,6 +923,7 @@
catalog = get_utility(ICatalog)
workflow = get_utility(IWorkflow, name=self.context.shared_content_workflow)
params = And(Eq(catalog['parents'], intids.register(self.context)),
+ Any(catalog['content_type'], CONTENT_TYPES.keys()) & \
Any(catalog['workflow_state'], workflow.published_states))
return unique(CatalogResultSet(CatalogQuery(catalog).query(params,
limit=50,
--- a/src/pyams_content/shared/common/zmi/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -120,7 +120,7 @@
class SharedToolPropertiesHelpAdapter(FormHelp):
"""Shared tool properties help adapter"""
- permission = MANAGE_TOOL_PERMISSION
+ permission = MANAGE_SYSTEM_PERMISSION
header = _("WARNING")
status = 'danger'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/zmi/portal.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,72 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.shared.common import IWfSharedContent
+from pyams_content.shared.common.interfaces import IWfSharedContentPortalContext, ISharedToolPortalContext, ISharedTool
+from pyams_content.shared.common.interfaces.types import ITypedSharedToolPortalContext
+from pyams_form.interfaces.form import IFormHelp
+from pyams_portal.interfaces import MANAGE_TEMPLATE_PERMISSION
+from pyams_skin.layer import IPyAMSLayer
+from pyams_zmi.layer import IAdminLayer
+
+# import packages
+from pyams_form.form import ajax_config
+from pyams_form.help import FormHelp
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_portal.zmi.page import PortalContextTemplatePropertiesEditForm
+from pyams_utils.adapter import adapter_config
+
+from pyams_content import _
+
+
+@pagelet_config(name='template-properties.html', context=ISharedToolPortalContext, layer=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION)
+@pagelet_config(name='template-properties.html', context=ITypedSharedToolPortalContext, layer=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION)
+@ajax_config(name='template-properties.json', context=ISharedToolPortalContext, layer=IPyAMSLayer)
+@ajax_config(name='template-properties.json', context=ITypedSharedToolPortalContext, layer=IPyAMSLayer)
+class SharedToolTemplatePropertiesEditForm(PortalContextTemplatePropertiesEditForm):
+ """Shared content template properties edit form"""
+
+ legend = _("Edit default template properties")
+
+
+@adapter_config(context=(ISharedToolPortalContext, IAdminLayer, SharedToolTemplatePropertiesEditForm),
+ provides=IFormHelp)
+@adapter_config(context=(ITypedSharedToolPortalContext, IAdminLayer, SharedToolTemplatePropertiesEditForm),
+ provides=IFormHelp)
+class SharedToolPortalContextPropertiesEditFormHelpAdapter(FormHelp):
+ """Shared tool template properties edit form help adapter"""
+
+ message = _("**This form allows you to select shared content default template.**\n"
+ "\n"
+ "If you choose to use a shared template, you can only adjust settings of "
+ "each portlet individually but can't change portlets list or page configuration.\n"
+ "\n"
+ "If you use a local template, you can define a whole custom "
+ "configuration but the template definition can't be reused anywhere...""")
+ message_format = 'rest'
+
+
+@pagelet_config(name='template-properties.html', context=IWfSharedContentPortalContext, layer=IPyAMSLayer,
+ permission=MANAGE_TEMPLATE_PERMISSION)
+@ajax_config(name='template-properties.json', context=IWfSharedContent, layer=IPyAMSLayer)
+class SharedContentTemplatePropertiesEditForm(PortalContextTemplatePropertiesEditForm):
+ """Shared content template properties edit form"""
+
+ override_legend = _("Override tool default template")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/zmi/rename.py Wed Jun 27 16:42:01 2018 +0200
@@ -0,0 +1,121 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.interfaces import MANAGE_SITE_PERMISSION
+from pyams_content.shared.common.interfaces import ISharedSite
+from pyams_content.shared.site.interfaces import ISiteFolder
+from pyams_content.skin.zmi.interfaces import ISiteTreeTable
+from pyams_skin.interfaces.viewlet import ITableItemColumnActionsMenu, IContextActions
+from pyams_skin.layer import IPyAMSLayer
+from z3c.form.interfaces import IDataExtractedEvent
+from zope.location.interfaces import ILocation
+
+# import packages
+from pyams_form.form import ajax_config
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.viewlet.toolbar import ToolbarMenuItem
+from pyams_utils.unicode import translate_string
+from pyams_utils.url import absolute_url
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogEditForm
+from pyramid.events import subscriber
+from z3c.form import field
+from zope.interface import Interface, Invalid
+
+from pyams_content import _
+
+
+#
+# Site container rename view
+#
+
+@viewlet_config(name='rename-item.menu', context=ISharedSite, layer=IPyAMSLayer,
+ view=ISiteTreeTable, manager=ITableItemColumnActionsMenu,
+ permission=MANAGE_SITE_PERMISSION, weight=900)
+@viewlet_config(name='rename-item.menu', context=ISharedSite, layer=IPyAMSLayer,
+ view=Interface, manager=IContextActions,
+ permission=MANAGE_SITE_PERMISSION, weight=900)
+@viewlet_config(name='rename-item.menu', context=ISiteFolder, layer=IPyAMSLayer,
+ view=ISiteTreeTable, manager=ITableItemColumnActionsMenu,
+ permission=MANAGE_SITE_PERMISSION, weight=900)
+@viewlet_config(name='rename-item.menu', context=ISiteFolder, layer=IPyAMSLayer,
+ view=Interface, manager=IContextActions,
+ permission=MANAGE_SITE_PERMISSION, weight=900)
+class SiteContainerRenameMenu(ToolbarMenuItem):
+ """Site container rename menu"""
+
+ label = _("Change URL...")
+ label_css_class = 'fa fa-fw fa-edit'
+ url = 'rename-item.html'
+ modal_target = True
+
+
+@pagelet_config(name='rename-item.html', context=ISharedSite, layer=IPyAMSLayer,
+ permission=MANAGE_SITE_PERMISSION)
+@ajax_config(name='rename-item.json', context=ISharedSite, layer=IPyAMSLayer)
+@pagelet_config(name='rename-item.html', context=ISiteFolder, layer=IPyAMSLayer,
+ permission=MANAGE_SITE_PERMISSION)
+@ajax_config(name='rename-item.json', context=ISiteFolder, layer=IPyAMSLayer)
+class SiteContainerRenameForm(AdminDialogEditForm):
+ """Site container rename form"""
+
+ prefix = 'rename_item.'
+
+ legend = _("Change item URL")
+
+ fields = field.Fields(ILocation).select('__name__')
+ edit_permission = MANAGE_SITE_PERMISSION
+
+ def updateWidgets(self, prefix=None):
+ super(SiteContainerRenameForm, self).updateWidgets(prefix)
+ self.widgets['__name__'].label = _("Item URL part")
+ self.widgets['__name__'].description = _("URL part used to access this content")
+
+ def update_content(self, content, data):
+ data = data.get(self, data)
+ old_name = content.__name__
+ new_name = data['__name__'] = translate_string(data['__name__'], spaces='-', keep_chars='-')
+ changes = super(SiteContainerRenameForm, self).update_content(content, data)
+ if changes:
+ # revert rename to adjust container properties
+ content.__name__ = old_name
+ parent = content.__parent__
+ parent[new_name] = content
+ del parent[old_name]
+ return changes
+
+ def get_ajax_output(self, changes):
+ if changes:
+ return {
+ 'status': 'redirect',
+ 'location': absolute_url(self.context, self.request, 'admin'),
+ 'smallbox': {
+ 'status': 'success',
+ 'message': self.request.localizer.translate(self.successMessage)
+ }
+ }
+ else:
+ return super(SiteContainerRenameForm, self).get_ajax_output(changes)
+
+
+@subscriber(IDataExtractedEvent, form_selector=SiteContainerRenameForm)
+def handle_rename_form_data_extraction(event):
+ """Handle rename form data extraction"""
+ name = event.data.get('__name__')
+ if not name:
+ event.form.widgets.errors += (Invalid(_("You must provide an URL for this item!")),)
--- a/src/pyams_content/shared/common/zmi/security.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/security.py Wed Jun 27 16:42:01 2018 +0200
@@ -115,7 +115,7 @@
class SharedToolContributorsRestrictionsChecksColumn(I18nColumn, GetAttrColumn):
"""Shared tool contributor enabled publication checks column"""
- _header = _("Publication checks")
+ _header = _("Activated publication checks?")
weight = 20
cssClasses = {'td': 'center'}
@@ -267,7 +267,7 @@
class SharedToolManagerRestrictionsChecksColumn(I18nColumn, GetAttrColumn):
"""Shared tool manager enabled publication checks column"""
- _header = _("Publication checks")
+ _header = _("Activated publication checks?")
weight = 40
cssClasses = {'td': 'center'}
--- a/src/pyams_content/shared/common/zmi/templates/dashboard.pt Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/templates/dashboard.pt Wed Jun 27 16:42:01 2018 +0200
@@ -25,7 +25,9 @@
<label class="input">
<button type="submit" class="icon-append fa fa-fw fa-search no-border no-padding"
data-ams-form-hide-loading="true"></button>
- <input type="text" name="query" placeholder="Quick search..." i18n:attributes="placeholder" />
+ <input type="text" name="query"
+ placeholder="Quick search..." i18n:attributes="placeholder"
+ data-ams-events-handlers='{"keyup": "MyAMS.helpers.clearSearchTarget"}' />
</label>
</div>
<div class="col-md-6">
@@ -36,7 +38,8 @@
</form>
</div>
</div>
- <div id="search_results" tal:define="global dashboard_length 0">
+ <div id="search_results"></div>
+ <tal:var define="global dashboard_length 0">
<tal:loop repeat="table view.tables">
<tal:if condition="table.values">
<tal:var content="structure table.render()" />
@@ -46,6 +49,6 @@
<div tal:condition="not:dashboard_length" class="alert alert-info" i18n:translate="">
You are not actually concerned by any content.
</div>
- </div>
+ </tal:var>
</div>
</div>
--- a/src/pyams_content/shared/common/zmi/types.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/types.py Wed Jun 27 16:42:01 2018 +0200
@@ -146,7 +146,9 @@
def renderCell(self, item):
return '<span data-ams-stop-propagation="true" ' \
- ' data-ams-click-handler="PyAMS_content.types.switchSubtypes">' \
+ ' data-ams-click-handler="MyAMS.skin.switchCellContent" ' \
+ ' data-ams-switch-handler="get-subtypes-table.json" ' \
+ ' data-ams-switch-target=".subtypes">' \
' <span class="small hint" title="{hint}" data-ams-hint-gravity="e">' \
' <i class="fa fa-plus-square-o switch"></i>' \
' </span>' \
@@ -315,8 +317,6 @@
attributes = super(DatatypeSubtypesTable, self).data_attributes
attributes['table'] = {
'id': self.id,
- 'data-ams-plugins': 'pyams_content',
- 'data-ams-plugin-pyams_content-src': get_resource_path(pyams_content),
'data-ams-location': absolute_url(self.context, self.request),
'data-ams-tablednd-drag-handle': 'td.sorter',
'data-ams-tablednd-drop-target': 'set-subtypes-order.json'
--- a/src/pyams_content/shared/common/zmi/workflow.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/common/zmi/workflow.py Wed Jun 27 16:42:01 2018 +0200
@@ -9,12 +9,6 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
-from z3c.form.browser.radio import RadioWidget
-from z3c.form.widget import FieldWidget
-
-from pyams_form.group import NamedWidgetsGroup
-from pyams_form.interfaces import IFormLayer
-from pyams_form.widget import widgettemplate_config
__docformat__ = 'restructuredtext'
@@ -26,6 +20,7 @@
from pyams_content.interfaces import PUBLISH_CONTENT_PERMISSION, CREATE_CONTENT_PERMISSION, MANAGE_CONTENT_PERMISSION
from pyams_content.shared.common.interfaces import IWfSharedContent, IBaseSharedTool, ISharedContent, \
IContributorRestrictions, IManagerRestrictions
+from pyams_form.interfaces import IFormLayer
from pyams_form.interfaces.form import IWidgetsPrefixViewletsManager, IFormSuffixViewletsManager, IInnerSubForm
from pyams_security.interfaces import ISecurityManager
from pyams_skin.layer import IPyAMSLayer
@@ -38,6 +33,7 @@
from pyams_content.workflow import DRAFT, DELETED
from pyams_form.form import AJAXAddForm, ajax_config
from pyams_form.schema import CloseButton
+from pyams_form.widget import widgettemplate_config
from pyams_pagelet.pagelet import pagelet_config
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
@@ -48,11 +44,12 @@
from pyams_utils.traversing import get_parent
from pyams_utils.url import absolute_url
from pyams_viewlet.viewlet import viewlet_config, Viewlet
-from pyams_workflow.zmi.transition import WorkflowContentTransitionForm, WorkflowContentTransitionAJAXForm
+from pyams_workflow.zmi.transition import WorkflowContentTransitionForm
from pyams_zmi.form import InnerAdminAddForm
from pyramid.events import subscriber
-from pyramid.view import view_config
from z3c.form import field, button
+from z3c.form.browser.radio import RadioWidget
+from z3c.form.widget import FieldWidget
from zope.interface import Interface, Invalid
from zope.schema import Bool
@@ -129,7 +126,7 @@
@pagelet_config(name='wf-propose.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='wf-propose.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=MANAGE_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationRequestForm(WorkflowContentTransitionForm):
"""Shared content publication request form"""
@@ -216,7 +213,7 @@
@pagelet_config(name='wf-cancel-propose.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='wf-cancel-propose.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=MANAGE_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationRequestCancelForm(WorkflowContentTransitionForm):
"""Shared content publication request cancel form"""
@@ -256,7 +253,7 @@
@pagelet_config(name='wf-refuse.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=PUBLISH_CONTENT_PERMISSION)
@ajax_config(name='wf-refuse.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=PUBLISH_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=PUBLISH_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationRequestRefuseForm(WorkflowContentTransitionForm):
"""Shared content publication request refuse form"""
@@ -310,7 +307,7 @@
@pagelet_config(name='wf-publish.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=PUBLISH_CONTENT_PERMISSION)
@ajax_config(name='wf-publish.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=PUBLISH_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=PUBLISH_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationForm(WorkflowContentTransitionForm):
"""Shared content publication form"""
@@ -399,7 +396,7 @@
@pagelet_config(name='wf-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='wf-retiring.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=MANAGE_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationRetireRequestForm(WorkflowContentTransitionForm):
"""Shared content publication request refuse form"""
@@ -455,7 +452,7 @@
@pagelet_config(name='wf-cancel-retiring.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='wf-cancel-retiring.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=MANAGE_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationRetireCancelForm(WorkflowContentTransitionForm):
"""Shared content publication retire request cancel form"""
@@ -495,7 +492,7 @@
@pagelet_config(name='wf-retire.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=PUBLISH_CONTENT_PERMISSION)
@ajax_config(name='wf-retire.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=PUBLISH_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=PUBLISH_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationRetireForm(WorkflowContentTransitionForm):
"""Shared content publication retire form"""
@@ -536,7 +533,7 @@
@pagelet_config(name='wf-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='wf-archiving.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=MANAGE_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationArchiveRequestForm(WorkflowContentTransitionForm):
"""Shared content publication request archive form"""
@@ -579,7 +576,7 @@
@pagelet_config(name='wf-cancel-archiving.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='wf-cancel-archiving.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=MANAGE_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationArchiveCancelForm(WorkflowContentTransitionForm):
"""Shared content publication archive request cancel form"""
@@ -619,7 +616,7 @@
@pagelet_config(name='wf-archive.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=PUBLISH_CONTENT_PERMISSION)
@ajax_config(name='wf-archive.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=PUBLISH_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=PUBLISH_CONTENT_PERMISSION, base=AJAXAddForm)
class PublicationArchiveForm(WorkflowContentTransitionForm):
"""Shared content publication archive form"""
@@ -711,7 +708,7 @@
@pagelet_config(name='wf-delete.html', context=IWfSharedContent, layer=IPyAMSLayer,
permission=MANAGE_CONTENT_PERMISSION)
@ajax_config(name='wf-delete.json', context=IWfSharedContent, layer=IPyAMSLayer,
- permission=MANAGE_CONTENT_PERMISSION, base=WorkflowContentTransitionAJAXForm)
+ permission=MANAGE_CONTENT_PERMISSION, base=AJAXAddForm)
class SharedContentDeleteForm(WorkflowContentTransitionForm):
"""Shared content delete form"""
@@ -835,7 +832,7 @@
(manager_restrictions.check_access(context, request=request)) and \
(not manager_restrictions.publication_checks):
return None
- if isinstance(form, PublicationForm):
+ if isinstance(form, PublicationRequestForm):
restrictions = IContributorRestrictions(context, None)
if restrictions is not None:
contributor_restrictions = restrictions.get_restrictions(principal_id)
--- a/src/pyams_content/shared/form/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/form/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,8 @@
# import standard library
# import interfaces
-from pyams_content.shared.common.interfaces import ISharedTool, IWfSharedContent, ISharedContent
+from pyams_content.shared.common.interfaces import ISharedContent, IWfSharedContentPortalContext, \
+ ISharedToolPortalContext
from zope.annotation.interfaces import IAttributeAnnotatable
from zope.container.interfaces import IContainer, IContained
@@ -36,7 +37,7 @@
FORM_FIELD_CONTAINER_KEY = 'pyams_content.shared.form_fields'
-class IFormsManager(ISharedTool):
+class IFormsManager(ISharedToolPortalContext):
"""Forms manager interface"""
@@ -115,7 +116,7 @@
"""Form fields container target marker interface"""
-class IWfForm(IWfSharedContent):
+class IWfForm(IWfSharedContentPortalContext):
"""Form interface"""
user_title = I18nTextLineField(title=_("Form title"),
--- a/src/pyams_content/shared/form/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/form/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -18,7 +18,7 @@
# import interfaces
from pyams_content.shared.common.interfaces import ISharedContentFactory
from pyams_content.shared.form.interfaces import IFormsManager, FORM_CONTENT_TYPE, IFormsManagerFactory
-from zope.annotation.interfaces import IAttributeAnnotatable
+from pyams_portal.interfaces import IPortalContext
from zope.component.interfaces import ISite
from zope.lifecycleevent.interfaces import IObjectAddedEvent
@@ -32,7 +32,7 @@
from zope.interface import implementer
-@implementer(IFormsManager, IAttributeAnnotatable)
+@implementer(IFormsManager)
class FormsManager(SharedTool):
"""Forms manager class"""
--- a/src/pyams_content/shared/form/zmi/render.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/form/zmi/render.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_content.features.renderer.interfaces import ISharedContentRenderer
from pyams_content.shared.form.interfaces import IFormFieldContainerTarget, IFormFieldContainer
from pyams_form.interfaces.form import IFormHelp
from pyams_i18n.interfaces import II18n
@@ -77,7 +77,7 @@
@adapter_config(name='form-render', context=(IFormFieldContainerTarget, IPyAMSLayer),
- provides=IContentRenderer)
+ provides=ISharedContentRenderer)
class FormFieldContainerRenderer(BaseContentRenderer):
"""Form field container renderer"""
--- a/src/pyams_content/shared/imagemap/zmi/area.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/imagemap/zmi/area.py Wed Jun 27 16:42:01 2018 +0200
@@ -9,6 +9,8 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
+from pyams_skin.event import get_json_table_row_refresh_event
+from pyams_utils.traversing import get_parent
__docformat__ = 'restructuredtext'
@@ -24,7 +26,7 @@
# import packages
from pyams_content.shared.imagemap import ImageMapArea
-from pyams_content.shared.imagemap.zmi.container import ImagemapAreasContainerView
+from pyams_content.shared.imagemap.zmi.container import ImagemapAreasContainerView, ImagemapAreasTable
from pyams_content.shared.imagemap.zmi.widget import ImgareaInputFieldWidget
from pyams_form.form import AJAXAddForm, ajax_config
from pyams_pagelet.pagelet import pagelet_config
@@ -63,6 +65,9 @@
legend = _("Add new image area")
+ label_css_class = 'control-label col-md-2'
+ input_css_class = 'col-md-10'
+
@property
def dialog_class(self):
image = II18n(self.context).query_attribute('image', request=self.request)
@@ -101,6 +106,9 @@
legend = _("Edit image map properties")
+ label_css_class = 'control-label col-md-2'
+ input_css_class = 'col-md-10'
+
@property
def dialog_class(self):
image = II18n(self.context.__parent__).query_attribute('image', request=self.request)
@@ -119,3 +127,11 @@
fields['area'].widgetFactory = ImgareaInputFieldWidget
edit_permission = MANAGE_CONTENT_PERMISSION
+
+ def get_ajax_output(self, changes):
+ output = super(self.__class__, self).get_ajax_output(changes)
+ if changes:
+ container = get_parent(self.context, IWfImageMap)
+ output.setdefault('events', []).append(
+ get_json_table_row_refresh_event(container, self.request, ImagemapAreasTable, self.context))
+ return output
--- a/src/pyams_content/shared/imagemap/zmi/container.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/imagemap/zmi/container.py Wed Jun 27 16:42:01 2018 +0200
@@ -89,11 +89,11 @@
@property
def data_attributes(self):
attributes = super(ImagemapAreasTable, self).data_attributes
- attributes['table'] = {
+ attributes.setdefault('table', {}).update({
'data-ams-location': absolute_url(self.context, self.request),
'data-ams-datatable-sort': 'false',
'data-ams-datatable-pagination': 'false'
- }
+ })
return attributes
@reify
--- a/src/pyams_content/shared/imagemap/zmi/templates/paragraph-render.pt Wed Jun 27 16:34:12 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-<h3 tal:content="view.title">title</h3>
-<div class="no-padding" i18n:domain="pyams_content"
- data-ams-plugins="pyams_content"
- tal:define="imagemap context.get_target()"
- tal:attributes="data-ams-plugin-pyams_content-src extension:resource_path('pyams_content.skin:pyams_content')">
- <img usemap="#imagemap_preview"
- tal:define="image i18n:imagemap.image"
- tal:attributes="src extension:absolute_url(image);
- usemap string:#imagemap_preview_${context.__name__}"
- data-ams-callback="PyAMS_content.imgmap.initPreview" />
- <map name="imagemap_preview"
- tal:attributes="name string:imagemap_preview_${context.__name__}">
- <tal:loop repeat="area imagemap.areas.values()">
- <tal:var define="item imagemap.get_association(area)"
- condition="item and item.visible">
- <area shape="poly"
- tal:define="info view.get_item_info(item);
- area_title i18n:area.title;
- item_title i18n:info.user_title;
- title area_title or item_title;"
- tal:attributes="coords area.area;
- href item.get_url(request);
- title title;" />
- </tal:var>
- </tal:loop>
- </map>
-</div>
--- a/src/pyams_content/shared/imagemap/zmi/templates/render.pt Wed Jun 27 16:34:12 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-<div class="padding-y-5" i18n:domain="pyams_content"
- data-ams-plugins="pyams_content"
- tal:attributes="data-ams-plugin-pyams_content-src extension:resource_path('pyams_content.skin:pyams_content')">
- <img usemap="#imagemap_preview"
- tal:define="image i18n:context.image"
- tal:attributes="src extension:absolute_url(image);"
- data-ams-callback="PyAMS_content.imgmap.initSummary" />
- <map name="imagemap_preview">
- <tal:loop repeat="area context.areas.values()">
- <tal:var define="item context.get_association(area)"
- condition="item and item.visible">
- <area shape="poly"
- tal:define="info view.get_item_info(item);
- area_title i18n:area.title;
- item_title i18n:info.user_title;
- title area_title or item_title;"
- tal:attributes="coords area.area;
- href item.get_url(request);
- title title;" />
- </tal:var>
- </tal:loop>
- </map>
-</div>
--- a/src/pyams_content/shared/news/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/news/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.illustration import IIllustrationTarget
+from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
from pyams_content.component.theme.interfaces import IThemesTarget
from pyams_content.features.preview.interfaces import IPreviewTarget
@@ -30,7 +30,7 @@
from zope.interface import implementer, provider
-@implementer(IWfNewsEvent, IIllustrationTarget, IParagraphContainerTarget, IThemesTarget,
+@implementer(IWfNewsEvent, IIllustrationTarget, ILinkIllustrationTarget, IParagraphContainerTarget, IThemesTarget,
IPreviewTarget, IReviewTarget)
class WfNewsEvent(WfSharedContent):
"""Base news event"""
--- a/src/pyams_content/shared/news/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/news/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,8 @@
# import standard library
# import interfaces
-from pyams_content.shared.common.interfaces import ISharedTool, IWfSharedContent, ISharedContent
+from pyams_content.shared.common.interfaces import ISharedContent, \
+ IWfSharedContentPortalContext, ISharedToolPortalContext
# import packages
from zope.interface import Interface
@@ -28,7 +29,7 @@
NEWS_CONTENT_NAME = _("News topic")
-class INewsManager(ISharedTool):
+class INewsManager(ISharedToolPortalContext):
"""News manager interface"""
@@ -36,7 +37,7 @@
"""News manager factory interface"""
-class IWfNewsEvent(IWfSharedContent):
+class IWfNewsEvent(IWfSharedContentPortalContext):
"""News event interface"""
--- a/src/pyams_content/shared/site/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.illustration import IIllustrationTarget
+from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget
from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
from pyams_content.component.theme.interfaces import IThemesTarget
from pyams_content.features.preview.interfaces import IPreviewTarget
@@ -31,8 +31,8 @@
from zope.interface import implementer, provider
-@implementer(IWfTopic, IParagraphContainerTarget, IThemesTarget,
- IIllustrationTarget, IPreviewTarget, IReviewTarget)
+@implementer(IWfTopic, IIllustrationTarget, ILinkIllustrationTarget, IParagraphContainerTarget,
+ IThemesTarget, IPreviewTarget, IReviewTarget)
class WfTopic(WfSharedContent):
"""Base topic"""
--- a/src/pyams_content/shared/site/folder.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/folder.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.illustration import IIllustrationTarget
+from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget
from pyams_content.features.preview.interfaces import IPreviewTarget
from pyams_content.interfaces import MANAGE_SITE_PERMISSION
from pyams_content.shared.site.interfaces import ISiteFolder, ISiteManager, ISiteFolderRoles
@@ -24,7 +24,6 @@
from pyams_i18n.interfaces import II18n
from pyams_portal.interfaces import IPortalContext
from pyams_security.interfaces import IDefaultProtectionPolicy
-from zope.annotation.interfaces import IAttributeAnnotatable
from zope.intid.interfaces import IIntIds
# import packages
@@ -43,9 +42,11 @@
from pyams_content import _
+from pyams_content import _
+
@implementer(IDefaultProtectionPolicy, ISiteFolder, ISiteFolderRoles,
- IIllustrationTarget, IPortalContext, IPreviewTarget, IAttributeAnnotatable)
+ IIllustrationTarget, ILinkIllustrationTarget, IPortalContext, IPreviewTarget)
class SiteFolder(SiteContainerMixin, OrderedContainer, BaseSharedTool):
"""Site folder persistent class"""
--- a/src/pyams_content/shared/site/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,11 +19,12 @@
from pyams_content.interfaces import IBaseContent
from pyams_sequence.interfaces import ISequentialIdTarget, IInternalReference
from pyams_workflow.interfaces import IWorkflowPublicationSupport
+from zope.annotation.interfaces import IAttributeAnnotatable
from zope.container.interfaces import IContainer, IContained
# import packages
-from pyams_content.shared.common.interfaces import ISharedSite, IWfSharedContent, ISharedContent, \
- IBaseContentManagerRoles, IBaseSharedTool, IDeletableElement
+from pyams_content.shared.common.interfaces import ISharedSite, ISharedContent, \
+ IBaseContentManagerRoles, IBaseSharedTool, IDeletableElement, IWfSharedContentPortalContext
from pyams_i18n.schema import I18nTextLineField, I18nTextField
from zope.container.constraints import containers, contains
from zope.interface import Interface, Attribute
@@ -95,7 +96,7 @@
TOPIC_CONTENT_NAME = _("Topic")
-class IWfTopic(IWfSharedContent):
+class IWfTopic(IWfSharedContentPortalContext):
"""Topic interface"""
@@ -107,7 +108,7 @@
"""Workflow managed topic interface"""
-class IContentLink(ISiteElement, IInternalReference):
+class IContentLink(ISiteElement, IInternalReference, IAttributeAnnotatable):
"""Rented content interface"""
alt_title = I18nTextLineField(title=_("Alternate title"),
--- a/src/pyams_content/shared/site/link.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/link.py Wed Jun 27 16:42:01 2018 +0200
@@ -17,12 +17,14 @@
# import interfaces
from pyams_content.shared.site.interfaces import IContentLink
+from pyams_utils.interfaces.url import IRelativeURL
from pyams_workflow.interfaces import IWorkflow, IWorkflowVersion, IWorkflowVersions, IWorkflowPublicationInfo, \
IWorkflowState
# import packages
from persistent import Persistent
from pyams_sequence.utility import get_reference_target
+from pyams_skin.layer import IPyAMSUserLayer
from pyams_utils.adapter import adapter_config
from zope.container.contained import Contained
from zope.interface import implementer
@@ -83,3 +85,11 @@
target = context.get_target()
if target is not None:
return IWorkflowPublicationInfo(target, None)
+
+
+@adapter_config(context=(IContentLink, IPyAMSUserLayer), provides=IRelativeURL)
+def content_link_relative_url(context):
+ """Content link relative URL"""
+ target = context.get_target()
+ if target is not None:
+ return IRelativeURL(target, None)
--- a/src/pyams_content/shared/site/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,7 +16,7 @@
# import standard library
# import interfaces
-from pyams_content.component.illustration import IIllustrationTarget
+from pyams_content.component.illustration import IIllustrationTarget, ILinkIllustrationTarget
from pyams_content.component.paragraph.interfaces import IParagraphFactorySettings
from pyams_content.component.theme.interfaces import IThemesManagerTarget
from pyams_content.features.footer.interfaces import IFooterTarget
@@ -30,7 +30,6 @@
from pyams_form.interfaces.form import IFormContextPermissionChecker
from pyams_i18n.interfaces import II18n
from pyams_portal.interfaces import IPortalContext
-from zope.annotation.interfaces import IAttributeAnnotatable
from zope.component.interfaces import ISite
from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectRemovedEvent
@@ -51,9 +50,12 @@
from zope.schema.fieldproperty import FieldProperty
from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
+from pyams_content import _
+
@implementer(ISiteManager, IParagraphFactorySettings, IThemesManagerTarget, IPictogramManagerTarget,
- IIllustrationTarget, IPortalContext, IHeaderTarget, IFooterTarget, IPreviewTarget, IAttributeAnnotatable)
+ IIllustrationTarget, ILinkIllustrationTarget, IPortalContext, IHeaderTarget,
+ IFooterTarget, IPreviewTarget)
class SiteManager(SiteContainerMixin, OrderedContainer, BaseSharedTool, UserSkinnableContent):
"""Site manager persistent class"""
@@ -63,6 +65,8 @@
sequence_name = '' # use default sequence generator
sequence_prefix = ''
+ content_name = _("Site manager")
+
@property
def folder_factory(self):
return ISiteFolderFactory(self, SiteFolder)
--- a/src/pyams_content/shared/site/zmi/container.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/zmi/container.py Wed Jun 27 16:42:01 2018 +0200
@@ -68,7 +68,7 @@
from pyramid.view import view_config
from z3c.form import field
from z3c.table.column import GetAttrColumn
-from zope.interface import implementer
+from zope.interface import implementer, Interface
from zope.lifecycleevent import ObjectMovedEvent
from pyams_content import _
@@ -137,9 +137,9 @@
def updateWidgets(self, prefix=None):
super(SiteContainerWorkflowPublicationEditForm, self).updateWidgets(prefix)
if 'publication_effective_date' in self.widgets:
- widget = self.widgets['publication_effective_date']
- if not widget.value:
- widget.value = tztime(datetime.utcnow()).strftime('%d/%m/%y %H:%M')
+ pub_info = IWorkflowPublicationInfo(self.context)
+ if pub_info.publication_effective_date is None:
+ self.widgets['publication_effective_date'].value = tztime(datetime.utcnow()).strftime('%d/%m/%y %H:%M')
def get_ajax_output(self, changes):
output = super(self.__class__, self).get_ajax_output(changes)
@@ -203,7 +203,10 @@
permission = self.permission
if self.can_sort and ((not permission) or self.request.has_permission(permission, self.context)):
classes.append('table-dnd')
- return {'table': ' '.join(classes)}
+ return {
+ 'table': ' '.join(classes),
+ 'tr.selected': lambda item, col, row: 'current' if item is self.context else ''
+ }
@property
def data_attributes(self):
--- a/src/pyams_content/shared/site/zmi/folder.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/zmi/folder.py Wed Jun 27 16:42:01 2018 +0200
@@ -20,6 +20,7 @@
from pyams_content.shared.common.interfaces import IBaseSharedTool
from pyams_content.shared.site.interfaces import ISiteContainer, ISiteManager, ISiteFolder
from pyams_i18n.interfaces import INegotiator, II18n
+from pyams_skin.interfaces.container import ITableElementName, ITableElementEditor
from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IMenuHeader
from pyams_skin.layer import IPyAMSLayer
from pyams_zmi.interfaces.menu import ISiteManagementMenu
@@ -33,6 +34,7 @@
from pyams_form.form import AJAXAddForm, AJAXEditForm, ajax_config
from pyams_i18n.schema import I18nTextLineField
from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.table import DefaultElementEditorAdapter
from pyams_skin.viewlet.toolbar import ToolbarMenuItem
from pyams_utils.adapter import adapter_config, ContextRequestAdapter
from pyams_utils.registry import get_utility
@@ -164,6 +166,23 @@
# Site folder edit form
#
+@adapter_config(context=(ISiteFolder, IPyAMSLayer), provides=ITableElementName)
+class SiteFolderTableElementNameAdapter(ContextRequestAdapter):
+ """Site folder table element name adapter"""
+
+ @property
+ def name(self):
+ return II18n(self.context).query_attribute('short_name', request=self.request)
+
+
+@adapter_config(context=(ISiteFolder, IAdminLayer, Interface), provides=ITableElementEditor)
+class SiteFolderTableElementEditorAdapter(DefaultElementEditorAdapter):
+ """Site folder table element editor adapter"""
+
+ view_name = 'admin#site-tree.html'
+ modal_target = False
+
+
@pagelet_config(name='properties.html', context=ISiteFolder, layer=IPyAMSLayer, permission=MANAGE_TOOL_PERMISSION)
class SiteFolderPropertiesEditForm(SharedToolPropertiesEditForm):
"""Site folder properties edit form"""
--- a/src/pyams_content/shared/site/zmi/link.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/zmi/link.py Wed Jun 27 16:42:01 2018 +0200
@@ -9,6 +9,7 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
+from pyams_skin.event import get_json_table_row_refresh_event
__docformat__ = 'restructuredtext'
@@ -21,7 +22,6 @@
from pyams_content.shared.site.interfaces import ISiteContainer, IContentLink
from pyams_content.skin.zmi.interfaces import ISiteTreeTable
from pyams_i18n.interfaces import II18n
-from pyams_sequence.interfaces import IInternalReference
from pyams_skin.interfaces.container import ITableElementName
from pyams_skin.interfaces.viewlet import IToolbarAddingMenu
from pyams_skin.layer import IPyAMSLayer
@@ -31,7 +31,7 @@
# import packages
from pyams_content.shared.site.link import ContentLink
-from pyams_content.shared.site.zmi.container import SiteContainerTreeTable, SiteContainerTreeNameColumn
+from pyams_content.shared.site.zmi.container import SiteContainerTreeTable
from pyams_content.shared.site.zmi.widget import SiteManagerFoldersSelectorFieldWidget
from pyams_form.form import AJAXAddForm, ajax_config
from pyams_pagelet.pagelet import pagelet_config
@@ -140,7 +140,7 @@
def get_ajax_output(self, changes):
output = super(self.__class__, self).get_ajax_output(changes)
intids = get_utility(IIntIds)
- if 'reference' in changes.get(IInternalReference, ()):
+ if changes:
table = SiteContainerTreeTable(self.context.__parent__, self.request)
table.update()
row = table.setUpRow(self.context)
@@ -152,16 +152,4 @@
'row': table.renderRow(row)
}
})
- elif 'alt_title' in changes.get(IContentLink, ()):
- adapter = ContentLinkTableElementName(self.context, self.request, None)
- column = SiteContainerTreeNameColumn(self.context, self.request, None)
- output.setdefault('events', []).append({
- 'event': 'myams.refresh',
- 'options': {
- 'handler': 'MyAMS.skin.refreshRowCell',
- 'object_id': '{0}::{1}'.format(SiteContainerTreeTable.id, intids.queryId(self.context)),
- 'col_name': 'name',
- 'cell': column.renderCell(self.context, name=adapter.name)
- }
- })
return output
--- a/src/pyams_content/shared/site/zmi/manager.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/site/zmi/manager.py Wed Jun 27 16:42:01 2018 +0200
@@ -21,7 +21,7 @@
from pyams_content.shared.site.interfaces import ISiteManager, ISiteManagerFactory
from pyams_content.skin.zmi.interfaces import ISiteTreeTable, IUserAddingsMenuLabel
from pyams_i18n.interfaces import II18n, INegotiator
-from pyams_skin.interfaces.container import ITableElementEditor
+from pyams_skin.interfaces.container import ITableElementEditor, ITableElementName
from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IBreadcrumbItem, IMenuHeader
from pyams_skin.layer import IPyAMSLayer
from pyams_zmi.interfaces.menu import ISiteManagementMenu
@@ -45,7 +45,7 @@
from pyramid.events import subscriber
from pyramid.path import DottedNameResolver
from z3c.form import field
-from zope.interface import Invalid
+from zope.interface import Invalid, Interface
from pyams_content import _
@@ -68,6 +68,31 @@
css_class = 'strong'
+@adapter_config(context=(ISiteManager, IPyAMSLayer), provides=ITableElementName)
+class SiteManagerTableElementNameAdapter(ContextRequestAdapter):
+ """Site manager table element name adapter"""
+
+ @property
+ def name(self):
+ return II18n(self.context).query_attribute('short_name', request=self.request)
+
+
+@adapter_config(context=(ISiteManager, IAdminLayer, Interface), provides=ITableElementEditor)
+class SiteManagerTableElementEditorAdapter(DefaultElementEditorAdapter):
+ """Site manager table element editor adapter"""
+
+ view_name = 'admin#site-tree.html'
+ modal_target = False
+
+
+@adapter_config(context=(ISiteManager, IAdminLayer, ISiteTreeTable), provides=ITableElementEditor)
+class SiteManagerTableElementEditor(DefaultElementEditorAdapter):
+ """Site tree table element editor"""
+
+ view_name = 'admin#site-tree.html'
+ modal_target = False
+
+
@adapter_config(context=(ISiteManager, IAdminLayer), provides=IUserAddingsMenuLabel)
class SiteManagerUserAddingsMenuLabelAdapter(ContextRequestAdapter):
"""Site manager user addings menu label adapter"""
@@ -137,11 +162,3 @@
site = query_utility(ISiteManager, name=short_name)
if site is not None:
event.form.widgets.errors += (Invalid(_("A site manager is already registered with this name!!")),)
-
-
-@adapter_config(context=(ISiteManager, IAdminLayer, ISiteTreeTable), provides=ITableElementEditor)
-class SiteManagerTableElementEditor(DefaultElementEditorAdapter):
- """Site tree table element editor"""
-
- view_name = 'admin#site-tree.html'
- modal_target = False
--- a/src/pyams_content/shared/view/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/view/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -25,6 +25,7 @@
from pyams_content.features.review.interfaces import IReviewTarget
from pyams_content.shared.view.interfaces import IView, IWfView, IWfViewFactory, IViewQuery, \
IViewQueryParamsExtension, IViewQueryFilterExtension, VIEW_CONTENT_TYPE, VIEW_CONTENT_NAME, IViewSettings
+from pyams_utils.interfaces import ICacheKeyValue
from zope.intid.interfaces import IIntIds
from zope.lifecycleevent.interfaces import IObjectModifiedEvent
@@ -86,13 +87,12 @@
return list(content_types)
def get_results(self, context):
- intids = get_utility(IIntIds)
views_cache = get_cache(VIEWS_CACHE_REGION, VIEWS_CACHE_NAME)
if self.is_using_context:
- cache_key = VIEW_CONTEXT_CACHE_KEY.format(view=intids.queryId(self),
- context=intids.queryId(context))
+ cache_key = VIEW_CONTEXT_CACHE_KEY.format(view=ICacheKeyValue(self),
+ context=ICacheKeyValue(context))
else:
- cache_key = VIEW_CACHE_KEY.format(view=intids.queryId(self))
+ cache_key = VIEW_CACHE_KEY.format(ICacheKeyValue(self))
try:
results = views_cache.get_value(cache_key)
except KeyError:
@@ -101,6 +101,7 @@
if adapter is None:
adapter = registry.getAdapter(self, IViewQuery)
results = adapter.get_results(context, self.limit)
+ intids = get_utility(IIntIds)
views_cache.set_value(cache_key, [intids.queryId(item) for item in results])
logger.debug("Storing view items to cache key {0}".format(cache_key))
else:
--- a/src/pyams_content/shared/view/interfaces/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/view/interfaces/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -161,6 +161,11 @@
required=True,
default=ALWAYS_REFERENCE_MODE)
+ exclude_context = Bool(title=_("Exclude context?"),
+ description=_("If 'yes', context will be excluded from results list"),
+ required=True,
+ default=True)
+
VIEW_THEMES_SETTINGS_KEY = 'pyams_content.view.themes'
--- a/src/pyams_content/shared/view/portlet/__init__.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/view/portlet/__init__.py Wed Jun 27 16:42:01 2018 +0200
@@ -23,6 +23,7 @@
from pyams_content.workflow import PUBLISHED_STATES
from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
from pyams_sequence.utility import get_sequence_target
+from pyams_utils.factory import factory_config
from zope.interface import implementer
from zope.schema.fieldproperty import FieldProperty
@@ -33,6 +34,7 @@
@implementer(IViewItemsPortletSettings)
+@factory_config(provided=IViewItemsPortletSettings)
class ViewItemsPortletSettings(PortletSettings):
"""View items portlet settings"""
@@ -58,4 +60,4 @@
toolbar_image = None
toolbar_css_class = 'fa fa-fw fa-2x fa-th-list'
- settings_class = ViewItemsPortletSettings
+ settings_factory = IViewItemsPortletSettings
--- a/src/pyams_content/shared/view/portlet/templates/view-items-list.pt Wed Jun 27 16:34:12 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-<div tal:repeat="item view.settings.get_items(context)">
- <tal:var content="i18n:item.title" />
-</div>
--- a/src/pyams_content/shared/view/portlet/zmi/templates/view-items-list-preview.pt Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/view/portlet/zmi/templates/view-items-list-preview.pt Wed Jun 27 16:42:01 2018 +0200
@@ -1,22 +1,12 @@
<tal:var define="settings view.settings">
- <tal:if condition="settings.visible">
- <tal:var define="items settings.get_items(context)">
- <tal:if condition="items">
- <div tal:repeat="item items">
- <tal:var content="i18n:item.title" />
- </div>
- </tal:if>
- <tal:if condition="not:items" i18n:translate="">
- No result found
- </tal:if>
- </tal:var>
- </tal:if>
- <tal:if condition="not settings.visible">
- <div class="text-center padding-y-5">
- <span class="fa-stack fa-lg">
- <i class="fa fa-eye fa-stack-1x"></i>
- <i class="fa fa-ban fa-stack-2x text-danger"></i>
- </span>
- </div>
- </tal:if>
+ <tal:var define="items settings.get_items(context)">
+ <tal:if condition="items">
+ <div tal:repeat="item items">
+ <tal:var content="i18n:item.title" />
+ </div>
+ </tal:if>
+ <tal:if condition="not:items" i18n:translate="">
+ No result found
+ </tal:if>
+ </tal:var>
</tal:var>
--- a/src/pyams_content/shared/view/reference.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/view/reference.py Wed Jun 27 16:42:01 2018 +0200
@@ -9,6 +9,7 @@
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
+from pyams_sequence.interfaces import ISequentialIdInfo
__docformat__ = 'restructuredtext'
@@ -19,12 +20,12 @@
# import interfaces
from hypatia.interfaces import ICatalog
from pyams_content.shared.view.interfaces import IWfView, IViewSettings, IViewInternalReferencesSettings, \
- IViewQueryFilterExtension, VIEW_REFERENCES_SETTINGS_KEY, ALWAYS_REFERENCE_MODE
+ IViewQueryParamsExtension, IViewQueryFilterExtension, VIEW_REFERENCES_SETTINGS_KEY, ALWAYS_REFERENCE_MODE
# import packages
from hypatia.catalog import CatalogQuery
-from hypatia.query import Any
-from pyams_catalog.query import CatalogResultSet
+from hypatia.query import Any, Not, NotEq
+from pyams_catalog.query import CatalogResultSet, and_
from pyams_content.workflow import VISIBLE_STATES
from pyams_utils.adapter import adapter_config, ContextAdapter, get_annotation_adapter
from pyams_utils.registry import get_utility
@@ -39,6 +40,7 @@
references = FieldProperty(IViewInternalReferencesSettings['references'])
references_mode = FieldProperty(IViewInternalReferencesSettings['references_mode'])
+ exclude_context = FieldProperty(IViewInternalReferencesSettings['exclude_context'])
@property
def is_using_context(self):
@@ -53,6 +55,23 @@
name='++view:references++')
+@adapter_config(name='references', context=IWfView, provides=IViewQueryParamsExtension)
+class ViewThemesQueryParamsExtension(ContextAdapter):
+ """View internal references query params extension"""
+
+ weight = 50
+
+ def get_params(self, context):
+ catalog = get_utility(ICatalog)
+ settings = IViewInternalReferencesSettings(self.context)
+ params = None
+ # check themes
+ if settings.exclude_context:
+ oid = ISequentialIdInfo(context).hex_oid
+ params = and_(params, NotEq(catalog['oid'], oid))
+ return params
+
+
@adapter_config(name='references', context=IWfView, provides=IViewQueryFilterExtension)
class ViewInternalReferencesQueryFilterExtension(ContextAdapter):
"""View internal references filter extension"""
@@ -65,6 +84,7 @@
return items
if (not items) or (settings.references_mode == ALWAYS_REFERENCE_MODE):
catalog = get_utility(ICatalog)
- params = Any(catalog['oid'], settings.references) & Any(catalog['workflow_state'], VISIBLE_STATES)
+ params = Any(catalog['oid'], settings.references) & \
+ Any(catalog['workflow_state'], VISIBLE_STATES)
items.prepend(CatalogResultSet(CatalogQuery(catalog).query(params)))
return items
--- a/src/pyams_content/shared/view/theme.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/shared/view/theme.py Wed Jun 27 16:42:01 2018 +0200
@@ -16,12 +16,18 @@
# import standard library
# import interfaces
+from hypatia.interfaces import ICatalog
from pyams_content.component.theme.interfaces import IThemesInfo
-from pyams_content.shared.view.interfaces import IWfView, IViewSettings, IViewThemesSettings, VIEW_THEMES_SETTINGS_KEY
+from pyams_content.shared.view.interfaces import IWfView, IViewSettings, IViewThemesSettings, \
+ IViewQueryParamsExtension, VIEW_THEMES_SETTINGS_KEY
+from zope.intid.interfaces import IIntIds
# import packages
+from hypatia.query import Any
from persistent import Persistent
-from pyams_utils.adapter import adapter_config, get_annotation_adapter
+from pyams_catalog.query import and_
+from pyams_utils.adapter import adapter_config, get_annotation_adapter, ContextAdapter
+from pyams_utils.registry import get_utility
from zope.container.contained import Contained
from zope.interface import implementer
from zope.schema.fieldproperty import FieldProperty
@@ -49,7 +55,8 @@
return themes
def get_themes_index(self, context):
- return [theme.label for theme in self.get_themes(context)]
+ intids = get_utility(IIntIds)
+ return [intids.register(term) for term in self.get_themes(context)]
@adapter_config(context=IWfView, provides=IViewThemesSettings)
@@ -58,3 +65,20 @@
"""View themes settings factory"""
return get_annotation_adapter(view, VIEW_THEMES_SETTINGS_KEY, ViewThemesSettings,
name='++view:themes++')
+
+
+@adapter_config(name='themes', context=IWfView, provides=IViewQueryParamsExtension)
+class ViewThemesQueryParamsExtension(ContextAdapter):
+ """View themes query params extension"""
+
+ weight = 50
+
+ def get_params(self, context):
+ catalog = get_utility(ICatalog)
+ settings = IViewThemesSettings(self.context)
+ params = None
+ # check themes
+ themes = settings.get_themes_index(context)
+ if themes:
+ params = and_(params, Any(catalog['themes'], themes))
+ return params
--- a/src/pyams_content/shared/view/zmi/render.py Wed Jun 27 16:34:12 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#
-# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-
-__docformat__ = 'restructuredtext'
-
-
-# import standard library
-
-# import interfaces
-from pyams_content.features.renderer.interfaces import IContentRenderer
-from pyams_content.shared.view.interfaces import IWfView
-from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_content.features.renderer.skin import BaseContentRenderer
-from pyams_template.template import template_config
-from pyams_utils.adapter import adapter_config
-
-
-@adapter_config(name='view-render', context=(IWfView, IPyAMSLayer), provides=IContentRenderer)
-@template_config(template='templates/render.pt', layer=IPyAMSLayer)
-class ViewRenderer(BaseContentRenderer):
- """Shared view renderer"""
-
- weight = 20
-
- @property
- def items(self):
- return self.context.get_results(self.context)
--- a/src/pyams_content/shared/view/zmi/templates/render.pt Wed Jun 27 16:34:12 2018 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-<fieldset i18n:domain="pyams_content">
- <legend class="inner" i18n:translate="">View result items</legend>
- <div class="alert alert-info padding-5" i18n:translate="">
- WARNING: items displayed in this preview are out of context!!
- </div>
- <tal:loop repeat="item view.items">
- <span tal:content="i18n:item.title" /><br />
- </tal:loop>
-</fieldset>
--- a/src/pyams_content/site.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/site.py Wed Jun 27 16:42:01 2018 +0200
@@ -19,6 +19,7 @@
# import interfaces
from hypatia.interfaces import ICatalog
from pyams_content.shared.common.interfaces import IWfSharedContent
+from pyams_content.shared.site.interfaces import IContentLink
from zope.intid.interfaces import IIntIds
# import packages
@@ -38,6 +39,9 @@
for document in find_objects_providing(application, IWfSharedContent):
print("Indexing: {0!r}".format(document))
catalog.reindex_doc(intids.register(document), document)
+ for document in find_objects_providing(application, IContentLink):
+ print("Indexing: {0!r}".format(document))
+ catalog.reindex_doc(intids.register(document), document)
finally:
set_local_registry(None)
transaction.commit()
--- a/src/pyams_content/skin/resources/js/pyams_content.js Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/skin/resources/js/pyams_content.js Wed Jun 27 16:42:01 2018 +0200
@@ -337,7 +337,6 @@
},
updateMarkers: function(settings) {
- debugger;
var para = $('tr[id="' + settings.object_id + '"]');
var toolbar = $('.title-toolbar', para);
var marker = $('DIV.action.' + settings.marker_type, toolbar);
@@ -468,39 +467,6 @@
},
/**
- * Types management
- */
- types: {
-
- switchSubtypes: function(element) {
- var source = $(this);
- var switcher = $('i.switch', source);
- var td = source.parents('td');
- var subtypes = $('.subtypes', td);
- var datatype = source.parents('tr');
- if (switcher.hasClass('fa-plus-square-o')) {
- var container = datatype.parents('table');
- subtypes.html('<h1 class="loading"><i class="fa fa-2x fa-gear fa-spin"></i></h1>');
- MyAMS.ajax.post(container.data('ams-location') + '/get-subtypes-table.json',
- {object_name: datatype.data('ams-element-name')},
- function(result) {
- subtypes.html(result);
- if (result) {
- MyAMS.initContent(subtypes);
- switcher.removeClass('fa-plus-square-o')
- .addClass('fa-minus-square-o');
- }
- });
- } else {
- MyAMS.skin.cleanContainer(subtypes);
- subtypes.empty();
- switcher.removeClass('fa-minus-square-o')
- .addClass('fa-plus-square-o');
- }
- }
- },
-
- /**
* Site management
*/
site: {
@@ -607,6 +573,28 @@
},
/**
+ * Header management
+ */
+ header: {
+
+ submitEditForm: function() {
+ var form = $(this).parents('form').first();
+ MyAMS.form.submit(form, {form_data: {'autosubmit': true}});
+ }
+ },
+
+ /**
+ * Footer management
+ */
+ footer: {
+
+ submitEditForm: function() {
+ var form = $(this).parents('form').first();
+ MyAMS.form.submit(form, {form_data: {'autosubmit': true}});
+ }
+ },
+
+ /**
* User profile management
*/
profile: {
--- a/src/pyams_content/skin/resources/js/pyams_content.min.js Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/skin/resources/js/pyams_content.min.js Wed Jun 27 16:42:01 2018 +0200
@@ -1,1 +1,1 @@
-!function(t,e){"use strict";var a=e.MyAMS,i={widget:{treeview:{selectFolder:function(e,a){t(e.target).siblings('input[type="hidden"]').val(a.id)},unselectFolder:function(e,a){t(e.target).siblings('input[type="hidden"]').val(null)}}},TinyMCE:{initEditor:function(t){return tinyMCE.addI18n("fr",{"Link list":"Liste de liens","Toggle h3 header":"En-tête H3","Toggle h4 header":"En-tête H4","Insert internal link":"Insérer un lien interne","Link title":"Texte à afficher","Internal number":"N° interne"}),tinymce.PluginManager.add("internal_links",function(t,e){t.addButton("internal_links",{icon:"cloud-check",tooltip:"Insert internal link",image:"/--static--/pyams_content/img/internal-link.png",onclick:function(){t.windowManager.open({title:"Insert internal link",body:[{type:"textbox",name:"oid",label:"Internal number"},{type:"textbox",name:"title",label:"Link title",value:t.selection.getContent()}],onsubmit:function(e){t.insertContent('<a href="oid://'+e.data.oid+'">'+e.data.title+"</a>")}})}})}),tinyMCE.PluginManager.add("headers",function(t,e){["h3","h4"].forEach(function(e){t.addButton("header-"+e,{tooltip:"Toggle "+e+" header",text:e.toUpperCase(),onClick:function(){t.execCommand("mceToggleFormat",!1,e)},onPostRender:function(){var a=this,i=function(){t.formatter.formatChanged(e,function(t){a.active(t)})};t.formatter?i():t.on("init",i)}})})}),t.image_list=i.TinyMCE.getImagesList,t.link_list=i.TinyMCE.getLinksList,t.style_formats=[{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}],t.plugins+=" internal_links headers",t.toolbar1&&(t.toolbar1="undo redo | header-h3 header-h4 styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent"),t.toolbar2&&(t.toolbar2="forecolor backcolor | charmap internal_links link | fullscreen preview print | code"),t},getImagesList:function(e){var i=t(document.activeElement).parents("form");if(i.exists()){var n=i.attr("data-ams-form-handler")||i.attr("action"),s=n.substr(0,n.lastIndexOf("/")+1);return a.ajax.post(s+"get-images-list.json",{},e)}},getLinksList:function(e){var i=t(document.activeElement).parents("form");if(i.exists()){var n=i.attr("data-ams-form-handler")||i.attr("action"),s=n.substr(0,n.lastIndexOf("/")+1);return a.ajax.post(s+"get-links-list.json",{},e)}}},galleries:{updateMediaTitle:function(e){t('img[id="'+e.media_id+'"]').attr("original-title",e.title)},switchMediaVisibility:function(e){return function(){var e=t(this),i=e.parents(".media"),n=i.parents(".gallery");a.ajax.post(n.data("ams-location")+"/set-media-visibility.json",{object_name:i.data("ams-element-name")},function(a,i){a.visible?(t("i",e).attr("class","fa fa-fw fa-eye"),e.parents(".btn-group").siblings("a.fancyimg").removeClass("not-visible")):(t("i",e).attr("class","fa fa-fw fa-eye-slash text-danger"),e.parents(".btn-group").siblings("a.fancyimg").addClass("not-visible"))})}},setOrder:function(e,i){if(!i||!i.item.hasClass("already-dropped")){var n=i.item.parents(".gallery"),s=t(".media",n).listattr("data-ams-element-name");a.ajax.post(n.data("ams-location")+"/set-medias-order.json",{medias:JSON.stringify(s)})}},removeMedia:function(e){return function(){var e=t(this);a.skin.bigBox({title:a.i18n.WARNING,content:'<i class="text-danger fa fa-2x fa-bell shake animated"></i> '+a.i18n.DELETE_WARNING,buttons:a.i18n.BTN_OK_CANCEL},function(t){if(t===a.i18n.BTN_OK){var i=e.parents(".gallery").data("ams-location"),n=e.parents(".media"),s=n.data("ams-element-name");a.ajax.post(i+"/delete-element.json",{object_name:s},function(t,e){n.remove()})}})}},afterFancyboxLoad:function(t,e){t.element.hasClass("not-visible")&&t.inner.prepend('<div class="hidden-mask"></div>')}},paragraphs:{preReload:function(){i.paragraphs.switched=t("i.switch.fa-minus-square-o","#paragraphs_list").parents("tr").listattr("id")},postReload:function(){t(i.paragraphs.switched).each(function(){t("i.switch.fa-plus-square-o",'[id="'+this+'"]').parents("div").first().click()}),delete i.paragraphs.switched},refreshParagraph:function(e){var a=t('tr[id="'+e.object_id+'"]');t("span.title",a).html(e.title||" - - - - - - - -")},switchEditor:function(e){var i=t(this),n=t("i.switch",i),s=i.parents("td"),r=t(".editor",s),o=i.parents("tr");if(n.hasClass("fa-plus-square-o")){var l=o.parents("table");r.html('<h1 class="loading"><i class="fa fa-2x fa-gear fa-spin"></i></h1>'),a.ajax.post(l.data("ams-location")+"/get-paragraph-editor.json",{object_name:o.data("ams-element-name")},function(t){r.html(t),t&&(a.initContent(r),n.removeClass("fa-plus-square-o").addClass("fa-minus-square-o"),o.data("ams-disabled-handlers",!0),a.skin.scrollTo(r,{offset:r.height()-o.height()}))})}else a.skin.cleanContainer(r),r.empty(),n.removeClass("fa-minus-square-o").addClass("fa-plus-square-o"),o.removeData("ams-disabled-handlers")},switchLastEditor:function(e){var a=t('table[id="'+e+'"]'),i=t("tr:last",a);t('[data-ams-click-handler="PyAMS_content.paragraphs.switchEditor"]',i).click()},switchAllEditors:function(e){var i=t(this),n=t("i",i),s=i.parents("table");n.hasClass("fa-plus-square-o")?(n.removeClass("fa-plus-square-o").addClass("fa-cog fa-spin"),a.ajax.post(s.data("ams-location")+"/get-paragraphs-editors.json",{},function(e){for(var i in e)if(e.hasOwnProperty(i)){var r=t('tr[data-ams-element-name="'+i+'"]',s),o=t(".editor",r);o.is(":empty")&&o.html(e[i]),t(".fa-plus-square-o",r).removeClass("fa-plus-square-o").addClass("fa-minus-square-o"),r.data("ams-disabled-handlers",!0)}t("i.fa-plus-square-o",t("tbody",s)).exists()||n.removeClass("fa-cog fa-spin").addClass("fa-minus-square-o"),a.initContent(s)})):(t(".editor",s).each(function(){a.skin.cleanContainer(t(this)),t(this).empty()}),t(".fa-minus-square-o",s).removeClass("fa-minus-square-o").addClass("fa-plus-square-o"),t("tr",s).removeData("ams-disabled-handlers"))},updateToolbar:function(e){var i=t('tr[id="'+e.object_id+'"]'),n=t(".title-toolbar",i);n.replaceWith(e.toolbar_tag),n=t(".title-toolbar",i),a.initContent(n)},updateMarkers:function(e){var i=t('tr[id="'+e.object_id+'"]'),n=t(".title-toolbar",i),s=t("DIV.action."+e.marker_type,n);s.exists()?s.replaceWith(e.marker_tag):t(e.marker_tag).appendTo(n),e.marker_tag&&(s=t("DIV.action."+e.marker_type,n),a.initContent(s)),a.helpers.sort(n,"weight")}},pictograms:{initManagerSelection:function(){var e=t(this),a=t('input[type="hidden"]',t(".selected-pictograms",e)).listattr("value");return{selected:JSON.stringify(a)}},switchPictogram:function(){var e=t(this),a=e.parents(".pictograms"),i=a.parents(".pictograms-manager");a.hasClass("available-pictograms")?t(".selected-pictograms",i).append(e):t(".available-pictograms",i).append(e)}},themes:{initExtracts:function(e){var i=t('select[name="form.widgets.thesaurus_name:list"]',e).val(),n=t('select[name="form.widgets.extract_name:list"]',e),s=n.val();i&&a.jsonrpc.post("getExtracts",{thesaurus_name:i},{url:"/api/thesaurus/json"},function(e){n.empty(),t(e.result).each(function(){t("<option></option>").attr("value",this.id).attr("selected",this.id===s).text(this.text).appendTo(n)})}),n.attr("data-ams-events-handlers",'{"select2-open": "PyAMS_content.themes.getExtracts"}')},getExtracts:function(e){var i=t(e.currentTarget).parents("form"),n=t('select[name="form.widgets.thesaurus_name:list"]',i).val();n&&a.jsonrpc.post("getExtracts",{thesaurus_name:n},{url:"/api/thesaurus/json"},function(e){var a=t('select[name="form.widgets.extract_name:list"]',i).data("select2");a.results.empty(),a.opts.populateResults.call(a,a.results,e.result,{term:""})})}},fields:{refreshField:function(e){var a=t('table[id="form_fields_list"]'),i=t('tr[data-ams-element-name="'+e.object_name+'"]',a);t("td:nth-child(4)",i).html(e.title)}},imgmap:{init:function(){var e=t(this);a.ajax.check(t.fn.canvasAreaDraw,"/--static--/pyams_content/js/jquery-canvasAreaDraw"+a.devext+".js",function(){e.canvasAreaDraw({imageUrl:e.data("ams-image-url")})})},initPreview:function(){var e=t(this);a.ajax.check(t.fn.mapster,"/--static--/pyams_content/js/jquery-imagemapster-1.2.10"+a.devext+".js",function(){e.mapster({fillColor:"ff0000",fillOpacity:.35,selected:!0,highlight:!0,staticState:!0})})}},types:{switchSubtypes:function(e){var i=t(this),n=t("i.switch",i),s=i.parents("td"),r=t(".subtypes",s),o=i.parents("tr");if(n.hasClass("fa-plus-square-o")){var l=o.parents("table");r.html('<h1 class="loading"><i class="fa fa-2x fa-gear fa-spin"></i></h1>'),a.ajax.post(l.data("ams-location")+"/get-subtypes-table.json",{object_name:o.data("ams-element-name")},function(t){r.html(t),t&&(a.initContent(r),n.removeClass("fa-plus-square-o").addClass("fa-minus-square-o"))})}else a.skin.cleanContainer(r),r.empty(),n.removeClass("fa-minus-square-o").addClass("fa-plus-square-o")}},site:{switchVisibility:function(){return function(){var e=t(this),i=e.parents("tr").first();a.ajax.post(i.data("ams-location")+"/switch-content-visibility.json",{object_name:i.data("ams-element-name")},function(a,i){var n="fa-eye";a.visible||(n+="-slash"),a.published||(n+=" text-danger"),t("i",e).attr("class","fa fa-fw "+n)})}}},review:{timer:null,timer_duration:{general:3e4,chat:5e3},initComments:function(e){var n=t(".chat-body",e);n.animate({scrollTop:n[0].scrollHeight},1e3),clearInterval(i.review.timer),i.review.timer=setInterval(i.review.updateComments,i.review.timer_duration.chat),a.skin.registerCleanCallback(i.review.cleanCommentsCallback)},cleanCommentsCallback:function(){clearInterval(i.review.timer),i.review.timer=setInterval(i.review.updateComments,i.review.timer_duration.general)},updateComments:function(){var e,i=t(".badge",'nav a[href="#review-comments.html"]'),n=t(".chat-body",".widget-body");e=n.exists()?t(".message",n).length:parseInt(i.text()),a.ajax.post("get-last-review-comments.json",{count:e},function(a){n.exists()&&i.removeClass("bg-color-danger").addClass("bg-color-info"),e!==a.count&&(i.text(a.count).removeClass("hidden"),n.exists()&&(t(".messages",n).append(a.content),n.animate({scrollTop:n[0].scrollHeight},1e3)),n.exists()||i.removeClass("bg-color-info").addClass("bg-color-danger").animate({padding:"3px 12px 2px","margin-right":"9px"},"slow",function(){t(this).animate({padding:"3px 6px 2px","margin-right":"15px"},"slow")}))})},initCommentData:function(e){var a=t(".chat-body",".widget-body");return{count:t(".message",a).length}},addCommentAction:function(){return function(){t('textarea[name="comment"]').focus()}},addCommentCallback:function(e){var a=t(this),i=a.parents(".widget-body");t(".messages",i).append(e.content),t('textarea[name="comment"]',a).val("");var n=t(".chat-body",i);n.animate({scrollTop:n[0].scrollHeight},1e3),t(".badge",'nav a[href="#review-comments.html"]').text(e.count).removeClass("hidden")}},profile:{switchFavorite:function(){var e=t(this),i=e.data("sequence-oid");a.ajax.post("switch-user-favorite.json",{oid:i},function(t,a){t.favorite?e.removeClass("fa-star-o").addClass("fa-star"):e.removeClass("fa-star").addClass("fa-star-o")})}}};t(".badge",'nav a[href="#review-comments.html"]').exists()&&(i.review.timer=setInterval(i.review.updateComments,i.review.timer_duration.general)),e.PyAMS_content=i}(jQuery,this);
+!function(o,t){"use strict";var l=t.MyAMS,a={widget:{treeview:{selectFolder:function(t,e){o(t.target).siblings('input[type="hidden"]').val(e.id)},unselectFolder:function(t,e){o(t.target).siblings('input[type="hidden"]').val(null)}}},TinyMCE:{initEditor:function(t){return tinyMCE.addI18n("fr",{"Link list":"Liste de liens","Toggle h3 header":"En-tête H3","Toggle h4 header":"En-tête H4","Insert internal link":"Insérer un lien interne","Link title":"Texte à afficher","Internal number":"N° interne"}),tinymce.PluginManager.add("internal_links",function(e,t){e.addButton("internal_links",{icon:"cloud-check",tooltip:"Insert internal link",image:"/--static--/pyams_content/img/internal-link.png",onclick:function(){e.windowManager.open({title:"Insert internal link",body:[{type:"textbox",name:"oid",label:"Internal number"},{type:"textbox",name:"title",label:"Link title",value:e.selection.getContent()}],onsubmit:function(t){e.insertContent('<a href="oid://'+t.data.oid+'">'+t.data.title+"</a>")}})}})}),tinyMCE.PluginManager.add("headers",function(i,t){["h3","h4"].forEach(function(a){i.addButton("header-"+a,{tooltip:"Toggle "+a+" header",text:a.toUpperCase(),onClick:function(){i.execCommand("mceToggleFormat",!1,a)},onPostRender:function(){var e=this,t=function(){i.formatter.formatChanged(a,function(t){e.active(t)})};i.formatter?t():i.on("init",t)}})})}),t.image_list=a.TinyMCE.getImagesList,t.link_list=a.TinyMCE.getLinksList,t.style_formats=[{title:"Inline",items:[{title:"Bold",icon:"bold",format:"bold"},{title:"Italic",icon:"italic",format:"italic"},{title:"Underline",icon:"underline",format:"underline"},{title:"Strikethrough",icon:"strikethrough",format:"strikethrough"},{title:"Superscript",icon:"superscript",format:"superscript"},{title:"Subscript",icon:"subscript",format:"subscript"},{title:"Code",icon:"code",format:"code"}]},{title:"Blocks",items:[{title:"Paragraph",format:"p"},{title:"Blockquote",format:"blockquote"},{title:"Div",format:"div"},{title:"Pre",format:"pre"}]},{title:"Alignment",items:[{title:"Left",icon:"alignleft",format:"alignleft"},{title:"Center",icon:"aligncenter",format:"aligncenter"},{title:"Right",icon:"alignright",format:"alignright"},{title:"Justify",icon:"alignjustify",format:"alignjustify"}]}],t.plugins+=" internal_links headers",t.toolbar1&&(t.toolbar1="undo redo | header-h3 header-h4 styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent"),t.toolbar2&&(t.toolbar2="forecolor backcolor | charmap internal_links link | fullscreen preview print | code"),t},getImagesList:function(t){var e=o(document.activeElement).parents("form");if(e.exists()){var a=e.attr("data-ams-form-handler")||e.attr("action"),i=a.substr(0,a.lastIndexOf("/")+1);return l.ajax.post(i+"get-images-list.json",{},t)}},getLinksList:function(t){var e=o(document.activeElement).parents("form");if(e.exists()){var a=e.attr("data-ams-form-handler")||e.attr("action"),i=a.substr(0,a.lastIndexOf("/")+1);return l.ajax.post(i+"get-links-list.json",{},t)}}},galleries:{updateMediaTitle:function(t){o('img[id="'+t.media_id+'"]').attr("original-title",t.title)},switchMediaVisibility:function(t){return function(){var a=o(this),t=a.parents(".media"),e=t.parents(".gallery");l.ajax.post(e.data("ams-location")+"/set-media-visibility.json",{object_name:t.data("ams-element-name")},function(t,e){t.visible?(o("i",a).attr("class","fa fa-fw fa-eye"),a.parents(".btn-group").siblings("a.fancyimg").removeClass("not-visible")):(o("i",a).attr("class","fa fa-fw fa-eye-slash text-danger"),a.parents(".btn-group").siblings("a.fancyimg").addClass("not-visible"))})}},setOrder:function(t,e){if(!e||!e.item.hasClass("already-dropped")){var a=e.item.parents(".gallery"),i=o(".media",a).listattr("data-ams-element-name");l.ajax.post(a.data("ams-location")+"/set-medias-order.json",{medias:JSON.stringify(i)})}},removeMedia:function(t){return function(){var n=o(this);l.skin.bigBox({title:l.i18n.WARNING,content:'<i class="text-danger fa fa-2x fa-bell shake animated"></i> '+l.i18n.DELETE_WARNING,buttons:l.i18n.BTN_OK_CANCEL},function(t){if(t===l.i18n.BTN_OK){var e=n.parents(".gallery").data("ams-location"),a=n.parents(".media"),i=a.data("ams-element-name");l.ajax.post(e+"/delete-element.json",{object_name:i},function(t,e){a.remove()})}})}},afterFancyboxLoad:function(t,e){t.element.hasClass("not-visible")&&t.inner.prepend('<div class="hidden-mask"></div>')}},paragraphs:{preReload:function(){a.paragraphs.switched=o("i.switch.fa-minus-square-o","#paragraphs_list").parents("tr").listattr("id")},postReload:function(){o(a.paragraphs.switched).each(function(){o("i.switch.fa-plus-square-o",'[id="'+this+'"]').parents("div").first().click()}),delete a.paragraphs.switched},refreshParagraph:function(t){var e=o('tr[id="'+t.object_id+'"]');o("span.title",e).html(t.title||" - - - - - - - -")},switchEditor:function(t){var e=o(this),a=o("i.switch",e),i=e.parents("td"),n=o(".editor",i),s=e.parents("tr");if(a.hasClass("fa-plus-square-o")){var r=s.parents("table");n.html('<h1 class="loading"><i class="fa fa-2x fa-gear fa-spin"></i></h1>'),l.ajax.post(r.data("ams-location")+"/get-paragraph-editor.json",{object_name:s.data("ams-element-name")},function(t){n.html(t),t&&(l.initContent(n),a.removeClass("fa-plus-square-o").addClass("fa-minus-square-o"),s.data("ams-disabled-handlers",!0),l.skin.scrollTo(n,{offset:n.height()-s.height()}))})}else l.skin.cleanContainer(n),n.empty(),a.removeClass("fa-minus-square-o").addClass("fa-plus-square-o"),s.removeData("ams-disabled-handlers")},switchLastEditor:function(t){var e=o('table[id="'+t+'"]'),a=o("tr:last",e);o('[data-ams-click-handler="PyAMS_content.paragraphs.switchEditor"]',a).click()},switchAllEditors:function(t){var e=o(this),n=o("i",e),s=e.parents("table");n.hasClass("fa-plus-square-o")?(n.removeClass("fa-plus-square-o").addClass("fa-cog fa-spin"),l.ajax.post(s.data("ams-location")+"/get-paragraphs-editors.json",{},function(t){for(var e in t)if(t.hasOwnProperty(e)){var a=o('tr[data-ams-element-name="'+e+'"]',s),i=o(".editor",a);i.is(":empty")&&i.html(t[e]),o(".fa-plus-square-o",a).removeClass("fa-plus-square-o").addClass("fa-minus-square-o"),a.data("ams-disabled-handlers",!0)}o("i.fa-plus-square-o",o("tbody",s)).exists()||n.removeClass("fa-cog fa-spin").addClass("fa-minus-square-o"),l.initContent(s)})):(o(".editor",s).each(function(){l.skin.cleanContainer(o(this)),o(this).empty()}),o(".fa-minus-square-o",s).removeClass("fa-minus-square-o").addClass("fa-plus-square-o"),o("tr",s).removeData("ams-disabled-handlers"))},updateToolbar:function(t){var e=o('tr[id="'+t.object_id+'"]'),a=o(".title-toolbar",e);a.replaceWith(t.toolbar_tag),a=o(".title-toolbar",e),l.initContent(a)},updateMarkers:function(t){var e=o('tr[id="'+t.object_id+'"]'),a=o(".title-toolbar",e),i=o("DIV.action."+t.marker_type,a);i.exists()?i.replaceWith(t.marker_tag):o(t.marker_tag).appendTo(a),t.marker_tag&&(i=o("DIV.action."+t.marker_type,a),l.initContent(i)),l.helpers.sort(a,"weight")}},pictograms:{initManagerSelection:function(){var t=o(this),e=o('input[type="hidden"]',o(".selected-pictograms",t)).listattr("value");return{selected:JSON.stringify(e)}},switchPictogram:function(){var t=o(this),e=t.parents(".pictograms"),a=e.parents(".pictograms-manager");e.hasClass("available-pictograms")?o(".selected-pictograms",a).append(t):o(".available-pictograms",a).append(t)}},themes:{initExtracts:function(t){var e=o('select[name="form.widgets.thesaurus_name:list"]',t).val(),a=o('select[name="form.widgets.extract_name:list"]',t),i=a.val();e&&l.jsonrpc.post("getExtracts",{thesaurus_name:e},{url:"/api/thesaurus/json"},function(t){a.empty(),o(t.result).each(function(){o("<option></option>").attr("value",this.id).attr("selected",this.id===i).text(this.text).appendTo(a)})}),a.attr("data-ams-events-handlers",'{"select2-open": "PyAMS_content.themes.getExtracts"}')},getExtracts:function(t){var a=o(t.currentTarget).parents("form"),e=o('select[name="form.widgets.thesaurus_name:list"]',a).val();e&&l.jsonrpc.post("getExtracts",{thesaurus_name:e},{url:"/api/thesaurus/json"},function(t){var e=o('select[name="form.widgets.extract_name:list"]',a).data("select2");e.results.empty(),e.opts.populateResults.call(e,e.results,t.result,{term:""})})}},fields:{refreshField:function(t){var e=o('table[id="form_fields_list"]'),a=o('tr[data-ams-element-name="'+t.object_name+'"]',e);o("td:nth-child(4)",a).html(t.title)}},imgmap:{init:function(){var t=o(this);l.ajax.check(o.fn.canvasAreaDraw,"/--static--/pyams_content/js/jquery-canvasAreaDraw"+l.devext+".js",function(){t.canvasAreaDraw({imageUrl:t.data("ams-image-url")})})},initPreview:function(){var t=o(this);l.ajax.check(o.fn.mapster,"/--static--/pyams_content/js/jquery-imagemapster-1.2.10"+l.devext+".js",function(){t.mapster({fillColor:"ff0000",fillOpacity:.35,selected:!0,highlight:!0,staticState:!0})})}},site:{switchVisibility:function(){return function(){var i=o(this),t=i.parents("tr").first();l.ajax.post(t.data("ams-location")+"/switch-content-visibility.json",{object_name:t.data("ams-element-name")},function(t,e){var a="fa-eye";t.visible||(a+="-slash"),t.published||(a+=" text-danger"),o("i",i).attr("class","fa fa-fw "+a)})}}},review:{timer:null,timer_duration:{general:3e4,chat:5e3},initComments:function(t){var e=o(".chat-body",t);e.animate({scrollTop:e[0].scrollHeight},1e3),clearInterval(a.review.timer),a.review.timer=setInterval(a.review.updateComments,a.review.timer_duration.chat),l.skin.registerCleanCallback(a.review.cleanCommentsCallback)},cleanCommentsCallback:function(){clearInterval(a.review.timer),a.review.timer=setInterval(a.review.updateComments,a.review.timer_duration.general)},updateComments:function(){var e,a=o(".badge",'nav a[href="#review-comments.html"]'),i=o(".chat-body",".widget-body");e=i.exists()?o(".message",i).length:parseInt(a.text()),l.ajax.post("get-last-review-comments.json",{count:e},function(t){i.exists()&&a.removeClass("bg-color-danger").addClass("bg-color-info"),e!==t.count&&(a.text(t.count).removeClass("hidden"),i.exists()&&(o(".messages",i).append(t.content),i.animate({scrollTop:i[0].scrollHeight},1e3)),i.exists()||a.removeClass("bg-color-info").addClass("bg-color-danger").animate({padding:"3px 12px 2px","margin-right":"9px"},"slow",function(){o(this).animate({padding:"3px 6px 2px","margin-right":"15px"},"slow")}))})},initCommentData:function(t){var e=o(".chat-body",".widget-body");return{count:o(".message",e).length}},addCommentAction:function(){return function(){o('textarea[name="comment"]').focus()}},addCommentCallback:function(t){var e=o(this),a=e.parents(".widget-body");o(".messages",a).append(t.content),o('textarea[name="comment"]',e).val("");var i=o(".chat-body",a);i.animate({scrollTop:i[0].scrollHeight},1e3),o(".badge",'nav a[href="#review-comments.html"]').text(t.count).removeClass("hidden")}},header:{submitEditForm:function(){var t=o(this).parents("form").first();l.form.submit(t,{form_data:{autosubmit:!0}})}},footer:{submitEditForm:function(){var t=o(this).parents("form").first();l.form.submit(t,{form_data:{autosubmit:!0}})}},profile:{switchFavorite:function(){var a=o(this),t=a.data("sequence-oid");l.ajax.post("switch-user-favorite.json",{oid:t},function(t,e){t.favorite?a.removeClass("fa-star-o").addClass("fa-star"):a.removeClass("fa-star").addClass("fa-star-o")})}}};o(".badge",'nav a[href="#review-comments.html"]').exists()&&(a.review.timer=setInterval(a.review.updateComments,a.review.timer_duration.general)),t.PyAMS_content=a}(jQuery,this);
--- a/src/pyams_content/skin/routes.py Wed Jun 27 16:34:12 2018 +0200
+++ b/src/pyams_content/skin/routes.py Wed Jun 27 16:42:01 2018 +0200
@@ -26,7 +26,7 @@
from pyams_catalog.query import CatalogResultSet
from pyams_content.workflow import VISIBLE_STATES
from pyams_utils.registry import get_utility
-from pyams_utils.url import absolute_url
+from pyams_utils.url import absolute_url, canonical_url
from pyramid.exceptions import NotFound
from pyramid.response import Response
from pyramid.view import view_config
@@ -51,12 +51,13 @@
params &= Any(catalog['workflow_state'], VISIBLE_STATES)
results = list(CatalogResultSet(CatalogQuery(catalog).query(params)))
if results:
+ response = Response()
+ response.status_code = 302
if view_name: # back-office access => last version
version = IWorkflowVersions(results[0]).get_last_versions()[0]
+ response.location = absolute_url(version, request, '/'.join(view_name))
else:
version = results[0]
- response = Response()
- response.status_code = 302
- response.location = absolute_url(version, request, '/'.join(view_name))
+ response.location = canonical_url(version, request)
return response
raise NotFound()