--- a/src/pyams_content/component/links/__init__.py Wed Sep 25 09:47:48 2019 +0200
+++ b/src/pyams_content/component/links/__init__.py Wed Sep 25 09:50:05 2019 +0200
@@ -10,20 +10,20 @@
# FOR A PARTICULAR PURPOSE.
#
-__docformat__ = 'restructuredtext'
-
from html import escape
-from pyramid.encode import url_quote
-from zope.interface import implementer
+from pyramid.encode import url_quote, urlencode
+from pyramid.events import subscriber
+from zope.interface import alsoProvides, implementer, directlyProvidedBy, noLongerProvides
+from zope.lifecycleevent import IObjectAddedEvent, IObjectModifiedEvent
from zope.schema.fieldproperty import FieldProperty
from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
-from pyams_content import _
from pyams_content.component.association import AssociationItem
-from pyams_content.component.association.interfaces import IAssociationContainer, IAssociationContainerTarget, \
- IAssociationInfo
-from pyams_content.component.links.interfaces import IBaseLink, IExternalLink, IInternalLink, IMailtoLink
+from pyams_content.component.association.interfaces import IAssociationContainer, \
+ IAssociationContainerTarget, IAssociationInfo
+from pyams_content.component.links.interfaces import IBaseLink, IExternalLink, IInternalLink, \
+ IInternalLinkCustomInfoTarget, IMailtoLink, IInternalLinkCustomInfo, ICustomInternalLinkTarget
from pyams_content.features.checker import BaseContentChecker
from pyams_content.features.checker.interfaces import ERROR_VALUE, IContentChecker
from pyams_content.interfaces import IBaseContent
@@ -42,6 +42,11 @@
from pyams_workflow.interfaces import IWorkflow, IWorkflowPublicationInfo
+__docformat__ = 'restructuredtext'
+
+from pyams_content import _
+
+
#
# Links vocabulary
#
@@ -55,7 +60,8 @@
target = get_parent(context, IAssociationContainerTarget)
if target is not None:
terms = [SimpleTerm(link.__name__, title=IAssociationInfo(link).inner_title)
- for link in IAssociationContainer(target).values() if IBaseLink.providedBy(link)]
+ for link in IAssociationContainer(target).values() if
+ IBaseLink.providedBy(link)]
super(ContentLinksVocabulary, self).__init__(terms)
@@ -106,7 +112,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())
#
@@ -157,14 +163,48 @@
if target is not None:
if request is None:
request = check_request()
+ params = None
+ if IInternalLinkCustomInfoTarget.providedBy(target):
+ custom_info = IInternalLinkCustomInfo(self, None)
+ if custom_info is not None:
+ params = custom_info.get_url_params()
+ if params:
+ params = urlencode(params)
if self.force_canonical_url:
- return canonical_url(target, request, view_name)
+ return canonical_url(target, request, view_name, query=params)
else:
- return relative_url(target, request, view_name=view_name)
+ return relative_url(target, request, view_name=view_name, query=params)
else:
return ''
+@subscriber(IObjectAddedEvent, context_selector=IInternalLink)
+def handle_new_internal_link(event):
+ """Check if link target is providing custom info"""
+ link = event.object
+ target = link.target
+ if target is not None:
+ info = IInternalLinkCustomInfoTarget(target, None)
+ if info is not None:
+ alsoProvides(link, info.internal_link_marker_interface)
+
+
+@subscriber(IObjectModifiedEvent, context_selector=IInternalLink)
+def handle_updated_internal_link(event):
+ """Check when modified if new link target is providing custom info"""
+ link = event.object
+ # remove previous provided interfaces
+ ifaces = tuple([iface for iface in directlyProvidedBy(link)
+ if issubclass(iface, IInternalLinkCustomInfo)])
+ for iface in ifaces:
+ noLongerProvides(link, iface)
+ target = link.target
+ if target is not None:
+ info = IInternalLinkCustomInfoTarget(target, None)
+ if info is not None:
+ alsoProvides(link, info.internal_link_marker_interface)
+
+
@adapter_config(context=IInternalLink, provides=IAssociationInfo)
class InternalLinkAssociationInfoAdapter(BaseLinkInfoAdapter):
"""Internal link association info adapter"""
@@ -206,8 +246,10 @@
if workflow is not None:
target = self.context.get_target(state=workflow.published_states)
if target is None:
- output.append(translate(ERROR_VALUE).format(field=IInternalLink['reference'].title,
- message=translate(_("target is not published"))))
+ output.append(
+ translate(ERROR_VALUE).format(field=IInternalLink['reference'].title,
+ message=translate(
+ _("target is not published"))))
return output