Fixed #6409 -- Unbreak compound locale name parsing (e.g. zh-cn).
This was inadvertently broken back in [6608]. Slightly backwards-incompatible: people specifying "es_AR" in their LANGUAGES list will need to change that to "es-ar". Thanks, simonb and Ramiro Morales for making the effort to fix this. git-svn-id: http://code.djangoproject.com/svn/django/trunk@7091 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
fc1889ad63
commit
0a3c8f03e0
|
@ -47,7 +47,7 @@ LANGUAGES = (
|
|||
('el', gettext_noop('Greek')),
|
||||
('en', gettext_noop('English')),
|
||||
('es', gettext_noop('Spanish')),
|
||||
('es_AR', gettext_noop('Argentinean Spanish')),
|
||||
('es-ar', gettext_noop('Argentinean Spanish')),
|
||||
('fa', gettext_noop('Persian')),
|
||||
('fi', gettext_noop('Finnish')),
|
||||
('fr', gettext_noop('French')),
|
||||
|
|
|
@ -42,7 +42,10 @@ accept_language_re = re.compile(r'''
|
|||
''', re.VERBOSE)
|
||||
|
||||
def to_locale(language, to_lower=False):
|
||||
"Turns a language name (en-us) into a locale name (en_US)."
|
||||
"""
|
||||
Turns a language name (en-us) into a locale name (en_US). If 'to_lower' is
|
||||
True, the last component is lower-cased (en_us).
|
||||
"""
|
||||
p = language.find('-')
|
||||
if p >= 0:
|
||||
if to_lower:
|
||||
|
@ -357,19 +360,20 @@ def get_language_from_request(request):
|
|||
return lang_code
|
||||
|
||||
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
|
||||
for lang, unused in parse_accept_lang_header(accept):
|
||||
if lang == '*':
|
||||
for accept_lang, unused in parse_accept_lang_header(accept):
|
||||
if accept_lang == '*':
|
||||
break
|
||||
|
||||
# We have a very restricted form for our language files (no encoding
|
||||
# specifier, since they all must be UTF-8 and only one possible
|
||||
# language each time. So we avoid the overhead of gettext.find() and
|
||||
# look up the MO file manually.
|
||||
# work out the MO file manually.
|
||||
|
||||
normalized = locale.locale_alias.get(to_locale(lang, True))
|
||||
# 'normalized' is the root name of the locale in POSIX format (which is
|
||||
# the format used for the directories holding the MO files).
|
||||
normalized = locale.locale_alias.get(to_locale(accept_lang, True))
|
||||
if not normalized:
|
||||
continue
|
||||
|
||||
# Remove the default encoding from locale_alias
|
||||
normalized = normalized.split('.')[0]
|
||||
|
||||
|
@ -378,10 +382,11 @@ def get_language_from_request(request):
|
|||
# need to check again.
|
||||
return _accepted[normalized]
|
||||
|
||||
for lang in (normalized, normalized.split('_')[0]):
|
||||
for lang, dirname in ((accept_lang, normalized),
|
||||
(accept_lang.split('-')[0], normalized.split('_')[0])):
|
||||
if lang not in supported:
|
||||
continue
|
||||
langfile = os.path.join(globalpath, lang, 'LC_MESSAGES',
|
||||
langfile = os.path.join(globalpath, dirname, 'LC_MESSAGES',
|
||||
'django.mo')
|
||||
if os.path.exists(langfile):
|
||||
_accepted[normalized] = lang
|
||||
|
|
|
@ -2,6 +2,11 @@ tests = """
|
|||
>>> from django.utils.translation.trans_real import parse_accept_lang_header
|
||||
>>> p = parse_accept_lang_header
|
||||
|
||||
#
|
||||
# Testing HTTP header parsing. First, we test that we can parse the values
|
||||
# according to the spec (and that we extract all the pieces in the right order).
|
||||
#
|
||||
|
||||
Good headers.
|
||||
>>> p('de')
|
||||
[('de', 1.0)]
|
||||
|
@ -54,4 +59,44 @@ Bad headers; should always return [].
|
|||
>>> p('')
|
||||
[]
|
||||
|
||||
#
|
||||
# Now test that we parse a literal HTTP header correctly.
|
||||
#
|
||||
|
||||
>>> from django.utils.translation.trans_real import get_language_from_request
|
||||
>>> g = get_language_from_request
|
||||
>>> from django.http import HttpRequest
|
||||
>>> r = HttpRequest
|
||||
>>> r.COOKIES = {}
|
||||
|
||||
These tests assumes the es, es_AR, pt and pt_BR translations exit in the Django
|
||||
source tree.
|
||||
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'}
|
||||
>>> g(r)
|
||||
'pt-br'
|
||||
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt'}
|
||||
>>> g(r)
|
||||
'pt'
|
||||
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es,de'}
|
||||
>>> g(r)
|
||||
'es'
|
||||
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'}
|
||||
>>> g(r)
|
||||
'es-ar'
|
||||
|
||||
This test assumes there won't be a Django translation to a US variation
|
||||
of the Spanish language, a safe assumption. When the user sets it
|
||||
as the preferred language, the main 'es' translation should be selected
|
||||
instead.
|
||||
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'}
|
||||
>>> g(r)
|
||||
'es'
|
||||
|
||||
This tests the following scenario: there isn't a main language (zh)
|
||||
translation of Django but there is a translation to variation (zh_CN)
|
||||
the user sets zh-cn as the preferred language, it should be selected by
|
||||
Django without falling back nor ignoring it.
|
||||
>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-cn,de'}
|
||||
>>> g(r)
|
||||
'zh-cn'
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue