Added "++lang++" namespace traverser
authorThierry Florac <thierry.florac@onf.fr>
Fri, 22 Feb 2019 12:32:18 +0100
changeset 85 fecadd248cdb
parent 84 e2aceb25e9a5
child 86 5831b250d96d
Added "++lang++" namespace traverser
src/pyams_i18n/negotiator.py
--- a/src/pyams_i18n/negotiator.py	Fri Dec 28 10:59:43 2018 +0100
+++ b/src/pyams_i18n/negotiator.py	Fri Feb 22 12:32:18 2019 +0100
@@ -12,21 +12,19 @@
 
 __docformat__ = 'restructuredtext'
 
-
-# import standard library
-
-# import interfaces
-from pyams_i18n.interfaces import INegotiator, LANGUAGE_CACHE_KEY
-from zope.i18n.interfaces import INegotiator as IZopeNegotiator
-
-# import packages
-from pyams_utils.i18n import get_browser_language
-from pyams_utils.registry import query_utility, utility_config, get_global_registry
 from persistent import Persistent
 from zope.container.contained import Contained
+from zope.i18n.interfaces import INegotiator as IZopeNegotiator
 from zope.i18n.locales import locales
-from zope.interface import implementer
+from zope.interface import Interface, implementer
 from zope.schema.fieldproperty import FieldProperty
+from zope.traversing.interfaces import ITraversable
+
+from pyams_i18n.interfaces import INegotiator, LANGUAGE_CACHE_KEY
+from pyams_skin.layer import IPyAMSUserLayer
+from pyams_utils.adapter import ContextRequestAdapter, adapter_config
+from pyams_utils.i18n import get_browser_language
+from pyams_utils.registry import get_global_registry, query_utility, utility_config
 
 
 @implementer(INegotiator)
@@ -40,6 +38,11 @@
 
     def get_language(self, request):
         """See :intf:`INegotiator`"""
+
+        # lang parameter, if defined, is of higher priority
+        if 'lang' in request.params:
+            return request.params['lang']
+
         policies = self.policy.split(' --> ')
         for policy in policies:
 
@@ -84,8 +87,25 @@
             pass
 
 
+@adapter_config(name='lang', context=(Interface, IPyAMSUserLayer), provides=ITraversable)
+class LangNamespaceTraverser(ContextRequestAdapter):
+    """++lang++ namespace traverser
+
+    This traverser is mainly used for backward compatibility with previous Zope 3 websites.
+    """
+
+    def traverse(self, name, furtherpath=None):
+        if name != '*':
+            self.request.GET['lang'] = name
+        return self.context
+
+
 def locale_negotiator(request):
-    """Negotiate language based on server, browser and user settings"""
+    """Negotiate language based on server, browser, request and user settings
+
+    Locale is extracted from request's "lang" parameter, from browser settings or from
+    negotiator utility
+    """
     negotiator = query_utility(INegotiator)
     if negotiator is not None:
         locale_name = negotiator.get_language(request)
@@ -101,7 +121,7 @@
 
 
 def get_locale(request):
-    """Get zope.i18n locale attribute"""
+    """Get zope.i18n "locale" attribute"""
     return locales.getLocale(request.locale_name)