Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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
  • Loading branch information...
commit 0a3c8f03e064e3c0502e9df64ad06764204c4b4a 1 parent fc1889a
@malcolmt malcolmt authored
View
2  django/conf/global_settings.py
@@ -47,7 +47,7 @@
('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')),
View
21 django/utils/translation/trans_real.py
@@ -42,7 +42,10 @@ def currentThread():
''', 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
View
45 tests/regressiontests/i18n/misc.py
@@ -2,6 +2,11 @@
>>> 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 @@
>>> 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'
"""
Please sign in to comment.
Something went wrong with that request. Please try again.