diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py index 2600b85727..5c4a5e8c70 100644 --- a/django/utils/translation/__init__.py +++ b/django/utils/translation/__init__.py @@ -205,6 +205,10 @@ def get_language_from_path(path): return _trans.get_language_from_path(path) +def get_supported_language_variant(lang_code, *, strict=False): + return _trans.get_supported_language_variant(lang_code, strict) + + def templatize(src, **kwargs): from .template import templatize return templatize(src, **kwargs) diff --git a/django/utils/translation/trans_null.py b/django/utils/translation/trans_null.py index 72af147351..3eb6910f04 100644 --- a/django/utils/translation/trans_null.py +++ b/django/utils/translation/trans_null.py @@ -66,3 +66,10 @@ def get_language_from_request(request, check_path=False): def get_language_from_path(request): return None + + +def get_supported_language_variant(lang_code, strict=False): + if lang_code == settings.LANGUAGE_CODE: + return lang_code + else: + raise LookupError(lang_code) diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index d6127e3fed..581156b5d8 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -1092,6 +1092,23 @@ functions without the ``u``. for whether its path begins with a language code listed in the :setting:`LANGUAGES` setting. +.. function:: get_supported_language_variant(lang_code, strict=False) + + .. versionadded:: 2.1 + + Returns ``lang_code`` if it's in the :setting:`LANGUAGES` setting, possibly + selecting a more generic variant. For example, ``'es'`` is returned if + ``lang_code`` is ``'es-ar'`` and ``'es'`` is in :setting:`LANGUAGES` but + ``'es-ar'`` isn't. + + If ``strict`` is ``False`` (the default), a country-specific variant may + be returned when neither the language code nor its generic variant is found. + For example, if only ``'es-co'`` is in :setting:`LANGUAGES`, that's + returned for ``lang_code``\s like ``'es'`` and ``'es-ar'``. Those matches + aren't returned if ``strict=True``. + + Raises :exc:`LookupError` if nothing is found. + .. function:: to_locale(language) Turns a language name (en-us) into a locale name (en_US). diff --git a/docs/releases/2.1.txt b/docs/releases/2.1.txt index b1fc5015f6..0963862f17 100644 --- a/docs/releases/2.1.txt +++ b/docs/releases/2.1.txt @@ -162,7 +162,8 @@ Generic Views Internationalization ~~~~~~~~~~~~~~~~~~~~ -* ... +* Added the :meth:`~django.utils.translation.get_supported_language_variant` + function. Management Commands ~~~~~~~~~~~~~~~~~~~ diff --git a/tests/i18n/tests.py b/tests/i18n/tests.py index 10deb48479..afb4ac2ddb 100644 --- a/tests/i18n/tests.py +++ b/tests/i18n/tests.py @@ -1306,6 +1306,50 @@ class MiscTests(SimpleTestCase): r.META = {'HTTP_ACCEPT_LANGUAGE': 'de'} self.assertEqual(g(r), 'zh-hans') + @override_settings( + USE_I18N=True, + LANGUAGES=[ + ('en', 'English'), + ('de', 'German'), + ('de-at', 'Austrian German'), + ('pt-br', 'Portuguese (Brazil)'), + ], + ) + def test_get_supported_language_variant_real(self): + g = trans_real.get_supported_language_variant + self.assertEqual(g('en'), 'en') + self.assertEqual(g('en-gb'), 'en') + self.assertEqual(g('de'), 'de') + self.assertEqual(g('de-at'), 'de-at') + self.assertEqual(g('de-ch'), 'de') + self.assertEqual(g('pt-br'), 'pt-br') + self.assertEqual(g('pt'), 'pt-br') + self.assertEqual(g('pt-pt'), 'pt-br') + with self.assertRaises(LookupError): + g('pt', strict=True) + with self.assertRaises(LookupError): + g('pt-pt', strict=True) + with self.assertRaises(LookupError): + g('xyz') + with self.assertRaises(LookupError): + g('xy-zz') + + def test_get_supported_language_variant_null(self): + g = trans_null.get_supported_language_variant + self.assertEqual(g(settings.LANGUAGE_CODE), settings.LANGUAGE_CODE) + with self.assertRaises(LookupError): + g('pt') + with self.assertRaises(LookupError): + g('de') + with self.assertRaises(LookupError): + g('de-at') + with self.assertRaises(LookupError): + g('de', strict=True) + with self.assertRaises(LookupError): + g('de-at', strict=True) + with self.assertRaises(LookupError): + g('xyz') + @override_settings( LANGUAGES=[ ('en', 'English'),