Permalink
Browse files

Support unknown locales in Python. [bug 650363]

* Removes known-unknown locales from .htaccess.
* Makes it easy to add known-unknown locales in the future.
  • Loading branch information...
1 parent 32f0dfa commit b2fda76f6a6875bbb2703dd352ca1aa50a6009ba James Socol committed May 4, 2011
Showing with 51 additions and 4 deletions.
  1. +24 −1 apps/sumo/tests/test_locale_middleware.py
  2. +20 −1 apps/sumo/urlresolvers.py
  3. +7 −0 settings.py
  4. +0 −2 webroot/.htaccess
View
25 apps/sumo/tests/test_locale_middleware.py
@@ -1,7 +1,10 @@
+from django.conf import settings
+
+import mock
from nose.tools import eq_
from sumo.tests import TestCase
-from sumo.urlresolvers import get_best_language
+from sumo.urlresolvers import get_best_language, get_non_supported
class TestLocaleMiddleware(TestCase):
@@ -81,3 +84,23 @@ def test_prefix_matching(self):
"""en-US is a better match for en-gb, es;q=0.2 than es."""
best = get_best_language('en-gb, es;q=0.2')
eq_('en-US', best)
+
+
+class NonSupportedTests(TestCase):
+ @mock.patch.object(settings._wrapped, 'NON_SUPPORTED_LOCALES',
+ {'nn-NO': 'no', 'xx': None})
+ def test_get_non_supported(self):
+ eq_('no', get_non_supported('nn-NO'))
+ eq_('no', get_non_supported('nn-no'))
+ eq_(settings.LANGUAGE_CODE, get_non_supported('xx'))
+ eq_(None, get_non_supported('xx-YY'))
+
+ @mock.patch.object(settings._wrapped, 'NON_SUPPORTED_LOCALES',
+ {'nn-NO': 'no'})
+ def test_middleware(self):
+ response = self.client.get('/nn-NO/home', follow=True)
+ self.assertRedirects(response, '/no/home', status_code=302)
+
+ response = self.client.get('/home', follow=True,
+ HTTP_ACCEPT_LANGUAGE='nn-no')
+ self.assertRedirects(response, '/no/home', status_code=302)
View
21 apps/sumo/urlresolvers.py
@@ -61,6 +61,18 @@ def find_supported(test):
x.split('-', 1)[0] == test.lower().split('-', 1)[0]]
+def get_non_supported(lang):
+ """Find known non-supported locales with fallbacks."""
+ lang = lang.lower()
+ langs = dict((k.lower(), v) for k, v in
+ settings.NON_SUPPORTED_LOCALES.items())
+ if lang in langs:
+ if langs[lang] is None:
+ return settings.LANGUAGE_CODE
+ return langs[lang]
+ return None
+
+
def get_best_language(accept_lang):
"""Given an Accept-Language header, return the best-matching language."""
@@ -76,7 +88,12 @@ def get_best_language(accept_lang):
pre = lang.split('-')[0]
if pre in langs:
return langs[pre]
- # Could not find an acceptable language.
+ # Separate because it should never take precedence.
+ for lang, _ in ranked:
+ ns = get_non_supported(lang)
+ if ns is not None:
+ return ns
+ # Couldn't find any acceptable locale.
return False
@@ -94,6 +111,8 @@ def split_path(path):
lang = first.lower()
if lang in settings.LANGUAGE_URL_MAP:
return settings.LANGUAGE_URL_MAP[lang], rest
+ elif get_non_supported(lang) is not None:
+ return get_non_supported(lang), rest
else:
supported = find_supported(first)
if supported:
View
7 settings.py
@@ -78,6 +78,13 @@
LANGUAGE_URL_MAP = dict([(i.lower(), i) for i in SUMO_LANGUAGES])
+# Locales that are known but unsupported. Keys are the locale, values are
+# an optional fallback locale, or None, to use the LANGUAGE_CODE.
+NON_SUPPORTED_LOCALES = {
+ 'nb-NO': 'no',
+ 'nn-NO': 'no',
+}
+
TEXT_DOMAIN = 'messages'
SITE_ID = 1
View
2 webroot/.htaccess
@@ -2,8 +2,6 @@ RewriteEngine On
# Redirect locales that point to one locale in SUMO.
# Kitsune does this by itself, mostly.
-# Not sure about this guy: may need to special-case it in the LocaleURLMiddleware.
-RewriteRule ^n[bn]\-NO/(.+)$ /no/$1 [L,R]
# Just need to move sr-CYRL above sr-LATN to get this.
RewriteRule ^sr/(.+)$ /sr-CYRL/$1 [L,R]

0 comments on commit b2fda76

Please sign in to comment.