# HG changeset patch # User Damien Correia # Date 1542114302 -3600 # Node ID 3d259e1718ef50ba9ee5fed454d5a1946554f928 # Parent a5e56749ca3d78368a9b85f601936b05a17ce18d# Parent 6b6a884fa28aa34c99e0aa696ea2e0b8b938f224 Merge default diff -r a5e56749ca3d -r 3d259e1718ef .hgtags --- a/.hgtags Fri Oct 12 14:33:03 2018 +0200 +++ b/.hgtags Tue Nov 13 14:05:02 2018 +0100 @@ -30,3 +30,7 @@ 0ca2b4efb1589f728f5d6b65cef339d357f5e08f 0.1.21 0ca2b4efb1589f728f5d6b65cef339d357f5e08f 0.1.21 9b87a68986bf0b3c9b210707f7abf156ce799e5b 0.1.21 +56cbd405769f11a6861e7fc8dcc696aafaf0307a 0.1.22 +b371683a9aa7df8e45566023574607672467f555 0.1.23 +18aaa69eee31629d77a23466cec72cfdad9f5bd8 0.1.24 +5df53dbacc2e03f12d8bad9909d336b69f591adb 0.1.25 diff -r a5e56749ca3d -r 3d259e1718ef buildout.cfg --- a/buildout.cfg Fri Oct 12 14:33:03 2018 +0200 +++ b/buildout.cfg Tue Nov 13 14:05:02 2018 +0100 @@ -86,4 +86,4 @@ eggs = pyams_content [test] [versions] -pyams_content = 0.1.21 +pyams_content = 0.1.26 diff -r a5e56749ca3d -r 3d259e1718ef docs/HISTORY.txt --- a/docs/HISTORY.txt Fri Oct 12 14:33:03 2018 +0200 +++ b/docs/HISTORY.txt Tue Nov 13 14:05:02 2018 +0100 @@ -1,6 +1,33 @@ History ======= +0.1.25 +------ + - added pictograms manager to handle empty pictograms list + - keep order when updating container's object URL's + - updated permission to access properties view + - corrected OpenGraph locale tags + +0.1.24 +------ + - updated public title of attachments + - check view's context before using it's content type + - get view's internal references into given order + +0.1.23 +------ + - added check in text with prefix widgets + - updated attachment public title + +0.1.22 +------ + - sort pictograms in manager settings form + - use request hostname in portlets cache key + - added attributes, methods and portlet related to site navigation + - added settings to add prefix to all external files download links + - added sitemap and "robots.txt" views + - updated videos renderers + 0.1.21 ------ - updated cancel button's type in paragraphs inner edit forms diff -r a5e56749ca3d -r 3d259e1718ef setup.py --- a/setup.py Fri Oct 12 14:33:03 2018 +0200 +++ b/setup.py Tue Nov 13 14:05:02 2018 +0100 @@ -24,7 +24,7 @@ README = os.path.join(DOCS, 'README.txt') HISTORY = os.path.join(DOCS, 'HISTORY.txt') -version = '0.1.21' +version = '0.1.26' long_description = open(README).read() + '\n\n' + open(HISTORY).read() tests_require = [] @@ -105,7 +105,7 @@ 'pyams_index = pyams_content.scripts.index:index_site' ], 'fanstatic.libraries': [ - 'pyams_content = pyams_content.skin:library' + 'pyams_content = pyams_content.zmi:library' ], 'zodbupdate': [ 'renames = pyams_content.generations:RENAMED_CLASSES' diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content.egg-info/PKG-INFO --- a/src/pyams_content.egg-info/PKG-INFO Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content.egg-info/PKG-INFO Tue Nov 13 14:05:02 2018 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyams-content -Version: 0.1.21 +Version: 0.1.25 Summary: PyAMS base content interfaces and classes Home-page: http://hg.ztfy.org/pyams/pyams_content Author: Thierry Florac @@ -72,6 +72,33 @@ History ======= + 0.1.25 + ------ + - added pictograms manager to handle empty pictograms list + - keep order when updating container's object URL's + - updated permission to access properties view + - corrected OpenGraph locale tags + + 0.1.24 + ------ + - updated public title of attachments + - check view's context before using it's content type + - get view's internal references into given order + + 0.1.23 + ------ + - added check in text with prefix widgets + - updated attachment public title + + 0.1.22 + ------ + - sort pictograms in manager settings form + - use request hostname in portlets cache key + - added attributes, methods and portlet related to site navigation + - added settings to add prefix to all external files download links + - added sitemap and "robots.txt" views + - updated videos renderers + 0.1.21 ------ - updated cancel button's type in paragraphs inner edit forms diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content.egg-info/SOURCES.txt --- a/src/pyams_content.egg-info/SOURCES.txt Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content.egg-info/SOURCES.txt Tue Nov 13 14:05:02 2018 +0100 @@ -24,9 +24,14 @@ src/pyams_content/component/association/zmi/interfaces.py src/pyams_content/component/association/zmi/paragraph.py src/pyams_content/component/extfile/__init__.py +src/pyams_content/component/extfile/manager.py src/pyams_content/component/extfile/interfaces/__init__.py src/pyams_content/component/extfile/zmi/__init__.py src/pyams_content/component/extfile/zmi/container.py +src/pyams_content/component/extfile/zmi/manager.py +src/pyams_content/component/extfile/zmi/widget.py +src/pyams_content/component/extfile/zmi/templates/extfile-title-display.pt +src/pyams_content/component/extfile/zmi/templates/extfile-title-input.pt src/pyams_content/component/file/__init__.py src/pyams_content/component/gallery/__init__.py src/pyams_content/component/gallery/file.py @@ -196,6 +201,12 @@ src/pyams_content/features/review/zmi/templates/review-comments-json.pt src/pyams_content/features/review/zmi/templates/review-comments.pt src/pyams_content/features/review/zmi/templates/review-notification.pt +src/pyams_content/features/sitemap/__init__.py +src/pyams_content/features/sitemap/skin/__init__.py +src/pyams_content/features/sitemap/skin/templates/humans.pt +src/pyams_content/features/sitemap/skin/templates/robots.pt +src/pyams_content/features/sitemap/skin/templates/root-sitemap.pt +src/pyams_content/features/sitemap/skin/templates/tool-sitemap.pt src/pyams_content/generations/__init__.py src/pyams_content/interfaces/__init__.py src/pyams_content/interfaces/container.py @@ -336,8 +347,14 @@ src/pyams_content/shared/site/link.py src/pyams_content/shared/site/manager.py src/pyams_content/shared/site/interfaces/__init__.py +src/pyams_content/shared/site/portlet/__init__.py +src/pyams_content/shared/site/portlet/interfaces.py +src/pyams_content/shared/site/portlet/zmi/__init__.py +src/pyams_content/shared/site/portlet/zmi/templates/site-summary-preview.pt src/pyams_content/shared/site/skin/__init__.py src/pyams_content/shared/site/skin/breadcrumb.py +src/pyams_content/shared/site/skin/folder.py +src/pyams_content/shared/site/skin/link.py src/pyams_content/shared/site/zmi/__init__.py src/pyams_content/shared/site/zmi/container.py src/pyams_content/shared/site/zmi/folder.py diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/association/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/association/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,103 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_content.component.paragraph.interfaces import IBaseParagraph +from zope.annotation.interfaces import IAttributeAnnotatable +from zope.container.interfaces import IOrderedContainer + +# import packages +from zope.container.constraints import containers, contains +from zope.interface import Interface, Attribute +from zope.schema import Bool, Choice + +from pyams_content import _ + + +ASSOCIATION_CONTAINER_KEY = 'pyams_content.associations' + + +class IAssociationItem(IAttributeAnnotatable): + """Base association item interface""" + + containers('.IAssociationContainer') + + icon_class = Attribute("Icon class in associations list") + icon_hint = Attribute("Icon hint in associations list") + + visible = Bool(title=_("Visible?"), + description=_("Is this item visible in front-office?"), + required=True, + default=True) + + def is_visible(self, request=None): + """Is association item published?""" + + def get_url(self, request=None, view_name=None): + """Get link URL""" + + +class IAssociationInfo(Interface): + """Association information interface""" + + pictogram = Attribute("Association pictogram") + + user_title = Attribute("Association title proposed on public site") + + user_icon = Attribute("Iocn associated with user title") + + inner_title = Attribute("Inner content, if available") + + human_size = Attribute("Content size, if available") + + +class IAssociationContainer(IOrderedContainer): + """Associations container interface""" + + contains(IAssociationItem) + + def append(self, value, notify=True): + """Append given value to container""" + + def get_visible_items(self, request=None): + """Get list of visible items""" + + +class IAssociationContainerTarget(IAttributeAnnotatable): + """Associations container target interface""" + + +class IAssociationRenderer(Interface): + """Association renderer adapter interface""" + + +# +# Associations paragraph +# + +ASSOCIATION_PARAGRAPH_TYPE = 'Associations' +ASSOCIATION_PARAGRAPH_NAME = _("Associations") +ASSOCIATION_PARAGRAPH_RENDERERS = 'PyAMS.associations.renderers' + + +class IAssociationParagraph(IBaseParagraph): + """Associations paragraph interface""" + + renderer = Choice(title=_("Associations template"), + description=_("Presentation template used for associations"), + vocabulary=ASSOCIATION_PARAGRAPH_RENDERERS, + default='default') diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/association/interfaces/__init__.py --- a/src/pyams_content/component/association/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces -from pyams_content.component.paragraph.interfaces import IBaseParagraph -from zope.annotation.interfaces import IAttributeAnnotatable -from zope.container.interfaces import IOrderedContainer - -# import packages -from zope.container.constraints import containers, contains -from zope.interface import Interface, Attribute -from zope.schema import Bool, Choice - -from pyams_content import _ - - -ASSOCIATION_CONTAINER_KEY = 'pyams_content.associations' - - -class IAssociationItem(IAttributeAnnotatable): - """Base association item interface""" - - containers('.IAssociationContainer') - - icon_class = Attribute("Icon class in associations list") - icon_hint = Attribute("Icon hint in associations list") - - visible = Bool(title=_("Visible?"), - description=_("Is this item visible in front-office?"), - required=True, - default=True) - - def is_visible(self, request=None): - """Is association item published?""" - - def get_url(self, request=None, view_name=None): - """Get link URL""" - - -class IAssociationInfo(Interface): - """Association information interface""" - - pictogram = Attribute("Association pictogram") - - user_title = Attribute("Association title proposed on public site") - - user_icon = Attribute("Iocn associated with user title") - - inner_title = Attribute("Inner content, if available") - - human_size = Attribute("Content size, if available") - - -class IAssociationContainer(IOrderedContainer): - """Associations container interface""" - - contains(IAssociationItem) - - def append(self, value, notify=True): - """Append given value to container""" - - def get_visible_items(self, request=None): - """Get list of visible items""" - - -class IAssociationContainerTarget(IAttributeAnnotatable): - """Associations container target interface""" - - -class IAssociationRenderer(Interface): - """Association renderer adapter interface""" - - -# -# Associations paragraph -# - -ASSOCIATION_PARAGRAPH_TYPE = 'Associations' -ASSOCIATION_PARAGRAPH_NAME = _("Associations") -ASSOCIATION_PARAGRAPH_RENDERERS = 'PyAMS.associations.renderers' - - -class IAssociationParagraph(IBaseParagraph): - """Associations paragraph interface""" - - renderer = Choice(title=_("Associations template"), - description=_("Presentation template used for associations"), - vocabulary=ASSOCIATION_PARAGRAPH_RENDERERS, - default='default') diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/__init__.py --- a/src/pyams_content/component/extfile/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/extfile/__init__.py Tue Nov 13 14:05:02 2018 +0100 @@ -12,37 +12,33 @@ __docformat__ = 'restructuredtext' - -# import standard library import os -# import interfaces -from pyams_content.component.association.interfaces import IAssociationInfo -from pyams_content.component.extfile.interfaces import IBaseExtFile, IExtFile, IExtImage, IExtVideo, IExtAudio, \ - IExtMedia -from pyams_content.features.checker.interfaces import IContentChecker, MISSING_VALUE, MISSING_LANG_VALUE -from pyams_content.shared.common.interfaces import IWfSharedContent -from pyams_file.interfaces import IFileInfo, IImage, IResponsiveImage -from pyams_i18n.interfaces import II18n, INegotiator, II18nManager +from pyramid.events import subscriber +from pyramid.threadlocal import get_current_registry +from zope.interface import alsoProvides, implementer +from zope.lifecycleevent import ObjectModifiedEvent from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent +from zope.schema.fieldproperty import FieldProperty +from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary -# import packages from pyams_content.component.association import AssociationItem +from pyams_content.component.association.interfaces import IAssociationInfo +from pyams_content.component.extfile.interfaces import IBaseExtFile, IExtAudio, IExtFile, IExtFileManagerInfo, \ + IExtImage, IExtMedia, IExtVideo from pyams_content.features.checker import BaseContentChecker +from pyams_content.features.checker.interfaces import IContentChecker, MISSING_LANG_VALUE, MISSING_VALUE +from pyams_content.shared.common.interfaces import IWfSharedContent from pyams_file.file import EXTENSIONS_THUMBNAILS +from pyams_file.interfaces import IFileInfo, IImage, IResponsiveImage +from pyams_i18n.interfaces import II18n, II18nManager, INegotiator from pyams_i18n.property import I18nFileProperty -from pyams_utils.adapter import adapter_config, ContextAdapter -from pyams_utils.registry import query_utility, get_utility +from pyams_utils.adapter import ContextAdapter, adapter_config +from pyams_utils.registry import get_utility, query_utility from pyams_utils.request import check_request from pyams_utils.size import get_human_size from pyams_utils.traversing import get_parent from pyams_utils.vocabulary import vocabulary_config -from pyramid.events import subscriber -from pyramid.threadlocal import get_current_registry -from zope.interface import implementer, alsoProvides -from zope.lifecycleevent import ObjectModifiedEvent -from zope.schema.fieldproperty import FieldProperty -from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm from pyams_content import _ @@ -87,10 +83,15 @@ @property def user_title(self): + request = check_request() + manager_info = IExtFileManagerInfo(request.root) title = II18n(self.context).query_attribute('title') if not title: title = self.context.filename - return title + if '.' in title: + title, extension = title.rsplit('.', 1) + return '{0} {1}'.format(II18n(manager_info).query_attribute('default_title_prefix', request=request) or '', + title) @property def user_icon(self): @@ -173,6 +174,7 @@ data = I18nFileProperty(IExtFile['data']) + register_file_factory('file', ExtFile, _("Standard file")) @@ -185,7 +187,7 @@ request = check_request() translate = request.localizer.translate return II18n(self.context).query_attribute('title', request) or \ - '({0})'.format(translate(self.context.icon_hint).lower()) + '({0})'.format(translate(self.context.icon_hint).lower()) interface = IExtFile @@ -197,7 +199,7 @@ langs = manager.get_languages() else: negotiator = get_utility(INegotiator) - langs = (negotiator.server_language, ) + langs = (negotiator.server_language,) i18n = II18n(self.context) for attr in ('title', 'data'): for lang in langs: @@ -235,6 +237,7 @@ if IImage.providedBy(data): alsoProvides(data, IResponsiveImage) + register_file_factory('image', ExtImage, _("Image")) @@ -254,6 +257,7 @@ data = I18nFileProperty(IExtVideo['data']) + register_file_factory('video', ExtVideo, _("Video")) @@ -273,6 +277,7 @@ data = I18nFileProperty(IExtAudio['data']) + register_file_factory('audio', ExtAudio, _("Audio file")) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/extfile/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,107 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +from zope.interface import Interface +from zope.schema import Choice, TextLine + +from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem +from pyams_i18n.schema import I18nAudioField, I18nFileField, I18nTextField, I18nTextLineField, I18nThumbnailImageField, \ + I18nVideoField + +from pyams_content import _ + + +EXTFILE_CONTAINER_KEY = 'pyams_content.extfile' +EXTFILE_LINKS_CONTAINER_KEY = 'pyams_content.extfile.links' + + +class IBaseExtFile(IAssociationItem): + """Base external file interface""" + + title = I18nTextLineField(title=_("Download link label"), + description=_("Label of download link, as shown in front-office"), + required=False) + + description = I18nTextField(title=_("Description"), + description=_("File description displayed by front-office template"), + required=False) + + author = TextLine(title=_("Author"), + description=_("Name of document's author"), + required=False) + + language = Choice(title=_("Language"), + description=_("File's content language"), + vocabulary="PyAMS base languages", + required=False) + + filename = TextLine(title=_("Save file as..."), + description=_("Name under which the file will be saved"), + required=False) + + +class IExtFile(IBaseExtFile): + """Generic external file interface""" + + data = I18nFileField(title=_("File data"), + description=_("File content"), + required=True) + + +class IExtMedia(IExtFile): + """External media file interface""" + + +class IExtImage(IExtMedia): + """External image file interface""" + + data = I18nThumbnailImageField(title=_("Image data"), + description=_("Image content"), + required=True) + + +class IExtVideo(IExtMedia): + """External video file interface""" + + data = I18nVideoField(title=_("Video data"), + description=_("Video content"), + required=True) + + +class IExtAudio(IExtMedia): + """External audio file interface""" + + data = I18nAudioField(title=_("Audio data"), + description=_("Audio file content"), + required=True) + + +class IExtFileContainerTarget(IAssociationContainerTarget): + """External files container marker interface""" + + +# +# External files management +# + +EXTFILE_MANAGER_INFO_KEY = 'pyams_content.extfile.manager' + + +class IExtFileManagerInfo(Interface): + """External file manager interface""" + + default_title_prefix = I18nTextLineField(title=_("Default title prefix"), + description=_("If used, this prefix will be automatically added to " + "download link's label of all files"), + required=False) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/interfaces/__init__.py --- a/src/pyams_content/component/extfile/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces -from pyams_content.component.association.interfaces import IAssociationItem, IAssociationContainerTarget - -# import packages -from pyams_i18n.schema import I18nTextLineField, I18nTextField, I18nFileField, I18nThumbnailImageField, \ - I18nVideoField, I18nAudioField -from zope.schema import TextLine, Choice - -from pyams_content import _ - - -EXTFILE_CONTAINER_KEY = 'pyams_content.extfile' -EXTFILE_LINKS_CONTAINER_KEY = 'pyams_content.extfile.links' - - -class IBaseExtFile(IAssociationItem): - """Base external file interface""" - - title = I18nTextLineField(title=_("Alternate title"), - description=_("File title, as shown in front-office"), - required=False) - - description = I18nTextField(title=_("Description"), - description=_("File description displayed by front-office template"), - required=False) - - author = TextLine(title=_("Author"), - description=_("Name of document's author"), - required=False) - - language = Choice(title=_("Language"), - description=_("File's content language"), - vocabulary="PyAMS base languages", - required=False) - - filename = TextLine(title=_("Save file as..."), - description=_("Name under which the file will be saved"), - required=False) - - -class IExtFile(IBaseExtFile): - """Generic external file interface""" - - data = I18nFileField(title=_("File data"), - description=_("File content"), - required=True) - - -class IExtMedia(IExtFile): - """External media file interface""" - - -class IExtImage(IExtMedia): - """External image file interface""" - - data = I18nThumbnailImageField(title=_("Image data"), - description=_("Image content"), - required=True) - - -class IExtVideo(IExtMedia): - """External video file interface""" - - data = I18nVideoField(title=_("Video data"), - description=_("Video content"), - required=True) - - -class IExtAudio(IExtMedia): - """External audio file interface""" - - data = I18nAudioField(title=_("Audio data"), - description=_("Audio file content"), - required=True) - - -class IExtFileContainerTarget(IAssociationContainerTarget): - """External files container marker interface""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/manager.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/extfile/manager.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,33 @@ +# +# Copyright (c) 2008-2018 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +from persistent import Persistent +from zope.interface import implementer +from zope.schema.fieldproperty import FieldProperty + +from pyams_content.component.extfile.interfaces import EXTFILE_MANAGER_INFO_KEY, IExtFileManagerInfo +from pyams_content.root import ISiteRoot +from pyams_utils.adapter import adapter_config, get_annotation_adapter + + +@implementer(IExtFileManagerInfo) +class ExtFileManagerInfo(Persistent): + """external files manager settings""" + + default_title_prefix = FieldProperty(IExtFileManagerInfo['default_title_prefix']) + + +@adapter_config(context=ISiteRoot, provides=IExtFileManagerInfo) +def site_root_extfile_manager_info_factory(context): + return get_annotation_adapter(context, EXTFILE_MANAGER_INFO_KEY, ExtFileManagerInfo) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/zmi/__init__.py --- a/src/pyams_content/component/extfile/zmi/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/extfile/zmi/__init__.py Tue Nov 13 14:05:02 2018 +0100 @@ -22,6 +22,7 @@ from pyams_content.component.extfile import EXTERNAL_FILES_FACTORIES from pyams_content.component.extfile.interfaces import IExtAudio, IExtFile, IExtFileContainerTarget, IExtImage, \ IExtMedia, IExtVideo +from pyams_content.component.extfile.zmi.widget import I18nExtFileTitleFieldWidget 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.component.paragraph.zmi.interfaces import IParagraphContainerTable, IParagraphTitleToolbar @@ -99,6 +100,8 @@ icon_css_class = 'fa fa-fw fa-file-text-o' fields = field.Fields(IExtFile).select('data', 'filename', 'title', 'description', 'author', 'language') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget + edit_permission = MANAGE_CONTENT_PERMISSION def create(self, data): @@ -130,6 +133,8 @@ dialog_class = 'modal-large' fields = field.Fields(IExtFile).select('data', 'filename', 'title', 'description', 'author', 'language') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget + edit_permission = MANAGE_CONTENT_PERMISSION def get_ajax_output(self, changes): @@ -184,6 +189,7 @@ icon_css_class = 'fa fa-fw fa-file-image-o' fields = field.Fields(IExtImage).select('data', 'filename', 'title', 'description', 'author') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget def updateWidgets(self, prefix=None): super(ExtImageAddForm, self).updateWidgets(prefix) @@ -215,6 +221,7 @@ icon_css_class = 'fa fa-fw fa-file-image-o' fields = field.Fields(IExtImage).select('data', 'filename', 'title', 'description', 'author') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget def updateWidgets(self, prefix=None): super(ExtImagePropertiesEditForm, self).updateWidgets(prefix) @@ -275,6 +282,7 @@ icon_css_class = 'fa fa-fw fa-file-video-o' fields = field.Fields(IExtVideo).select('data', 'filename', 'title', 'description', 'author', 'language') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget def create(self, data): factory = EXTERNAL_FILES_FACTORIES.get('video') @@ -299,6 +307,7 @@ icon_css_class = 'fa fa-fw fa-file-video-o' fields = field.Fields(IExtVideo).select('data', 'filename', 'title', 'description', 'author', 'language') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget def get_ajax_output(self, changes): if changes: @@ -352,6 +361,7 @@ icon_css_class = 'fa fa-fw fa-file-audio-o' fields = field.Fields(IExtAudio).select('data', 'filename', 'title', 'description', 'author', 'language') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget def create(self, data): factory = EXTERNAL_FILES_FACTORIES.get('audio') @@ -376,6 +386,7 @@ icon_css_class = 'fa fa-fw fa-file-audio-o' fields = field.Fields(IExtAudio).select('data', 'filename', 'title', 'description', 'author', 'language') + fields['title'].widgetFactory = I18nExtFileTitleFieldWidget def get_ajax_output(self, changes): if changes: diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/zmi/manager.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/extfile/zmi/manager.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,57 @@ +# +# Copyright (c) 2008-2018 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +from z3c.form import field + +from pyams_content.component.extfile.interfaces import IExtFileManagerInfo +from pyams_content.interfaces import MANAGE_SITE_ROOT_PERMISSION +from pyams_content.root import ISiteRoot +from pyams_form.form import ajax_config +from pyams_pagelet.pagelet import pagelet_config +from pyams_skin.layer import IPyAMSLayer +from pyams_skin.viewlet.menu import MenuItem +from pyams_viewlet.viewlet import viewlet_config +from pyams_zmi.form import AdminDialogEditForm +from pyams_zmi.interfaces.menu import IPropertiesMenu +from pyams_zmi.layer import IAdminLayer + +from pyams_content import _ + + +@viewlet_config(name='extfiles-manager.menu', context=ISiteRoot, layer=IAdminLayer, + manager=IPropertiesMenu, permission=MANAGE_SITE_ROOT_PERMISSION, weight=80) +class ExtFileManagerMenu(MenuItem): + """External files manager menu""" + + label = _("External files...") + icon_class = 'fa-file-o' + url = 'extfiles-manager.html' + modal_target = True + + +@pagelet_config(name='extfiles-manager.html', context=ISiteRoot, layer=IPyAMSLayer, + permission=MANAGE_SITE_ROOT_PERMISSION) +@ajax_config(name='extfiles-manager.json', context=ISiteRoot, layer=IPyAMSLayer) +class ExtFileManagerInfoEditForm(AdminDialogEditForm): + """External files manager properties edit form""" + + prefix = 'extfiles_manager_info.' + + legend = _("External files properties") + + fields = field.Fields(IExtFileManagerInfo) + edit_permission = MANAGE_SITE_ROOT_PERMISSION + + def getContent(self): + return IExtFileManagerInfo(self.context) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/zmi/templates/extfile-title-display.pt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/extfile/zmi/templates/extfile-title-display.pt Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,20 @@ +
+ ${view/prefix} + +
\ No newline at end of file diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/zmi/templates/extfile-title-input.pt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/extfile/zmi/templates/extfile-title-input.pt Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,37 @@ +
+ ${view/prefix} + +
diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/extfile/zmi/widget.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/extfile/zmi/widget.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,77 @@ +# +# Copyright (c) 2008-2018 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +from z3c.form.browser.text import TextWidget +from z3c.form.interfaces import DISPLAY_MODE, INPUT_MODE, ITextWidget +from z3c.form.widget import FieldWidget +from zope.interface import implementer_only + +from pyams_content.component.extfile.interfaces import IExtFileManagerInfo +from pyams_form.interfaces import IFormLayer +from pyams_form.widget import widgettemplate_config +from pyams_i18n.interfaces import II18n +from pyams_i18n.interfaces.widget import II18nTextLineWidget +from pyams_i18n.widget import I18nTextLineWidget + + +# +# External file title field widget +# + +class IExtFileTitleWidget(ITextWidget): + """External file title field widget interface""" + + +@widgettemplate_config(mode=INPUT_MODE, template='templates/extfile-title-input.pt', layer=IFormLayer) +@widgettemplate_config(mode=DISPLAY_MODE, template='templates/extfile-title-display.pt', layer=IFormLayer) +@implementer_only(IExtFileTitleWidget) +class ExtFileTitleWidget(TextWidget): + """External file title widget""" + + @property + def prefix(self): + manager_info = IExtFileManagerInfo(self.request.root, None) + if manager_info is not None: + lang = getattr(self, 'lang', None) # I18n widget + if lang is not None: + return (manager_info.default_title_prefix or {}).get(lang, '') or '' + else: + return II18n(manager_info).query_attribute('default_title_prefix', request=self.request) or '' + else: + return '' + + +def ExtFileTitleFieldWidget(field, request): + """External file title widget factory""" + return FieldWidget(field, ExtFileTitleWidget(request)) + + +# +# I18n external file title field widget +# + +class II18nExtFileTitleWidget(II18nTextLineWidget): + """I18n external file title field widget interface""" + + +@implementer_only(II18nExtFileTitleWidget) +class I18nExtFileTitleWidget(I18nTextLineWidget): + """I18n external file title widget""" + + +def I18nExtFileTitleFieldWidget(field, request): + """I18n external file title widget factory""" + widget = I18nExtFileTitleWidget(request) + widget.widget_factory = ExtFileTitleFieldWidget + return FieldWidget(field, widget) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/gallery/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/gallery/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,124 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +from zope.annotation.interfaces import IAttributeAnnotatable +from zope.container.constraints import containers, contains +from zope.container.interfaces import IOrderedContainer +from zope.interface import Interface +from zope.schema import Bool, Choice, TextLine + +from pyams_content.component.paragraph.interfaces import IBaseParagraph +from pyams_content.features.renderer.interfaces import IRenderedContent +from pyams_file.schema import AudioField, MediaField +from pyams_i18n.schema import I18nTextField, I18nTextLineField + +from pyams_content import _ + + +GALLERY_CONTAINER_KEY = 'pyams_content.gallery' +GALLERY_RENDERERS = 'PyAMS.gallery.renderers' + + +class IGalleryItem(Interface): + """Gallery item base interface""" + + containers('.IGallery') + + +class IGalleryFile(IGalleryItem): + """Gallery file marker interface""" + + data = MediaField(title=_("Image or video data"), + description=_("Image or video content"), + required=True) + + title = I18nTextLineField(title=_("Legend"), + required=False) + + alt_title = I18nTextLineField(title=_("Accessibility title"), + description=_("Alternate title used to describe media content"), + required=False) + + description = I18nTextField(title=_("Description"), + required=False) + + author = TextLine(title=_("Author"), + description=_("Name of document's author"), + required=True) + + sound = AudioField(title=_("Audio data"), + description=_("Sound file associated with the current media"), + required=False) + + sound_title = I18nTextLineField(title=_("Sound title"), + description=_("Title of associated sound file"), + required=False) + + sound_description = I18nTextField(title=_("Sound description"), + description=_("Short description of associated sound file"), + required=False) + + visible = Bool(title=_("Visible media?"), + description=_("If 'no', this media won't be displayed in front office"), + required=True, + default=True) + + +GALLERY_FILE_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible') + + +class IBaseGallery(IOrderedContainer, IAttributeAnnotatable, IRenderedContent): + """Base gallery interface""" + + renderer = Choice(title=_("Gallery template"), + description=_("Presentation template used for this gallery"), + vocabulary=GALLERY_RENDERERS, + default='default') + + def append(self, value, notify=True): + """Append new file to gallery + + @param value: the media object to append + @param boolean notify: if 'False', the given value object is pre-located so that + adding events are not notified + """ + + def get_visible_medias(self): + """Get iterator over visible medias""" + + +class IGallery(IBaseGallery): + """Gallery interface""" + + contains(IGalleryItem) + + title = I18nTextLineField(title=_("Title"), + description=_("Gallery title, as shown in front-office"), + required=False) + + description = I18nTextField(title=_("Description"), + description=_("Gallery description displayed by front-office template"), + required=False) + + +class IGalleryTarget(IAttributeAnnotatable): + """Gallery container target marker interface""" + + +GALLERY_PARAGRAPH_TYPE = 'Gallery' +GALLERY_PARAGRAPH_NAME = _("Medias gallery") + + +class IGalleryParagraph(IBaseGallery, IBaseParagraph): + """Gallery paragraph""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/gallery/interfaces/__init__.py --- a/src/pyams_content/component/gallery/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - -from zope.annotation.interfaces import IAttributeAnnotatable -from zope.container.constraints import containers, contains -from zope.container.interfaces import IOrderedContainer -from zope.interface import Interface -from zope.schema import Bool, Choice, TextLine - -from pyams_content.component.paragraph.interfaces import IBaseParagraph -from pyams_content.features.renderer.interfaces import IRenderedContent -from pyams_file.schema import AudioField, MediaField -from pyams_i18n.schema import I18nTextField, I18nTextLineField - -from pyams_content import _ - - -GALLERY_CONTAINER_KEY = 'pyams_content.gallery' -GALLERY_RENDERERS = 'PyAMS.gallery.renderers' - - -class IGalleryItem(Interface): - """Gallery item base interface""" - - containers('.IGallery') - - -class IGalleryFile(IGalleryItem): - """Gallery file marker interface""" - - data = MediaField(title=_("Image or video data"), - description=_("Image or video content"), - required=True) - - title = I18nTextLineField(title=_("Legend"), - required=False) - - alt_title = I18nTextLineField(title=_("Accessibility title"), - description=_("Alternate title used to describe media content"), - required=False) - - description = I18nTextField(title=_("Description"), - required=False) - - author = TextLine(title=_("Author"), - description=_("Name of document's author"), - required=True) - - sound = AudioField(title=_("Audio data"), - description=_("Sound file associated with the current media"), - required=False) - - sound_title = I18nTextLineField(title=_("Sound title"), - description=_("Title of associated sound file"), - required=False) - - sound_description = I18nTextField(title=_("Sound description"), - description=_("Short description of associated sound file"), - required=False) - - visible = Bool(title=_("Visible media?"), - description=_("If 'no', this media won't be displayed in front office"), - required=True, - default=True) - - -GALLERY_FILE_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible') - - -class IBaseGallery(IOrderedContainer, IAttributeAnnotatable, IRenderedContent): - """Base gallery interface""" - - renderer = Choice(title=_("Gallery template"), - description=_("Presentation template used for this gallery"), - vocabulary=GALLERY_RENDERERS, - default='default') - - def append(self, value, notify=True): - """Append new file to gallery - - @param value: the media object to append - @param boolean notify: if 'False', the given value object is pre-located so that - adding events are not notified - """ - - def get_visible_medias(self): - """Get iterator over visible medias""" - - -class IGallery(IBaseGallery): - """Gallery interface""" - - contains(IGalleryItem) - - title = I18nTextLineField(title=_("Title"), - description=_("Gallery title, as shown in front-office"), - required=False) - - description = I18nTextField(title=_("Description"), - description=_("Gallery description displayed by front-office template"), - required=False) - - -class IGalleryTarget(IAttributeAnnotatable): - """Gallery container target marker interface""" - - -GALLERY_PARAGRAPH_TYPE = 'Gallery' -GALLERY_PARAGRAPH_NAME = _("Medias gallery") - - -class IGalleryParagraph(IBaseGallery, IBaseParagraph): - """Gallery paragraph""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/gallery/zmi/__init__.py --- a/src/pyams_content/component/gallery/zmi/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/gallery/zmi/__init__.py Tue Nov 13 14:05:02 2018 +0100 @@ -9,6 +9,10 @@ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # +from pyams_content.component.gallery.zmi.paragraph import ParagraphContainerGalleryMarker, GalleryInnerEditForm +from pyams_content.component.paragraph import IBaseParagraph +from pyams_content.component.paragraph.zmi import get_json_paragraph_markers_refresh_event + __docformat__ = 'restructuredtext' @@ -140,7 +144,18 @@ if media is None: raise NotFound() media.visible = not media.visible - return {'visible': media.visible} + result = {'visible': media.visible} + if IBaseParagraph.providedBy(gallery): + form = GalleryInnerEditForm(gallery, request) + form.update() + result.update({ + 'status': 'success', + 'handle_json': True, + 'events': [ + get_json_paragraph_markers_refresh_event(gallery, request, form, ParagraphContainerGalleryMarker) + ] + }) + return result # diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/gallery/zmi/paragraph.py --- a/src/pyams_content/component/gallery/zmi/paragraph.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/gallery/zmi/paragraph.py Tue Nov 13 14:05:02 2018 +0100 @@ -20,6 +20,7 @@ from z3c.form.interfaces import INPUT_MODE from zope.interface import Interface, implementer +from pyams_content.component.gallery import IBaseGallery from pyams_content.component.gallery.interfaces import GALLERY_PARAGRAPH_TYPE, IGalleryParagraph from pyams_content.component.gallery.paragraph import Gallery from pyams_content.component.gallery.zmi.file import GalleryMediaAddForm @@ -27,9 +28,10 @@ from pyams_content.component.paragraph.interfaces import IParagraphContainer, IParagraphContainerTarget from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, BaseParagraphAJAXEditForm, \ BaseParagraphAddMenu, BaseParagraphPropertiesEditForm, IParagraphInnerEditFormButtons, ParagraphContainerTable, \ - get_json_paragraph_refresh_event -from pyams_content.component.paragraph.zmi.interfaces import IParagraphContainerView, IParagraphInnerEditor, \ - IParagraphTitleValue + get_json_paragraph_refresh_event, get_json_paragraph_markers_refresh_event +from pyams_content.component.paragraph.zmi.container import ParagraphContainerCounterBase +from pyams_content.component.paragraph.zmi.interfaces import IParagraphContainerTable, IParagraphContainerView, \ + IParagraphInnerEditor, IParagraphTitleToolbar from pyams_content.features.renderer.zmi.widget import RendererFieldWidget from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION from pyams_content.shared.common.zmi import WfSharedContentPermissionMixin @@ -44,7 +46,7 @@ from pyams_skin.viewlet.toolbar import ToolbarAction from pyams_template.template import template_config from pyams_utils.adapter import adapter_config -from pyams_utils.interfaces import ICacheKeyValue +from pyams_utils.interfaces import ICacheKeyValue, VIEW_SYSTEM_PERMISSION from pyams_utils.traversing import get_parent from pyams_utils.url import absolute_url from pyams_viewlet.viewlet import viewlet_config @@ -74,7 +76,7 @@ legend = _("Add new gallery") icon_css_class = 'fa fa-fw fa-picture-o' - fields = field.Fields(IGalleryParagraph).select('renderer') + fields = field.Fields(IGalleryParagraph).select('title', 'renderer') edit_permission = MANAGE_CONTENT_PERMISSION def create(self, data): @@ -84,20 +86,6 @@ IParagraphContainer(self.context).append(object) -@adapter_config(context=(IGalleryParagraph, IPyAMSLayer), provides=IParagraphTitleValue) -def gallery_paragraph_title_adapter(context, request): - """Gallery paragraph title adapter""" - translate = request.localizer.translate - nb_medias = len(context) - if nb_medias > 1: - title = translate(_("(gallery contains {0} medias)")).format(nb_medias) - elif nb_medias == 1: - title = translate(_("(gallery contains 1 media)")) - else: - title = translate(_("(empty gallery)")) - return '{0}'.format(title) - - @pagelet_config(name='properties.html', context=IGalleryParagraph, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION) @ajax_config(name='properties.json', context=IGalleryParagraph, layer=IPyAMSLayer, @@ -110,7 +98,7 @@ legend = _("Edit gallery properties") icon_css_class = 'fa fa-fw fa-picture-o' - fields = field.Fields(IGalleryParagraph).select('renderer') + fields = field.Fields(IGalleryParagraph).select('title', 'renderer') fields['renderer'].widgetFactory = RendererFieldWidget edit_permission = MANAGE_CONTENT_PERMISSION @@ -132,6 +120,27 @@ # +# Paragraph container gallery marker +# + +@viewlet_config(name='gallery', context=IBaseGallery, layer=IPyAMSLayer, view=IParagraphContainerTable, + manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=5) +class ParagraphContainerGalleryMarker(ParagraphContainerCounterBase): + """Paragraph container gallery marker column""" + + weight = 6 + action_class = 'action gallery-medias nowrap width-40' + icon_class = 'fa fa-fw fa-picture-o' + icon_hint = _("Visible medias") + + marker_type = 'gallery-medias' + + @property + def count(self): + return len(tuple(self.context.get_visible_medias())) + + +# # Gallery contents view # @@ -183,6 +192,8 @@ 'status': 'success', 'message': self.request.localizer.translate(_("Media(s) successfully added")), 'events': [ + get_json_paragraph_markers_refresh_event(self.context, self.request, + self, ParagraphContainerGalleryMarker), get_json_paragraph_refresh_event(self.context, self.request) ], 'callback': 'PyAMS_content.galleries.addMediaCallback', @@ -202,9 +213,13 @@ """Delete media from container""" result = delete_container_element(request, IGalleryParagraph) if result.get('status') == 'success': + form = GalleryInnerEditForm(request.context, request) + form.update() result.update({ 'handle_json': True, 'events': [ + get_json_paragraph_markers_refresh_event(request.context, request, + form, ParagraphContainerGalleryMarker), get_json_paragraph_refresh_event(request.context, request) ] }) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/gallery/zmi/templates/gallery-medias.pt --- a/src/pyams_content/component/gallery/zmi/templates/gallery-medias.pt Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/gallery/zmi/templates/gallery-medias.pt Tue Nov 13 14:05:02 2018 +0100 @@ -1,8 +1,8 @@
diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/gallery/zmi/templates/paragraph-gallery-icon.pt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/gallery/zmi/templates/paragraph-gallery-icon.pt Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,8 @@ +
+ +
diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/illustration/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/illustration/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,105 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +from zope.annotation.interfaces import IAttributeAnnotatable +from zope.interface import Interface +from zope.schema import Choice, TextLine + +from pyams_content import _ +from pyams_content.component.paragraph.interfaces import IBaseParagraph +from pyams_content.features.renderer.interfaces import IRenderedContent +from pyams_i18n.schema import I18nTextField, I18nTextLineField, I18nThumbnailMediaField + + +# +# Illustration +# + +BASIC_ILLUSTRATION_KEY = 'pyams_content.illustration.base' + +ILLUSTRATION_KEY = 'pyams_content.illustration' +ILLUSTRATION_RENDERERS = 'PyAMS.illustration.renderers' + +LINK_ILLUSTRATION_KEY = '{0}::link'.format(ILLUSTRATION_KEY) + + +class IBasicIllustration(Interface): + """Basic illustration interface""" + + data = I18nThumbnailMediaField(title=_("Image or video data"), + description=_("Image or video content"), + required=False) + + def has_data(self): + """Check if data is provided in any language""" + + title = I18nTextLineField(title=_("Legend"), + required=False) + + alt_title = I18nTextLineField(title=_("Accessibility title"), + description=_("Alternate title used to describe image content"), + required=False) + + author = TextLine(title=_("Author"), + description=_("Name of picture's author"), + required=False) + + +class IIllustration(IBasicIllustration, IRenderedContent): + """Illustration paragraph""" + + description = I18nTextField(title=_("Associated text"), + description=_("Illustration description displayed in front-office templates"), + required=False) + + renderer = Choice(title=_("Illustration template"), + description=_("Presentation template used for illustration"), + vocabulary=ILLUSTRATION_RENDERERS, + default='default') + + +class ILinkIllustration(IBasicIllustration): + """Navigation link illustration interface""" + + +class IIllustrationTargetBase(IAttributeAnnotatable): + """Illustration target base interface""" + + +class IBasicIllustrationTarget(IIllustrationTargetBase): + """Basic illustration target marker interface""" + + +class IIllustrationTarget(IBasicIllustrationTarget): + """Illustration target interface""" + + +class ILinkIllustrationTarget(IIllustrationTargetBase): + """Link illustration target interface""" + + +# +# Illustration paragraph +# + +ILLUSTRATION_PARAGRAPH_TYPE = 'Illustration' +ILLUSTRATION_PARAGRAPH_NAME = _("Illustration") + + +class IIllustrationParagraph(IIllustration, IBaseParagraph): + """Illustration paragraph""" + + data = I18nThumbnailMediaField(title=_("Image or video data"), + description=_("Image or video content"), + required=True) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/illustration/interfaces/__init__.py --- a/src/pyams_content/component/illustration/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - -from zope.annotation.interfaces import IAttributeAnnotatable -from zope.interface import Interface -from zope.schema import Choice, TextLine - -from pyams_content import _ -from pyams_content.component.paragraph.interfaces import IBaseParagraph -from pyams_content.features.renderer.interfaces import IRenderedContent -from pyams_i18n.schema import I18nTextField, I18nTextLineField, I18nThumbnailMediaField - - -# -# Illustration -# - -BASIC_ILLUSTRATION_KEY = 'pyams_content.illustration.base' - -ILLUSTRATION_KEY = 'pyams_content.illustration' -ILLUSTRATION_RENDERERS = 'PyAMS.illustration.renderers' - -LINK_ILLUSTRATION_KEY = '{0}::link'.format(ILLUSTRATION_KEY) - - -class IBasicIllustration(Interface): - """Basic illustration interface""" - - data = I18nThumbnailMediaField(title=_("Image or video data"), - description=_("Image or video content"), - required=False) - - def has_data(self): - """Check if data is provided in any language""" - - title = I18nTextLineField(title=_("Legend"), - required=False) - - alt_title = I18nTextLineField(title=_("Accessibility title"), - description=_("Alternate title used to describe image content"), - required=False) - - author = TextLine(title=_("Author"), - description=_("Name of picture's author"), - required=False) - - -class IIllustration(IBasicIllustration, IRenderedContent): - """Illustration paragraph""" - - description = I18nTextField(title=_("Associated text"), - description=_("Illustration description displayed in front-office templates"), - required=False) - - renderer = Choice(title=_("Illustration template"), - description=_("Presentation template used for illustration"), - vocabulary=ILLUSTRATION_RENDERERS, - default='default') - - -class ILinkIllustration(IBasicIllustration): - """Navigation link illustration interface""" - - -class IIllustrationTargetBase(IAttributeAnnotatable): - """Illustration target base interface""" - - -class IBasicIllustrationTarget(IIllustrationTargetBase): - """Basic illustration target marker interface""" - - -class IIllustrationTarget(IBasicIllustrationTarget): - """Illustration target interface""" - - -class ILinkIllustrationTarget(IIllustrationTargetBase): - """Link illustration target interface""" - - -# -# Illustration paragraph -# - -ILLUSTRATION_PARAGRAPH_TYPE = 'Illustration' -ILLUSTRATION_PARAGRAPH_NAME = _("Illustration") - - -class IIllustrationParagraph(IIllustration, IBaseParagraph): - """Illustration paragraph""" - - data = I18nThumbnailMediaField(title=_("Image or video data"), - description=_("Image or video content"), - required=True) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/illustration/zmi/__init__.py --- a/src/pyams_content/component/illustration/zmi/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/illustration/zmi/__init__.py Tue Nov 13 14:05:02 2018 +0100 @@ -18,11 +18,11 @@ from pyams_content.component.illustration.interfaces import IBasicIllustration, IBasicIllustrationTarget, \ IIllustration, IIllustrationTarget, ILinkIllustrationTarget -from pyams_content.component.illustration.zmi.paragraph import ParagraphContainerIllustrationMarker +from pyams_content.component.illustration.zmi.paragraph import ParagraphIllustrationMarker from pyams_content.component.paragraph import IBaseParagraph from pyams_content.component.paragraph.zmi import get_json_paragraph_markers_refresh_event from pyams_content.features.renderer.zmi.widget import RendererFieldWidget -from pyams_content.skin import pyams_content +from pyams_content.zmi import pyams_content from pyams_form.interfaces.form import IInnerSubForm, IWidgetsPrefixViewletsManager from pyams_form.security import ProtectedFormObjectMixin from pyams_skin.event import get_json_form_refresh_event, get_json_widget_refresh_event @@ -100,12 +100,12 @@ if self.getContent().data: events.append( get_json_paragraph_markers_refresh_event(self.context, self.request, self, - ParagraphContainerIllustrationMarker)) + ParagraphIllustrationMarker)) else: events.append( get_json_paragraph_markers_refresh_event(self.context, self.request, self, EmptyViewlet, - ParagraphContainerIllustrationMarker.marker_type)) + ParagraphIllustrationMarker.marker_type)) events.append(get_json_form_refresh_event(self.context, self.request, self.__class__)) return output diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/illustration/zmi/paragraph.py --- a/src/pyams_content/component/illustration/zmi/paragraph.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/illustration/zmi/paragraph.py Tue Nov 13 14:05:02 2018 +0100 @@ -141,11 +141,13 @@ # Paragraph container illustration marker # +@viewlet_config(name='illustration', context=IIllustrationParagraph, layer=IPyAMSLayer, view=IParagraphContainerTable, + manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=5) @viewlet_config(name='illustration', context=IBasicIllustrationTarget, 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""" +class ParagraphIllustrationMarker(Viewlet): + """Paragraph illustration marker column""" weight = 5 action_class = 'action illustration nowrap width-40' @@ -159,5 +161,5 @@ if illustration and illustration.data: for value in illustration.data.values(): if value: - return super(ParagraphContainerIllustrationMarker, self).render() + return super(ParagraphIllustrationMarker, self).render() return '' diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/keynumber/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/keynumber/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,97 @@ +# +# Copyright (c) 2008-2018 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_content.component.paragraph.interfaces import IBaseParagraph +from pyams_content.interfaces.container import IOrderedContainer +from zope.annotation.interfaces import IAttributeAnnotatable + +# import packages +from pyams_i18n.schema import I18nTextLineField +from zope.container.constraints import containers, contains +from zope.interface import Interface +from zope.schema import Bool, TextLine, Choice + +from pyams_content import _ + + +KEYNUMBER_CONTAINER_KEY = 'pyams_content.keynumbers' + + +class IKeyNumber(IAttributeAnnotatable): + """Base key number interface""" + + containers('.IKeyNumberContainer') + + visible = Bool(title=_("Visible?"), + description=_("Is this key number visible in front-office?"), + required=True, + default=True) + + label = I18nTextLineField(title=_('key-number-label', default="Header"), + description=_("Small text to be displayed above number (according to selected " + "renderer)"), + required=False) + + number = TextLine(title=_("Number"), + description=_("Key number value"), + required=True) + + unit = I18nTextLineField(title=_('key-number-unit', default="Unit"), + description=_("Displayed unit"), + required=False) + + text = I18nTextLineField(title=_("Associated text"), + description=_("The way this text will be rendered depends on presentation template"), + required=False) + + +KEYNUMBER_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible') + + +class IKeyNumberContainer(IOrderedContainer): + """Key numbers container interface""" + + contains(IKeyNumber) + + def append(self, value, notify=True): + """Append given key number to container""" + + def get_visible_items(self): + """Get list of visible key numbers""" + + +class IKeyNumberContainerTarget(Interface): + """Key numbers container target interface""" + + +KEYNUMBER_PARAGRAPH_TYPE = 'KeyNumbers' +KEYNUMBER_PARAGRAPH_NAME = _("Key numbers") +KEYNUMBER_PARAGRAPH_RENDERERS = 'PyAMS.keynumbers.renderers' + + +# +# KeyNumber paragraph +# + +class IKeyNumberParagraph(IKeyNumberContainerTarget, IBaseParagraph): + """Key numbers paragraph interface""" + + renderer = Choice(title=_("Key numbers template"), + description=_("Presentation template used for key numbers"), + vocabulary=KEYNUMBER_PARAGRAPH_RENDERERS, + default='default') diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/keynumber/interfaces/__init__.py --- a/src/pyams_content/component/keynumber/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -# -# Copyright (c) 2008-2018 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces -from pyams_content.component.paragraph.interfaces import IBaseParagraph -from pyams_content.interfaces.container import IOrderedContainer -from zope.annotation.interfaces import IAttributeAnnotatable - -# import packages -from pyams_i18n.schema import I18nTextLineField -from zope.container.constraints import containers, contains -from zope.interface import Interface -from zope.schema import Bool, TextLine, Choice - -from pyams_content import _ - - -KEYNUMBER_CONTAINER_KEY = 'pyams_content.keynumbers' - - -class IKeyNumber(IAttributeAnnotatable): - """Base key number interface""" - - containers('.IKeyNumberContainer') - - visible = Bool(title=_("Visible?"), - description=_("Is this key number visible in front-office?"), - required=True, - default=True) - - label = I18nTextLineField(title=_('key-number-label', default="Header"), - description=_("Small text to be displayed above number (according to selected " - "renderer)"), - required=False) - - number = TextLine(title=_("Number"), - description=_("Key number value"), - required=True) - - unit = I18nTextLineField(title=_('key-number-unit', default="Unit"), - description=_("Displayed unit"), - required=False) - - text = I18nTextLineField(title=_("Associated text"), - description=_("The way this text will be rendered depends on presentation template"), - required=False) - - -KEYNUMBER_HIDDEN_FIELDS = ('__parent__', '__name__', 'visible') - - -class IKeyNumberContainer(IOrderedContainer): - """Key numbers container interface""" - - contains(IKeyNumber) - - def append(self, value, notify=True): - """Append given key number to container""" - - def get_visible_items(self): - """Get list of visible key numbers""" - - -class IKeyNumberContainerTarget(Interface): - """Key numbers container target interface""" - - -KEYNUMBER_PARAGRAPH_TYPE = 'KeyNumbers' -KEYNUMBER_PARAGRAPH_NAME = _("Key numbers") -KEYNUMBER_PARAGRAPH_RENDERERS = 'PyAMS.keynumbers.renderers' - - -# -# KeyNumber paragraph -# - -class IKeyNumberParagraph(IKeyNumberContainerTarget, IBaseParagraph): - """Key numbers paragraph interface""" - - renderer = Choice(title=_("Key numbers template"), - description=_("Presentation template used for key numbers"), - vocabulary=KEYNUMBER_PARAGRAPH_RENDERERS, - default='default') diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/keynumber/portlet/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/keynumber/portlet/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,43 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_portal.interfaces import IPortletSettings + +# import packages +from pyams_i18n.schema import I18nTextLineField, 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""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/keynumber/portlet/interfaces/__init__.py --- a/src/pyams_content/component/keynumber/portlet/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces -from pyams_portal.interfaces import IPortletSettings - -# import packages -from pyams_i18n.schema import I18nTextLineField, 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""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/links/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/links/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,84 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem +from pyams_content.reference.pictograms.interfaces import SELECTED_PICTOGRAM_VOCABULARY +from pyams_sequence.interfaces import IInternalReference + +# import packages +from pyams_i18n.schema import I18nTextLineField, I18nTextField +from pyams_utils.schema import MailAddressField +from zope.interface import Attribute +from zope.schema import Choice, TextLine, URI + +from pyams_content import _ + + +class IBaseLink(IAssociationItem): + """Base link interface""" + + title = I18nTextLineField(title=_("Alternate title"), + description=_("Link title, as shown in front-office"), + required=False) + + description = I18nTextField(title=_("Description"), + description=_("Link description displayed by front-office template"), + required=False) + + pictogram_name = Choice(title=_("Pictogram"), + description=_("Name of the pictogram associated with this link"), + required=False, + vocabulary=SELECTED_PICTOGRAM_VOCABULARY) + + pictogram = Attribute("Selected pictogram object") + + def get_editor_url(self): + """Get URL for use in HTML editor""" + + +class IInternalLink(IBaseLink, IInternalReference): + """Internal link interface""" + + +class IExternalLink(IBaseLink): + """External link interface""" + + url = URI(title=_("Target URL"), + description=_("URL used to access external resource"), + required=True) + + language = Choice(title=_("Language"), + description=_("Language used in this remote resource"), + vocabulary='PyAMS base languages', + required=False) + + +class IMailtoLink(IBaseLink): + """Mailto link interface""" + + address = MailAddressField(title=_("Target address"), + description=_("Target email address"), + required=True) + + address_name = TextLine(title=_("Address name"), + description=_("Address as displayed in address book"), + required=True) + + +class ILinkContainerTarget(IAssociationContainerTarget): + """Links container marker interface""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/links/interfaces/__init__.py --- a/src/pyams_content/component/links/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces -from pyams_content.component.association.interfaces import IAssociationContainerTarget, IAssociationItem -from pyams_content.reference.pictograms.interfaces import SELECTED_PICTOGRAM_VOCABULARY -from pyams_sequence.interfaces import IInternalReference - -# import packages -from pyams_i18n.schema import I18nTextLineField, I18nTextField -from pyams_utils.schema import MailAddressField -from zope.interface import Attribute -from zope.schema import Choice, TextLine, URI - -from pyams_content import _ - - -class IBaseLink(IAssociationItem): - """Base link interface""" - - title = I18nTextLineField(title=_("Alternate title"), - description=_("Link title, as shown in front-office"), - required=False) - - description = I18nTextField(title=_("Description"), - description=_("Link description displayed by front-office template"), - required=False) - - pictogram_name = Choice(title=_("Pictogram"), - description=_("Name of the pictogram associated with this link"), - required=False, - vocabulary=SELECTED_PICTOGRAM_VOCABULARY) - - pictogram = Attribute("Selected pictogram object") - - def get_editor_url(self): - """Get URL for use in HTML editor""" - - -class IInternalLink(IBaseLink, IInternalReference): - """Internal link interface""" - - -class IExternalLink(IBaseLink): - """External link interface""" - - url = URI(title=_("Target URL"), - description=_("URL used to access external resource"), - required=True) - - language = Choice(title=_("Language"), - description=_("Language used in this remote resource"), - vocabulary='PyAMS base languages', - required=False) - - -class IMailtoLink(IBaseLink): - """Mailto link interface""" - - address = MailAddressField(title=_("Target address"), - description=_("Target email address"), - required=True) - - address_name = TextLine(title=_("Address name"), - description=_("Address as displayed in address book"), - required=True) - - -class ILinkContainerTarget(IAssociationContainerTarget): - """Links container marker interface""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/frame.py --- a/src/pyams_content/component/paragraph/frame.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/frame.py Tue Nov 13 14:05:02 2018 +0100 @@ -16,7 +16,7 @@ from zope.schema.fieldproperty import FieldProperty from pyams_content.component.extfile.interfaces import IExtFileContainerTarget -from pyams_content.component.illustration.interfaces import IBasicIllustrationTarget +from pyams_content.component.illustration.interfaces import IIllustrationTarget from pyams_content.component.links.interfaces import ILinkContainerTarget from pyams_content.component.paragraph import BaseParagraph, BaseParagraphContentChecker, BaseParagraphFactory from pyams_content.component.paragraph.interfaces import IParagraphFactory @@ -36,7 +36,7 @@ # Frame paragraph # -@implementer(IFrameParagraph, IBasicIllustrationTarget, IExtFileContainerTarget, ILinkContainerTarget) +@implementer(IFrameParagraph, IIllustrationTarget, IExtFileContainerTarget, ILinkContainerTarget) @factory_config(provided=IFrameParagraph) class FrameParagraph(BaseParagraph): """Framed text paragraph""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/portlet/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/paragraph/portlet/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,68 @@ +# +# Copyright (c) 2008-2018 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import packages +from zope.schema import Bool, Choice, List, Set + +from pyams_content import _ +# import interfaces +from pyams_content.component.paragraph.interfaces import PARAGRAPH_FACTORIES_VOCABULARY +from pyams_portal.interfaces import IPortletSettings + + +class IParagraphContainerPortletSettings(IPortletSettings): + """Paragraphs container portlet settings interface""" + + paragraphs = List(title=_("Selected paragraphs"), + description=_("List of selected paragraphs; an empty selection means that " + "all paragraphs will be selectable by following filters; otherwise, " + "this selection will have priority"), + value_type=Choice(vocabulary='PyAMS content paragraphs'), + required=False) + + factories = Set(title=_("Paragraph types"), + description=_("Select list of paragraph types you want to include; an empty " + "selection means that all paragraphs types will be selected"), + required=False, + value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY)) + + anchors_only = Bool(title=_("Anchors only?"), + description=_("If 'yes', only paragraphs set as 'anchors' will be selected"), + required=True, + default=False) + + +class IParagraphNavigationPortletSettings(IPortletSettings): + """Paragraphs container navigation settings interface""" + + paragraphs = List(title=_("Selected paragraphs"), + description=_("List of paragraphs selected for navigation; an empty selection means that " + "all paragraphs will be selectable by following filters; otherwise, " + "this selection will have priority"), + value_type=Choice(vocabulary='PyAMS content paragraphs'), + required=False) + + factories = Set(title=_("Paragraph types"), + description=_("Select list of paragraph types you want to use for navigation; an empty " + "selection means that all paragraphs types will be selected"), + required=False, + value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY)) + + anchors_only = Bool(title=_("Anchors only?"), + description=_("If 'no', all paragraphs will be used as navigation anchors"), + required=True, + default=True) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/portlet/interfaces/__init__.py --- a/src/pyams_content/component/paragraph/portlet/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -# -# Copyright (c) 2008-2018 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import packages -from zope.schema import Bool, Choice, List, Set - -from pyams_content import _ -# import interfaces -from pyams_content.component.paragraph.interfaces import PARAGRAPH_FACTORIES_VOCABULARY -from pyams_portal.interfaces import IPortletSettings - - -class IParagraphContainerPortletSettings(IPortletSettings): - """Paragraphs container portlet settings interface""" - - paragraphs = List(title=_("Selected paragraphs"), - description=_("List of selected paragraphs; an empty selection means that " - "all paragraphs will be selectable by following filters; otherwise, " - "this selection will have priority"), - value_type=Choice(vocabulary='PyAMS content paragraphs'), - required=False) - - factories = Set(title=_("Paragraph types"), - description=_("Select list of paragraph types you want to include; an empty " - "selection means that all paragraphs types will be selected"), - required=False, - value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY)) - - anchors_only = Bool(title=_("Anchors only?"), - description=_("If 'yes', only paragraphs set as 'anchors' will be selected"), - required=True, - default=False) - - -class IParagraphNavigationPortletSettings(IPortletSettings): - """Paragraphs container navigation settings interface""" - - paragraphs = List(title=_("Selected paragraphs"), - description=_("List of paragraphs selected for navigation; an empty selection means that " - "all paragraphs will be selectable by following filters; otherwise, " - "this selection will have priority"), - value_type=Choice(vocabulary='PyAMS content paragraphs'), - required=False) - - factories = Set(title=_("Paragraph types"), - description=_("Select list of paragraph types you want to use for navigation; an empty " - "selection means that all paragraphs types will be selected"), - required=False, - value_type=Choice(vocabulary=PARAGRAPH_FACTORIES_VOCABULARY)) - - anchors_only = Bool(title=_("Anchors only?"), - description=_("If 'no', all paragraphs will be used as navigation anchors"), - required=True, - default=True) diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/audio.py --- a/src/pyams_content/component/paragraph/zmi/audio.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/audio.py Tue Nov 13 14:05:02 2018 +0100 @@ -48,7 +48,7 @@ """Audio paragraph add menu""" label = _("Audio paragraph...") - label_css_class = 'fa fa-fw fa-volume-up' + label_css_class = 'fa fa-fw ' + AudioParagraph.icon_class url = 'add-audio-paragraph.html' paragraph_type = AUDIO_PARAGRAPH_TYPE @@ -62,7 +62,7 @@ legend = _("Add new audio paragraph") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-volume-up' + icon_css_class = 'fa fa-fw ' + AudioParagraph.icon_class fields = field.Fields(IAudioParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -84,7 +84,7 @@ legend = _("Edit audio properties") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-volume-up' + icon_css_class = 'fa fa-fw ' + AudioParagraph.icon_class fields = field.Fields(IAudioParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/contact.py --- a/src/pyams_content/component/paragraph/zmi/contact.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/contact.py Tue Nov 13 14:05:02 2018 +0100 @@ -46,7 +46,7 @@ """Contact paragraph add menu""" label = _("Contact card...") - label_css_class = 'fa fa-fw fa-id-card-o' + label_css_class = 'fa fa-fw ' + ContactParagraph.icon_class url = 'add-contact-paragraph.html' paragraph_type = CONTACT_PARAGRAPH_TYPE @@ -60,7 +60,7 @@ legend = _("Add new contact card") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-id-card-o' + icon_css_class = 'fa fa-fw ' + ContactParagraph.icon_class fields = field.Fields(IContactParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -82,7 +82,7 @@ prefix = 'contact_properties.' legend = _("Edit contact card properties") - icon_css_class = 'fa fa-fw fa-id-card-o' + icon_css_class = 'fa fa-fw ' + ContactParagraph.icon_class fields = field.Fields(IContactParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/container.py --- a/src/pyams_content/component/paragraph/zmi/container.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/container.py Tue Nov 13 14:05:02 2018 +0100 @@ -32,7 +32,7 @@ IParagraphInnerEditor, IParagraphTitleToolbar, IParagraphTitleValue from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION from pyams_content.shared.common.zmi import WfModifiedContentColumnMixin -from pyams_content.skin import pyams_content +from pyams_content.zmi import pyams_content from pyams_form.interfaces.form import IFormSecurityContext, IInnerSubForm from pyams_form.security import ProtectedFormObjectMixin from pyams_i18n.interfaces import II18n diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/frame.py --- a/src/pyams_content/component/paragraph/zmi/frame.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/frame.py Tue Nov 13 14:05:02 2018 +0100 @@ -94,7 +94,7 @@ """Framed text paragraph add menu""" label = _("Framed text...") - label_css_class = 'fa fa-fw fa-window-maximize' + label_css_class = 'fa fa-fw ' + FrameParagraph.icon_class url = 'add-frame-paragraph.html' paragraph_type = FRAME_PARAGRAPH_TYPE @@ -109,7 +109,7 @@ legend = _("Add new framed text paragraph") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-window-maximize' + icon_css_class = 'fa fa-fw ' + FrameParagraph.icon_class label_css_class = 'control-label col-md-2' input_css_class = 'col-md-10' @@ -135,7 +135,7 @@ legend = _("Edit framed text paragraph properties") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-window-maximize' + icon_css_class = 'fa fa-fw ' + FrameParagraph.icon_class label_css_class = 'control-label col-md-2' input_css_class = 'col-md-10' diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/html.py --- a/src/pyams_content/component/paragraph/zmi/html.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/html.py Tue Nov 13 14:05:02 2018 +0100 @@ -72,7 +72,7 @@ """Raw HTML paragraph add menu""" label = _("Raw HTML...") - label_css_class = 'fa fa-fw fa-code' + label_css_class = 'fa fa-fw ' + RawParagraph.icon_class url = 'add-raw-paragraph.html' paragraph_type = RAW_PARAGRAPH_TYPE @@ -86,7 +86,7 @@ legend = _("Add new raw HTML paragraph") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-code' + icon_css_class = 'fa fa-fw ' + RawParagraph.icon_class label_css_class = 'control-label col-md-2' input_css_class = 'col-md-10' @@ -115,7 +115,7 @@ prefix = 'raw_properties.' legend = _("Edit raw HTML paragraph properties") - icon_css_class = 'fa fa-fw fa-code' + icon_css_class = 'fa fa-fw ' + RawParagraph.icon_class fields = field.Fields(IRawParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget @@ -155,7 +155,7 @@ """Rich text paragraph add menu""" label = _("Rich text...") - label_css_class = 'fa fa-fw fa-font' + label_css_class = 'fa fa-fw ' + HTMLParagraph.icon_class url = 'add-html-paragraph.html' paragraph_type = HTML_PARAGRAPH_TYPE @@ -169,7 +169,7 @@ legend = _("Add new rich text paragraph") dialog_class = 'modal-max' - icon_css_class = 'fa fa-fw fa-font' + icon_css_class = 'fa fa-fw ' + HTMLParagraph.icon_class label_css_class = 'control-label col-md-2' input_css_class = 'col-md-10' @@ -206,7 +206,7 @@ legend = _("Edit rich text paragraph properties") dialog_class = 'modal-max' - icon_css_class = 'fa fa-fw fa-font' + icon_css_class = 'fa fa-fw ' + HTMLParagraph.icon_class label_css_class = 'control-label col-md-2' input_css_class = 'col-md-10' diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/keypoint.py --- a/src/pyams_content/component/paragraph/zmi/keypoint.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/keypoint.py Tue Nov 13 14:05:02 2018 +0100 @@ -44,7 +44,7 @@ """Key points paragraph add menu""" label = _("Key points...") - label_css_class = 'fa fa-fw fa-list-ol' + label_css_class = 'fa fa-fw ' + KeypointsParagraph.icon_class url = 'add-keypoints-paragraph.html' paragraph_type = KEYPOINTS_PARAGRAPH_TYPE @@ -57,7 +57,7 @@ """Key points paragraph add form""" legend = _("Add new key points paragraph") - icon_css_class = 'fa fa-fw fa-list-ol' + icon_css_class = 'fa fa-fw ' + KeypointsParagraph.icon_class fields = field.Fields(IKeypointsParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -84,7 +84,7 @@ prefix = 'keypoints_properties.' legend = _("Edit key points paragraph properties") - icon_css_class = 'fa fa-fw fa-list-ol' + icon_css_class = 'fa fa-fw ' + KeypointsParagraph.icon_class fields = field.Fields(IKeypointsParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/map.py --- a/src/pyams_content/component/paragraph/zmi/map.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/map.py Tue Nov 13 14:05:02 2018 +0100 @@ -48,7 +48,7 @@ """Map paragraph add menu""" label = _("Location map...") - label_css_class = 'fa fa-fw fa-map-marker' + label_css_class = 'fa fa-fw ' + MapParagraph.icon_class url = 'add-map-paragraph.html' paragraph_type = MAP_PARAGRAPH_TYPE @@ -62,7 +62,7 @@ legend = _("Add new location map") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-map-marker' + icon_css_class = 'fa fa-fw ' + MapParagraph.icon_class fields = field.Fields(IMapParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -84,7 +84,7 @@ prefix = 'map_properties.' legend = _("Edit location map properties") - icon_css_class = 'fa fa-fw fa-map-marker' + icon_css_class = 'fa fa-fw ' + MapParagraph.icon_class fields = field.Fields(IMapParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/milestone.py --- a/src/pyams_content/component/paragraph/zmi/milestone.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/milestone.py Tue Nov 13 14:05:02 2018 +0100 @@ -72,7 +72,7 @@ """Milestone paragraph add menu""" label = _("Milestones...") - label_css_class = 'fa fa-fw fa-arrows-h' + label_css_class = 'fa fa-fw ' + MilestoneParagraph.icon_class url = 'add-milestone-paragraph.html' paragraph_type = MILESTONE_PARAGRAPH_TYPE @@ -85,7 +85,7 @@ """Milestone paragraph add form""" legend = _("Add new milestone paragraph") - icon_css_class = 'fa fa-fw fa-arrows-h' + icon_css_class = 'fa fa-fw ' + MilestoneParagraph.icon_class fields = field.Fields(IMilestoneParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -112,7 +112,7 @@ return II18n(content).query_attribute('title', request=self.request) legend = _("Edit milestone paragraph properties") - icon_css_class = 'fa fa-fw fa-arrows-h' + icon_css_class = 'fa fa-fw ' + MilestoneParagraph.icon_class fields = field.Fields(IMilestoneParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/pictogram.py --- a/src/pyams_content/component/paragraph/zmi/pictogram.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/pictogram.py Tue Nov 13 14:05:02 2018 +0100 @@ -77,7 +77,7 @@ """Pictogram paragraph add menu""" label = _("Pictograms...") - label_css_class = 'fa fa-fw fa-linode' + label_css_class = 'fa fa-fw ' + PictogramParagraph.icon_class url = 'add-pictogram-paragraph.html' paragraph_type = PICTOGRAM_PARAGRAPH_TYPE @@ -90,7 +90,7 @@ """Pictogram paragraph add form""" legend = _("Add new pictogram paragraph") - icon_css_class = 'fa fa-fw fa-linode' + icon_css_class = 'fa fa-fw ' + PictogramParagraph.icon_class fields = field.Fields(IPictogramParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -117,7 +117,7 @@ return II18n(content).query_attribute('title', request=self.request) legend = _("Edit pictogram paragraph properties") - icon_css_class = 'fa fa-fw fa-linode' + icon_css_class = 'fa fa-fw ' + PictogramParagraph.icon_class fields = field.Fields(IPictogramParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/preview.py --- a/src/pyams_content/component/paragraph/zmi/preview.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces -from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer, \ - IParagraphRenderer -from pyams_content.features.renderer.interfaces import ISharedContentRenderer -from pyams_skin.layer import IPyAMSLayer - -# import packages -from pyams_content.features.renderer.skin import BaseContentRenderer -from pyams_utils.adapter import adapter_config - - -@adapter_config(name='paragraphs-render', context=(IParagraphContainerTarget, IPyAMSLayer), - provides=ISharedContentRenderer) -class ParagraphsContainerRenderer(BaseContentRenderer): - """Paragraphs container renderer""" - - weight = 10 - - def __init__(self, context, request): - super(ParagraphsContainerRenderer, self).__init__(context, request) - paragraphs = [para for para in IParagraphContainer(self.context).values() - if para.visible] - registry = self.request.registry - self.renderers = [registry.queryMultiAdapter((paragraph, self.request), IParagraphRenderer) - for paragraph in paragraphs] - - def update(self): - super(ParagraphsContainerRenderer, self).update() - for renderer in self.renderers: - if renderer is not None: - renderer.language = self.language - renderer.update() - - def render(self): - result = '' - for renderer in self.renderers: - if renderer is not None: - result += renderer.render() - return result diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/verbatim.py --- a/src/pyams_content/component/paragraph/zmi/verbatim.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/verbatim.py Tue Nov 13 14:05:02 2018 +0100 @@ -9,8 +9,6 @@ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # -from pyams_content.component.paragraph import IBaseParagraph - __docformat__ = 'restructuredtext' @@ -19,6 +17,7 @@ from zope.interface import implementer from pyams_content.component.association.zmi.interfaces import IAssociationsParentForm +from pyams_content.component.paragraph import IBaseParagraph from pyams_content.component.paragraph.interfaces import IParagraphContainer, IParagraphContainerTarget, \ PARAGRAPH_HIDDEN_FIELDS from pyams_content.component.paragraph.interfaces.verbatim import IVerbatimParagraph, VERBATIM_PARAGRAPH_TYPE @@ -33,7 +32,6 @@ from pyams_form.interfaces.form import IInnerForm from pyams_i18n.interfaces import II18n from pyams_pagelet.pagelet import pagelet_config -from pyams_skin.event import get_json_widget_refresh_event from pyams_skin.interfaces.viewlet import IToolbarAddingMenu from pyams_skin.layer import IPyAMSLayer from pyams_utils.adapter import adapter_config @@ -55,7 +53,7 @@ """Verbatim paragraph add menu""" label = _("Verbatim...") - label_css_class = 'fa fa-fw fa-quote-right' + label_css_class = 'fa fa-fw ' + VerbatimParagraph.icon_class url = 'add-verbatim-paragraph.html' paragraph_type = VERBATIM_PARAGRAPH_TYPE @@ -68,7 +66,7 @@ """Verbatim paragraph add form""" legend = _("Add new verbatim paragraph") - icon_css_class = 'fa fa-fw fa-quote-right' + icon_css_class = 'fa fa-fw ' + VerbatimParagraph.icon_class fields = field.Fields(IVerbatimParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -107,13 +105,18 @@ prefix = 'verbatim_properties.' legend = _("Edit verbatim paragraph properties") - icon_css_class = 'fa fa-fw fa-quote-right' + icon_css_class = 'fa fa-fw ' + VerbatimParagraph.icon_class fields = field.Fields(IVerbatimParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget edit_permission = MANAGE_CONTENT_PERMISSION + def updateWidgets(self, prefix=None): + super(VerbatimParagraphPropertiesEditForm, self).updateWidgets(prefix) + if 'quote' in self.widgets: + self.widgets['quote'].widget_css_class = 'input height-200' + def get_ajax_output(self, changes): output = super(self.__class__, self).get_ajax_output(changes) if 'quote' in changes.get(IVerbatimParagraph, ()): diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/paragraph/zmi/video.py --- a/src/pyams_content/component/paragraph/zmi/video.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/paragraph/zmi/video.py Tue Nov 13 14:05:02 2018 +0100 @@ -48,7 +48,7 @@ """Video paragraph add menu""" label = _("Video paragraph...") - label_css_class = 'fa fa-fw fa-film' + label_css_class = 'fa fa-fw ' + VideoParagraph.icon_class url = 'add-video-paragraph.html' paragraph_type = VIDEO_PARAGRAPH_TYPE @@ -62,7 +62,7 @@ legend = _("Add new video paragraph") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-film' + icon_css_class = 'fa fa-fw ' + VideoParagraph.icon_class fields = field.Fields(IVideoParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) edit_permission = MANAGE_CONTENT_PERMISSION @@ -85,7 +85,7 @@ legend = _("Edit video properties") dialog_class = 'modal-large' - icon_css_class = 'fa fa-fw fa-film' + icon_css_class = 'fa fa-fw ' + VideoParagraph.icon_class fields = field.Fields(IVideoParagraph).omit(*PARAGRAPH_HIDDEN_FIELDS) fields['renderer'].widgetFactory = RendererFieldWidget diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/theme/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/theme/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,165 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_thesaurus.interfaces.thesaurus import IThesaurusContextManager, IThesaurusContextManagerTarget + +# import packages +from pyams_sequence.schema import InternalReferenceField +from pyams_thesaurus.schema import ThesaurusTermsListField +from zope.interface import Interface, invariant, Invalid +from zope.schema import Bool + +from pyams_content import _ + + +# +# Tags management +# + +TAGS_MANAGER_KEY = 'pyams_content.tags.manager' +TAGS_INFO_KEY = 'pyams_content.tags.info' + + +class ITagsManager(IThesaurusContextManager): + """Tags manager interface""" + + enable_tags_search = Bool(title=_("Enable search by tag?"), + description=_("If 'yes', displayed tags will lead to a search engine " + "displaying contents matching given tag"), + required=True, + default=False) + + tags_search_target = InternalReferenceField(title=_("Tags search target"), + description=_("Site or folder where tags search is displayed"), + required=False) + + @invariant + def check_search_target(self): + if self.enable_tags_search and not self.tags_search_target: + raise Invalid(_("You must specify search target when activating search by tags!")) + + +class ITagsManagerTarget(IThesaurusContextManagerTarget): + """Marker interface for tags manager""" + + +class ITagsInfo(Interface): + """Tags information interface""" + + tags = ThesaurusTermsListField(title=_("Tags"), + required=False) + + +class ITagsTarget(Interface): + """Tags target interface""" + + +PORTLET_SETTINGS_TAGS_KEY = 'pyams_content.portlet.tags.settings' + + +class IPortletTagsSettings(Interface): + """Interface for portlet settings managing tags""" + + tags = ThesaurusTermsListField(title=_("Tags"), + required=False) + + +class IPortletTagsSettingsTarget(Interface): + """Marker interface for portlet settings managing tags""" + + +# +# Themes management +# + +THEMES_MANAGER_KEY = 'pyams_content.themes.manager' +THEMES_INFO_KEY = 'pyams_content.themes.info' + + +class IThemesManager(IThesaurusContextManager): + """Themes manager interface""" + + +class IThemesManagerTarget(IThesaurusContextManagerTarget): + """Marker interface for tools managing themes""" + + +class IThemesInfo(Interface): + """Themes information interface""" + + themes = ThesaurusTermsListField(title=_("Themes"), + required=False) + + +class IThemesTarget(Interface): + """Themes target interface""" + + +PORTLET_SETTINGS_THEMES_KEY = 'pyams_content.portlet.themes.settings' + + +class IPortletThemesSettings(Interface): + """Interface for portlet settings managing themes""" + + themes = ThesaurusTermsListField(title=_("Themes"), + required=False) + + +class IPortletThemesSettingsTarget(Interface): + """Marker interface for portlet settings managing themes""" + + +# +# Collections management +# + +COLLECTIONS_MANAGER_KEY = 'pyams_content.collections.manager' +COLLECTIONS_INFO_KEY = 'pyams_content.collections.info' + + +class ICollectionsManager(IThesaurusContextManager): + """Collections manager interface""" + + +class ICollectionsManagerTarget(IThesaurusContextManagerTarget): + """Marker interface for tools managing collections""" + + +class ICollectionsInfo(Interface): + """Collections information interface""" + + collections = ThesaurusTermsListField(title=_("Collections"), + required=False) + + +class ICollectionsTarget(Interface): + """Collections target interface""" + + +PORTLET_SETTINGS_COLLECTIONS_KEY = 'pyams_content.portlet.collections.settings' + + +class IPortletCollectionsSettings(Interface): + """Interface for portlet settings managing collections""" + + collections = ThesaurusTermsListField(title=_("Collections"), + required=False) + + +class IPortletCollectionsSettingsTarget(Interface): + """Marker interface for portlet settings managing collections""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/theme/interfaces/__init__.py --- a/src/pyams_content/component/theme/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces -from pyams_thesaurus.interfaces.thesaurus import IThesaurusContextManager, IThesaurusContextManagerTarget - -# import packages -from pyams_sequence.schema import InternalReferenceField -from pyams_thesaurus.schema import ThesaurusTermsListField -from zope.interface import Interface, invariant, Invalid -from zope.schema import Bool - -from pyams_content import _ - - -# -# Tags management -# - -TAGS_MANAGER_KEY = 'pyams_content.tags.manager' -TAGS_INFO_KEY = 'pyams_content.tags.info' - - -class ITagsManager(IThesaurusContextManager): - """Tags manager interface""" - - enable_tags_search = Bool(title=_("Enable search by tag?"), - description=_("If 'yes', displayed tags will lead to a search engine " - "displaying contents matching given tag"), - required=True, - default=False) - - tags_search_target = InternalReferenceField(title=_("Tags search target"), - description=_("Site or folder where tags search is displayed"), - required=False) - - @invariant - def check_search_target(self): - if self.enable_tags_search and not self.tags_search_target: - raise Invalid(_("You must specify search target when activating search by tags!")) - - -class ITagsManagerTarget(IThesaurusContextManagerTarget): - """Marker interface for tags manager""" - - -class ITagsInfo(Interface): - """Tags information interface""" - - tags = ThesaurusTermsListField(title=_("Tags"), - required=False) - - -class ITagsTarget(Interface): - """Tags target interface""" - - -PORTLET_SETTINGS_TAGS_KEY = 'pyams_content.portlet.tags.settings' - - -class IPortletTagsSettings(Interface): - """Interface for portlet settings managing tags""" - - tags = ThesaurusTermsListField(title=_("Tags"), - required=False) - - -class IPortletTagsSettingsTarget(Interface): - """Marker interface for portlet settings managing tags""" - - -# -# Themes management -# - -THEMES_MANAGER_KEY = 'pyams_content.themes.manager' -THEMES_INFO_KEY = 'pyams_content.themes.info' - - -class IThemesManager(IThesaurusContextManager): - """Themes manager interface""" - - -class IThemesManagerTarget(IThesaurusContextManagerTarget): - """Marker interface for tools managing themes""" - - -class IThemesInfo(Interface): - """Themes information interface""" - - themes = ThesaurusTermsListField(title=_("Themes"), - required=False) - - -class IThemesTarget(Interface): - """Themes target interface""" - - -PORTLET_SETTINGS_THEMES_KEY = 'pyams_content.portlet.themes.settings' - - -class IPortletThemesSettings(Interface): - """Interface for portlet settings managing themes""" - - themes = ThesaurusTermsListField(title=_("Themes"), - required=False) - - -class IPortletThemesSettingsTarget(Interface): - """Marker interface for portlet settings managing themes""" - - -# -# Collections management -# - -COLLECTIONS_MANAGER_KEY = 'pyams_content.collections.manager' -COLLECTIONS_INFO_KEY = 'pyams_content.collections.info' - - -class ICollectionsManager(IThesaurusContextManager): - """Collections manager interface""" - - -class ICollectionsManagerTarget(IThesaurusContextManagerTarget): - """Marker interface for tools managing collections""" - - -class ICollectionsInfo(Interface): - """Collections information interface""" - - collections = ThesaurusTermsListField(title=_("Collections"), - required=False) - - -class ICollectionsTarget(Interface): - """Collections target interface""" - - -PORTLET_SETTINGS_COLLECTIONS_KEY = 'pyams_content.portlet.collections.settings' - - -class IPortletCollectionsSettings(Interface): - """Interface for portlet settings managing collections""" - - collections = ThesaurusTermsListField(title=_("Collections"), - required=False) - - -class IPortletCollectionsSettingsTarget(Interface): - """Marker interface for portlet settings managing collections""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/theme/zmi/manager.py --- a/src/pyams_content/component/theme/zmi/manager.py Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/theme/zmi/manager.py Tue Nov 13 14:05:02 2018 +0100 @@ -27,7 +27,7 @@ from pyams_zmi.layer import IAdminLayer # import packages -from pyams_content.skin import pyams_content +from pyams_content.zmi import pyams_content from pyams_form.form import ajax_config from pyams_pagelet.pagelet import pagelet_config from pyams_skin.viewlet.menu import MenuItem, MenuDivider diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/video/interfaces.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/video/interfaces.py Tue Nov 13 14:05:02 2018 +0100 @@ -0,0 +1,79 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + +from zope.annotation import IAttributeAnnotatable +from zope.contentprovider.interfaces import IContentProvider +from zope.interface import Interface, Attribute +from zope.schema import Choice, TextLine + +from pyams_content import _ +from pyams_content.component.paragraph.interfaces import IBaseParagraph +from pyams_i18n.schema import I18nTextField, I18nTextLineField + + +class IExternalVideoSettings(Interface): + """External video settings""" + + video_id = Attribute("Video ID") + + +class IExternalVideoProvider(Interface): + """External video provider""" + + label = Attribute("Video provider label") + weight = Attribute("Video provider weight (used for ordering)") + settings_interface = Attribute("Video provider settings interface") + + +class IExternalVideo(IAttributeAnnotatable): + """Base interface for external video integration""" + + author = TextLine(title=_("Author"), + description=_("Name of document's author"), + required=True) + + description = I18nTextField(title=_("Associated text"), + description=_("Video description displayed by front-office template"), + required=False) + + provider_name = Choice(title=_("Video provider"), + description=_("Name of external platform providing selected video"), + required=False, + vocabulary="PyAMS video providers") + + def get_provider(self): + """Get external video provider utility""" + + settings = Attribute("Video settings") + + +EXTERNAL_VIDEO_PARAGRAPH_TYPE = 'External video' +EXTERNAL_VIDEO_PARAGRAPH_NAME = _("External video") +EXTERNAL_VIDEO_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.video.renderers' + + +class IExternalVideoParagraph(IExternalVideo, IBaseParagraph): + """External video paragraph""" + + title = I18nTextLineField(title=_("Legend"), + required=False) + + renderer = Choice(title=_("Video template"), + description=_("Presentation template used for this video"), + vocabulary=EXTERNAL_VIDEO_PARAGRAPH_RENDERERS, + default='default') + + +class IExternalVideoRenderer(IContentProvider): + """External video renderer""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/video/interfaces/__init__.py --- a/src/pyams_content/component/video/interfaces/__init__.py Fri Oct 12 14:33:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -# -# Copyright (c) 2008-2015 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - -from zope.annotation import IAttributeAnnotatable -from zope.contentprovider.interfaces import IContentProvider -from zope.interface import Interface, Attribute -from zope.schema import Choice, TextLine - -from pyams_content import _ -from pyams_content.component.paragraph.interfaces import IBaseParagraph -from pyams_i18n.schema import I18nTextField, I18nTextLineField - - -class IExternalVideoSettings(Interface): - """External video settings""" - - video_id = Attribute("Video ID") - - -class IExternalVideoProvider(Interface): - """External video provider""" - - label = Attribute("Video provider label") - weight = Attribute("Video provider weight (used for ordering)") - settings_interface = Attribute("Video provider settings interface") - - -class IExternalVideo(IAttributeAnnotatable): - """Base interface for external video integration""" - - author = TextLine(title=_("Author"), - description=_("Name of document's author"), - required=True) - - description = I18nTextField(title=_("Associated text"), - description=_("Video description displayed by front-office template"), - required=False) - - provider_name = Choice(title=_("Video provider"), - description=_("Name of external platform providing selected video"), - required=False, - vocabulary="PyAMS video providers") - - def get_provider(self): - """Get external video provider utility""" - - settings = Attribute("Video settings") - - -EXTERNAL_VIDEO_PARAGRAPH_TYPE = 'External video' -EXTERNAL_VIDEO_PARAGRAPH_NAME = _("External video") -EXTERNAL_VIDEO_PARAGRAPH_RENDERERS = 'PyAMS.paragraph.video.renderers' - - -class IExternalVideoParagraph(IExternalVideo, IBaseParagraph): - """External video paragraph""" - - title = I18nTextLineField(title=_("Legend"), - required=False) - - renderer = Choice(title=_("Video template"), - description=_("Presentation template used for this video"), - vocabulary=EXTERNAL_VIDEO_PARAGRAPH_RENDERERS, - default='default') - - -class IExternalVideoRenderer(IContentProvider): - """External video renderer""" diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/video/provider/zmi/templates/custom-render.pt --- a/src/pyams_content/component/video/provider/zmi/templates/custom-render.pt Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/video/provider/zmi/templates/custom-render.pt Tue Nov 13 14:05:02 2018 +0100 @@ -1,3 +1,3 @@ -
+
Integration code
diff -r a5e56749ca3d -r 3d259e1718ef src/pyams_content/component/video/provider/zmi/templates/dailymotion-render.pt --- a/src/pyams_content/component/video/provider/zmi/templates/dailymotion-render.pt Fri Oct 12 14:33:03 2018 +0200 +++ b/src/pyams_content/component/video/provider/zmi/templates/dailymotion-render.pt Tue Nov 13 14:05:02 2018 +0100 @@ -1,4 +1,4 @@ -
+