Skip to content

Commit

Permalink
Support unknown locales in Python. [bug 650363]
Browse files Browse the repository at this point in the history
* Removes known-unknown locales from .htaccess.
* Makes it easy to add known-unknown locales in the future.
  • Loading branch information
James Socol committed May 4, 2011
1 parent 32f0dfa commit b2fda76
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
25 changes: 24 additions & 1 deletion apps/sumo/tests/test_locale_middleware.py
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.conf import settings

import mock
from nose.tools import eq_ from nose.tools import eq_


from sumo.tests import TestCase 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): class TestLocaleMiddleware(TestCase):
Expand Down Expand Up @@ -81,3 +84,23 @@ def test_prefix_matching(self):
"""en-US is a better match for en-gb, es;q=0.2 than es.""" """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') best = get_best_language('en-gb, es;q=0.2')
eq_('en-US', best) 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)
21 changes: 20 additions & 1 deletion apps/sumo/urlresolvers.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ def find_supported(test):
x.split('-', 1)[0] == test.lower().split('-', 1)[0]] 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): def get_best_language(accept_lang):
"""Given an Accept-Language header, return the best-matching language.""" """Given an Accept-Language header, return the best-matching language."""


Expand All @@ -76,7 +88,12 @@ def get_best_language(accept_lang):
pre = lang.split('-')[0] pre = lang.split('-')[0]
if pre in langs: if pre in langs:
return langs[pre] 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 return False




Expand All @@ -94,6 +111,8 @@ def split_path(path):
lang = first.lower() lang = first.lower()
if lang in settings.LANGUAGE_URL_MAP: if lang in settings.LANGUAGE_URL_MAP:
return settings.LANGUAGE_URL_MAP[lang], rest return settings.LANGUAGE_URL_MAP[lang], rest
elif get_non_supported(lang) is not None:
return get_non_supported(lang), rest
else: else:
supported = find_supported(first) supported = find_supported(first)
if supported: if supported:
Expand Down
7 changes: 7 additions & 0 deletions settings.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@


LANGUAGE_URL_MAP = dict([(i.lower(), i) for i in SUMO_LANGUAGES]) 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' TEXT_DOMAIN = 'messages'


SITE_ID = 1 SITE_ID = 1
Expand Down
2 changes: 0 additions & 2 deletions webroot/.htaccess
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ RewriteEngine On


# Redirect locales that point to one locale in SUMO. # Redirect locales that point to one locale in SUMO.
# Kitsune does this by itself, mostly. # 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. # Just need to move sr-CYRL above sr-LATN to get this.
RewriteRule ^sr/(.+)$ /sr-CYRL/$1 [L,R] RewriteRule ^sr/(.+)$ /sr-CYRL/$1 [L,R]


Expand Down

0 comments on commit b2fda76

Please sign in to comment.