Ticket #20125: locale.py

File locale.py, 4.0 KB (added by Max Arnold, 11 years ago)

rough concept of how locale selector might look like

Line 
1from __future__ import unicode_literals
2import locale
3import os
4
5from django.utils.translation.trans_real import (get_supported_language_variant,
6 parse_accept_lang_header,
7 get_language_from_path,
8 check_for_language,
9 all_locale_paths,
10 to_locale,
11 _accepted)
12
13# TODO: locale mapper (map locale in url to one of supported locales)
14# this may be convenient to design localized url first (for SEO purposes)
15# and add more locales later
16
17def LocaleSelector(object):
18 def __init__(self, check_path=False):
19 from django.conf import settings
20 self.supported = dict(settings.LANGUAGES)
21 self.cookie_name = settings.LANGUAGE_COOKIE_NAME
22 self.default_language_code = settings.LANGUAGE_CODE
23 self.check_path = check_path
24 self.selectors = [self.get_language_from_path,
25 self.get_language_from_session,
26 self.get_language_from_cookie,
27 self.get_language_from_header,
28 self.get_fallback_language] # last one should always return a result
29
30 def get_language_from_path(request):
31 if self.check_path:
32 lang_code = get_language_from_path(request.path_info, self.supported)
33 if lang_code is not None:
34 return lang_code
35
36 def get_language_from_session(request):
37 if hasattr(request, 'session'):
38 lang_code = request.session.get('django_language', None)
39 if lang_code in self.supported and lang_code is not None and check_for_language(lang_code):
40 return lang_code
41
42 def get_language_from_cookie(request):
43 lang_code = request.COOKIES.get(self.cookie_name)
44 try:
45 return get_supported_language_variant(lang_code, self.supported)
46 except LookupError:
47 pass
48
49 def get_language_from_header(request):
50 global _accepted
51
52 accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
53 for accept_lang, unused in parse_accept_lang_header(accept):
54 if accept_lang == '*':
55 break
56
57 # We have a very restricted form for our language files (no encoding
58 # specifier, since they all must be UTF-8 and only one possible
59 # language each time. So we avoid the overhead of gettext.find() and
60 # work out the MO file manually.
61
62 # 'normalized' is the root name of the locale in POSIX format (which is
63 # the format used for the directories holding the MO files).
64 normalized = locale.locale_alias.get(to_locale(accept_lang, True))
65 if not normalized:
66 continue
67 # Remove the default encoding from locale_alias.
68 normalized = normalized.split('.')[0]
69
70 if normalized in _accepted:
71 # We've seen this locale before and have an MO file for it, so no
72 # need to check again.
73 return _accepted[normalized]
74
75 for lang, dirname in ((accept_lang, normalized),
76 (accept_lang.split('-')[0], normalized.split('_')[0])):
77 if lang.lower() not in self.supported:
78 continue
79 for path in all_locale_paths():
80 if os.path.exists(os.path.join(path, dirname, 'LC_MESSAGES', 'django.mo')):
81 _accepted[normalized] = lang
82 return lang
83
84 def get_fallback_language(_request):
85 try:
86 return get_supported_language_variant(self.default_language_code, self.supported)
87 except LookupError:
88 return self.default_language_code
89
90 def select(request):
91 for selector in self.selectors:
92 lang_code = selector(request)
93 if lang_code is not None:
94 return lang_code
Back to Top