Added IRelativeURL interface, default adapter and TALES "relative_url" extension to get content's URL based on current display context
--- a/src/pyams_utils/interfaces/url.py Tue Jun 19 16:10:04 2018 +0200
+++ b/src/pyams_utils/interfaces/url.py Fri Jun 22 12:50:19 2018 +0200
@@ -26,3 +26,13 @@
def get_url(self, view_name=None, query=None):
"""Get content's canonical URL"""
+
+
+DISPLAY_CONTEXT = 'pyams_utils.display_context'
+
+
+class IRelativeURL(Interface):
+ """Get content URL based on another context"""
+
+ def get_url(self, display_context=None, view_name=None, query=None):
+ """Get content URL relative to given display context"""
--- a/src/pyams_utils/url.py Tue Jun 19 16:10:04 2018 +0200
+++ b/src/pyams_utils/url.py Fri Jun 22 12:50:19 2018 +0200
@@ -17,10 +17,10 @@
# import interfaces
from pyams_utils.interfaces.tales import ITALESExtension
-from pyams_utils.interfaces.url import ICanonicalURL
+from pyams_utils.interfaces.url import ICanonicalURL, IRelativeURL, DISPLAY_CONTEXT
# import packages
-from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
+from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config, ContextRequestAdapter
from pyams_utils.unicode import translate_string
from pyramid.encode import url_quote, urlencode
from pyramid.url import resource_url, QUERY_SAFE
@@ -38,6 +38,10 @@
remove_punctuation=True, keep_chars='-').split('-')))
+#
+# Absolute URLs management
+#
+
def absolute_url(context, request, view_name=None, query=None):
"""Get resource absolute_url
@@ -88,6 +92,10 @@
return absolute_url(context, self.request, view_name)
+#
+# Canonical URLs management
+#
+
def canonical_url(context, request, view_name=None, query=None):
"""Get resource canonical URL"""
@@ -116,3 +124,36 @@
if context is None:
context = self.context
return canonical_url(context, self.request, view_name)
+
+
+#
+# Relative URLs management
+#
+
+@adapter_config(context=(Interface, Interface), provides=IRelativeURL)
+class DefaultRelativeURLAdapter(ContextRequestAdapter):
+ """Default relative URL adapter"""
+
+ def get_url(self, display_context=None, view_name=None, query=None):
+ return absolute_url(self.context, self.request, view_name, query)
+
+
+def relative_url(context, request, display_context=None, view_name=None, query=None):
+ """Get resource URL relative to given context"""
+ if display_context is None:
+ display_context = request.annotations.get(DISPLAY_CONTEXT, request.context)
+ adapter = request.registry.getMultiAdapter((context, request), IRelativeURL)
+ return adapter.get_url(display_context, view_name, query)
+
+
+@adapter_config(name='relative_url', context=(Interface, Interface, Interface), provides=ITALESExtension)
+class RelativeUrlTalesExtension(ContextRequestViewAdapter):
+ """extension:relative_url(context, view_name, query) TALES extension
+
+ A PyAMS TALES extension used to get an object's relative URL based on current request display context.
+ """
+
+ def render(self, context=None, view_name=None, query=None):
+ if context is None:
+ context = self.context
+ return relative_url(context, self.request, view_name=view_name, query=query)