src/pyams_i18n/negotiator.py
changeset 85 fecadd248cdb
parent 52 568ef229cc20
equal deleted inserted replaced
84:e2aceb25e9a5 85:fecadd248cdb
    10 # FOR A PARTICULAR PURPOSE.
    10 # FOR A PARTICULAR PURPOSE.
    11 #
    11 #
    12 
    12 
    13 __docformat__ = 'restructuredtext'
    13 __docformat__ = 'restructuredtext'
    14 
    14 
    15 
       
    16 # import standard library
       
    17 
       
    18 # import interfaces
       
    19 from pyams_i18n.interfaces import INegotiator, LANGUAGE_CACHE_KEY
       
    20 from zope.i18n.interfaces import INegotiator as IZopeNegotiator
       
    21 
       
    22 # import packages
       
    23 from pyams_utils.i18n import get_browser_language
       
    24 from pyams_utils.registry import query_utility, utility_config, get_global_registry
       
    25 from persistent import Persistent
    15 from persistent import Persistent
    26 from zope.container.contained import Contained
    16 from zope.container.contained import Contained
       
    17 from zope.i18n.interfaces import INegotiator as IZopeNegotiator
    27 from zope.i18n.locales import locales
    18 from zope.i18n.locales import locales
    28 from zope.interface import implementer
    19 from zope.interface import Interface, implementer
    29 from zope.schema.fieldproperty import FieldProperty
    20 from zope.schema.fieldproperty import FieldProperty
       
    21 from zope.traversing.interfaces import ITraversable
       
    22 
       
    23 from pyams_i18n.interfaces import INegotiator, LANGUAGE_CACHE_KEY
       
    24 from pyams_skin.layer import IPyAMSUserLayer
       
    25 from pyams_utils.adapter import ContextRequestAdapter, adapter_config
       
    26 from pyams_utils.i18n import get_browser_language
       
    27 from pyams_utils.registry import get_global_registry, query_utility, utility_config
    30 
    28 
    31 
    29 
    32 @implementer(INegotiator)
    30 @implementer(INegotiator)
    33 class Negotiator(Persistent, Contained):
    31 class Negotiator(Persistent, Contained):
    34     """Language negotiator utility"""
    32     """Language negotiator utility"""
    38     offered_languages = FieldProperty(INegotiator['offered_languages'])
    36     offered_languages = FieldProperty(INegotiator['offered_languages'])
    39     cache_enabled = FieldProperty(INegotiator['cache_enabled'])
    37     cache_enabled = FieldProperty(INegotiator['cache_enabled'])
    40 
    38 
    41     def get_language(self, request):
    39     def get_language(self, request):
    42         """See :intf:`INegotiator`"""
    40         """See :intf:`INegotiator`"""
       
    41 
       
    42         # lang parameter, if defined, is of higher priority
       
    43         if 'lang' in request.params:
       
    44             return request.params['lang']
       
    45 
    43         policies = self.policy.split(' --> ')
    46         policies = self.policy.split(' --> ')
    44         for policy in policies:
    47         for policy in policies:
    45 
    48 
    46             # check server policy
    49             # check server policy
    47             if policy == 'server':
    50             if policy == 'server':
    82             del request.annotations[LANGUAGE_CACHE_KEY]
    85             del request.annotations[LANGUAGE_CACHE_KEY]
    83         except KeyError:
    86         except KeyError:
    84             pass
    87             pass
    85 
    88 
    86 
    89 
       
    90 @adapter_config(name='lang', context=(Interface, IPyAMSUserLayer), provides=ITraversable)
       
    91 class LangNamespaceTraverser(ContextRequestAdapter):
       
    92     """++lang++ namespace traverser
       
    93 
       
    94     This traverser is mainly used for backward compatibility with previous Zope 3 websites.
       
    95     """
       
    96 
       
    97     def traverse(self, name, furtherpath=None):
       
    98         if name != '*':
       
    99             self.request.GET['lang'] = name
       
   100         return self.context
       
   101 
       
   102 
    87 def locale_negotiator(request):
   103 def locale_negotiator(request):
    88     """Negotiate language based on server, browser and user settings"""
   104     """Negotiate language based on server, browser, request and user settings
       
   105 
       
   106     Locale is extracted from request's "lang" parameter, from browser settings or from
       
   107     negotiator utility
       
   108     """
    89     negotiator = query_utility(INegotiator)
   109     negotiator = query_utility(INegotiator)
    90     if negotiator is not None:
   110     if negotiator is not None:
    91         locale_name = negotiator.get_language(request)
   111         locale_name = negotiator.get_language(request)
    92     else:
   112     else:
    93         locale_name = get_browser_language(request)
   113         locale_name = get_browser_language(request)
    99         locale_name = locale_name.split('-')[0]
   119         locale_name = locale_name.split('-')[0]
   100     return locale_name
   120     return locale_name
   101 
   121 
   102 
   122 
   103 def get_locale(request):
   123 def get_locale(request):
   104     """Get zope.i18n locale attribute"""
   124     """Get zope.i18n "locale" attribute"""
   105     return locales.getLocale(request.locale_name)
   125     return locales.getLocale(request.locale_name)
   106 
   126 
   107 
   127 
   108 @utility_config(provides=IZopeNegotiator)
   128 @utility_config(provides=IZopeNegotiator)
   109 class ZopeNegotiator(object):
   129 class ZopeNegotiator(object):