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): |