Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
Malcolm Tredinnick authored February 06, 2008
2  django/conf/global_settings.py
@@ -47,7 +47,7 @@
47 47
     ('el', gettext_noop('Greek')),
48 48
     ('en', gettext_noop('English')),
49 49
     ('es', gettext_noop('Spanish')),
50  
-    ('es_AR', gettext_noop('Argentinean Spanish')),
  50
+    ('es-ar', gettext_noop('Argentinean Spanish')),
51 51
     ('fa', gettext_noop('Persian')),
52 52
     ('fi', gettext_noop('Finnish')),
53 53
     ('fr', gettext_noop('French')),
21  django/utils/translation/trans_real.py
@@ -42,7 +42,10 @@ def currentThread():
42 42
         ''', re.VERBOSE)
43 43
 
44 44
 def to_locale(language, to_lower=False):
45  
-    "Turns a language name (en-us) into a locale name (en_US)."
  45
+    """
  46
+    Turns a language name (en-us) into a locale name (en_US). If 'to_lower' is
  47
+    True, the last component is lower-cased (en_us).
  48
+    """
46 49
     p = language.find('-')
47 50
     if p >= 0:
48 51
         if to_lower:
@@ -357,19 +360,20 @@ def get_language_from_request(request):
357 360
         return lang_code
358 361
 
359 362
     accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
360  
-    for lang, unused in parse_accept_lang_header(accept):
361  
-        if lang == '*':
  363
+    for accept_lang, unused in parse_accept_lang_header(accept):
  364
+        if accept_lang == '*':
362 365
             break
363 366
 
364 367
         # We have a very restricted form for our language files (no encoding
365 368
         # specifier, since they all must be UTF-8 and only one possible
366 369
         # language each time. So we avoid the overhead of gettext.find() and
367  
-        # look up the MO file manually.
  370
+        # work out the MO file manually.
368 371
 
369  
-        normalized = locale.locale_alias.get(to_locale(lang, True))
  372
+        # 'normalized' is the root name of the locale in POSIX format (which is
  373
+        # the format used for the directories holding the MO files).
  374
+        normalized = locale.locale_alias.get(to_locale(accept_lang, True))
370 375
         if not normalized:
371 376
             continue
372  
-
373 377
         # Remove the default encoding from locale_alias
374 378
         normalized = normalized.split('.')[0]
375 379
 
@@ -378,10 +382,11 @@ def get_language_from_request(request):
378 382
             # need to check again.
379 383
             return _accepted[normalized]
380 384
 
381  
-        for lang in (normalized, normalized.split('_')[0]):
  385
+        for lang, dirname in ((accept_lang, normalized),
  386
+                (accept_lang.split('-')[0], normalized.split('_')[0])):
382 387
             if lang not in supported:
383 388
                 continue
384  
-            langfile = os.path.join(globalpath, lang, 'LC_MESSAGES',
  389
+            langfile = os.path.join(globalpath, dirname, 'LC_MESSAGES',
385 390
                     'django.mo')
386 391
             if os.path.exists(langfile):
387 392
                 _accepted[normalized] = lang
45  tests/regressiontests/i18n/misc.py
@@ -2,6 +2,11 @@
2 2
 >>> from django.utils.translation.trans_real import parse_accept_lang_header
3 3
 >>> p = parse_accept_lang_header
4 4
 
  5
+#
  6
+# Testing HTTP header parsing. First, we test that we can parse the values
  7
+# according to the spec (and that we extract all the pieces in the right order).
  8
+#
  9
+
5 10
 Good headers.
6 11
 >>> p('de')
7 12
 [('de', 1.0)]
@@ -54,4 +59,44 @@
54 59
 >>> p('')
55 60
 []
56 61
 
  62
+#
  63
+# Now test that we parse a literal HTTP header correctly.
  64
+#
  65
+
  66
+>>> from django.utils.translation.trans_real import get_language_from_request
  67
+>>> g = get_language_from_request
  68
+>>> from django.http import HttpRequest
  69
+>>> r = HttpRequest
  70
+>>> r.COOKIES = {}
  71
+
  72
+These tests assumes the es, es_AR, pt and pt_BR translations exit in the Django
  73
+source tree.
  74
+>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt-br'}
  75
+>>> g(r)
  76
+'pt-br'
  77
+>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'pt'}
  78
+>>> g(r)
  79
+'pt'
  80
+>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es,de'}
  81
+>>> g(r)
  82
+'es'
  83
+>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-ar,de'}
  84
+>>> g(r)
  85
+'es-ar'
  86
+
  87
+This test assumes there won't be a Django translation to a US variation
  88
+of the Spanish language, a safe assumption. When the user sets it
  89
+as the preferred language, the main 'es' translation should be selected
  90
+instead.
  91
+>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'es-us'}
  92
+>>> g(r)
  93
+'es'
  94
+
  95
+This tests the following scenario: there isn't a main language (zh)
  96
+translation of Django but there is a translation to variation (zh_CN)
  97
+the user sets zh-cn as the preferred language, it should be selected by
  98
+Django without falling back nor ignoring it.
  99
+>>> r.META = {'HTTP_ACCEPT_LANGUAGE': 'zh-cn,de'}
  100
+>>> g(r)
  101
+'zh-cn'
57 102
 """

0 notes on commit 0a3c8f0

Please sign in to comment.
Something went wrong with that request. Please try again.