# HG changeset patch # User Thierry Florac # Date 1468232782 -7200 # Node ID 4acef7070de733bd63453379b0e0395a9d5e0e15 # Parent d9400e3ca85d5e0248e2d084c910b29d0c4daf20 Added mailto: links diff -r d9400e3ca85d -r 4acef7070de7 src/pyams_content/component/links/__init__.py --- a/src/pyams_content/component/links/__init__.py Fri Jul 08 15:39:08 2016 +0200 +++ b/src/pyams_content/component/links/__init__.py Mon Jul 11 12:26:22 2016 +0200 @@ -9,6 +9,8 @@ # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # +from pyams_i18n.interfaces import II18n +from pyams_utils.request import check_request __docformat__ = 'restructuredtext' @@ -17,7 +19,7 @@ # import interfaces from hypatia.interfaces import ICatalog -from pyams_content.component.links.interfaces import IBaseLink, IInternalLink, IExternalLink +from pyams_content.component.links.interfaces import IBaseLink, IInternalLink, IExternalLink, IMailtoLink from pyams_content.shared.common.interfaces import IWfSharedContent from pyams_form.interfaces.form import IFormContextPermissionChecker from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectModifiedEvent, IObjectRemovedEvent @@ -117,7 +119,7 @@ @implementer(IExternalLink) class ExternalLink(BaseLink): - """external link persistent class""" + """External link persistent class""" url = FieldProperty(IExternalLink['url']) language = FieldProperty(IExternalLink['language']) @@ -127,3 +129,20 @@ def get_url(self, request, view_name=None): return self.url + + +@implementer(IMailtoLink) +class MailtoLink(BaseLink): + """Mailto link persistent class""" + + address = FieldProperty(IMailtoLink['address']) + + def get_editor_url(self): + request = check_request() + return 'mailto:{0} <{1}>'.format(II18n(self).query_attribute('title', request=request), + self.address) + + def get_url(self, request, view_name=None): + request = check_request() + return 'mailto:{0} <{1}>'.format(II18n(self).query_attribute('title', request=request), + self.address) diff -r d9400e3ca85d -r 4acef7070de7 src/pyams_content/component/links/interfaces/__init__.py --- a/src/pyams_content/component/links/interfaces/__init__.py Fri Jul 08 15:39:08 2016 +0200 +++ b/src/pyams_content/component/links/interfaces/__init__.py Mon Jul 11 12:26:22 2016 +0200 @@ -14,6 +14,7 @@ # import standard library +import re # import interfaces from zope.annotation.interfaces import IAttributeAnnotatable @@ -24,7 +25,7 @@ from pyams_sequence.schema import InternalReference from pyams_utils.schema import PersistentList from zope.container.constraints import containers, contains -from zope.interface import Interface, Attribute +from zope.interface import Interface from zope.schema import Choice, TextLine from pyams_content import _ @@ -80,6 +81,18 @@ required=False) +EMAIL_REGEX = re.compile("[^@]+@[^@]+\.[^@]+") + + +class IMailtoLink(IBaseLink): + """Mailto link interface""" + + address = TextLine(title=_("Target address"), + description=_("Target email address"), + constraint=EMAIL_REGEX.match, + required=True) + + class ILinkContainer(IContainer): """Links container""" diff -r d9400e3ca85d -r 4acef7070de7 src/pyams_content/component/links/zmi/__init__.py --- a/src/pyams_content/component/links/zmi/__init__.py Fri Jul 08 15:39:08 2016 +0200 +++ b/src/pyams_content/component/links/zmi/__init__.py Mon Jul 11 12:26:22 2016 +0200 @@ -17,7 +17,7 @@ # import interfaces from pyams_content.component.links.interfaces import ILinkContainerTarget, IInternalLink, ILinkContainer, IBaseLink, \ - IExternalLink + IExternalLink, IMailtoLink from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION from pyams_i18n.interfaces import II18n from pyams_skin.interfaces.viewlet import IToolbarAddingMenu @@ -25,7 +25,7 @@ from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION # import packages -from pyams_content.component.links import InternalLink, ExternalLink +from pyams_content.component.links import InternalLink, ExternalLink, MailtoLink from pyams_content.component.links.zmi.container import LinkContainerView from pyams_form.form import AJAXAddForm, AJAXEditForm from pyams_form.security import ProtectedFormObjectMixin @@ -248,3 +248,109 @@ 'location': '#links.html'} else: return super(ExternalLinkPropertiesAJAXEditForm, self).get_ajax_output(changes) + + +# +# Mailto links views +# + + +@viewlet_config(name='add-mailto-link.menu', context=ILinkContainerTarget, view=LinkContainerView, + layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=52) +class MailtoLinkAddMenu(ProtectedFormObjectMixin, ToolbarMenuItem): + """Mailto link add menu""" + + label = _("Add mailto link") + label_css_class = 'fa fa-fw fa-envelope-o' + + url = 'add-mailto-link.html' + modal_target = True + + +@pagelet_config(name='add-mailto-link.html', context=ILinkContainerTarget, layer=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION) +class MailtoLinkAddForm(AdminDialogAddForm): + """Mailto link add form""" + + legend = _("Add new mailto link") + icon_css_class = 'fa fa-fw fa-envelope-o' + + fields = field.Fields(IMailtoLink).omit('__parent__', '__name__') + + @property + def ajax_handler(self): + origin = self.request.params.get('origin') + if origin == 'link': + return 'add-mailto-link-link.json' + else: + return 'add-mailto-link.json' + + edit_permission = MANAGE_CONTENT_PERMISSION + + def updateWidgets(self, prefix=None): + super(MailtoLinkAddForm, self).updateWidgets(prefix) + self.widgets['description'].label_css_class = 'textarea' + + def create(self, data): + return MailtoLink() + + def add(self, object): + ILinkContainer(self.context)['none'] = object + + +@view_config(name='add-mailto-link.json', context=ILinkContainerTarget, request_type=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True) +class MailtoLinkAJAXAddForm(AJAXAddForm, MailtoLinkAddForm): + """Mailto link add form, JSON renderer""" + + def get_ajax_output(self, changes): + return {'status': 'reload', + 'location': '#links.html'} + + +@view_config(name='add-mailto-link-link.json', context=ILinkContainerTarget, request_type=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True) +class MailtoLinkLinkAJAXAddForm(AJAXAddForm, MailtoLinkAddForm): + """Mailto link link add form, JSON renderer""" + + def get_ajax_output(self, changes): + target = get_parent(self.context, ILinkContainerTarget) + container = ILinkContainer(target) + links = [{'id': link.__name__, + 'text': II18n(link).query_attribute('title', request=self.request)} + for link in container.values()] + return {'status': 'callback', + 'callback': 'PyAMS_content.links.refresh', + 'options': {'links': links, + 'new_link': {'id': changes.__name__, + 'text': II18n(changes).query_attribute('title', request=self.request)}}} + + +@pagelet_config(name='properties.html', context=IMailtoLink, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION) +class MailtoLinkPropertiesEditForm(AdminDialogEditForm): + """Mailto link properties edit form""" + + legend = _("Edit link properties") + icon_css_class = 'fa fa-fw fa-envelope-o' + + fields = field.Fields(IMailtoLink).omit('__parent__', '__name__') + ajax_handler = 'properties.json' + edit_permission = MANAGE_CONTENT_PERMISSION + + def updateWidgets(self, prefix=None): + super(MailtoLinkPropertiesEditForm, self).updateWidgets(prefix) + self.widgets['description'].label_css_class = 'textarea' + + +@view_config(name='properties.json', context=IMailtoLink, request_type=IPyAMSLayer, + permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True) +class MailtoLinkPropertiesAJAXEditForm(AJAXEditForm, MailtoLinkPropertiesEditForm): + """Mailto link properties edit form, JSON renderer""" + + def get_ajax_output(self, changes): + if ('title' in changes.get(IBaseLink, ())) or \ + ('reference' in changes.get(IMailtoLink, ())): + return {'status': 'reload', + 'location': '#links.html'} + else: + return super(MailtoLinkPropertiesAJAXEditForm, self).get_ajax_output(changes) diff -r d9400e3ca85d -r 4acef7070de7 src/pyams_content/component/links/zmi/container.py --- a/src/pyams_content/component/links/zmi/container.py Fri Jul 08 15:39:08 2016 +0200 +++ b/src/pyams_content/component/links/zmi/container.py Mon Jul 11 12:26:22 2016 +0200 @@ -14,6 +14,7 @@ # import standard library +import html # import interfaces from pyams_content.component.extfile.interfaces import IExtFileContainer, IExtFileContainerTarget @@ -162,7 +163,7 @@ mapping = get_sequence_dict(obj.get_target()) return mapping['text'] else: - return obj.url + return html.escape(obj.get_url(self.request)) @adapter_config(name='trash', context=(ILinkContainerTarget, IPyAMSLayer, LinkContainerTable), provides=IColumn) diff -r d9400e3ca85d -r 4acef7070de7 src/pyams_content/component/links/zmi/templates/widget-input.pt --- a/src/pyams_content/component/links/zmi/templates/widget-input.pt Fri Jul 08 15:39:08 2016 +0200 +++ b/src/pyams_content/component/links/zmi/templates/widget-input.pt Mon Jul 11 12:26:22 2016 +0200 @@ -19,6 +19,13 @@ Add external link... +
  • + + + Add mailto link... + +