From b15c679b6c3178c0d2ac56d6989051b94d589266 Mon Sep 17 00:00:00 2001 From: Johannes Hoppe Date: Sun, 16 Jul 2017 11:19:54 +0200 Subject: [PATCH] Add i18n support --- django_select2/__init__.py | 2 +- django_select2/conf.py | 82 ++++++++++++++++++++++++++++++++++++++ django_select2/forms.py | 5 ++- tests/test_forms.py | 22 ++++++++++ tests/testapp/settings.py | 6 +++ 5 files changed, 115 insertions(+), 2 deletions(-) diff --git a/django_select2/__init__.py b/django_select2/__init__.py index f638e09b..412d1edf 100644 --- a/django_select2/__init__.py +++ b/django_select2/__init__.py @@ -9,4 +9,4 @@ """ -__version__ = "5.10.0" +__version__ = "5.11.0" diff --git a/django_select2/conf.py b/django_select2/conf.py index 2bab82c3..37d23e9d 100644 --- a/django_select2/conf.py +++ b/django_select2/conf.py @@ -74,6 +74,88 @@ class Select2Conf(AppConf): develop without an Internet connection. """ + I18N_PATH = '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/i18n' + """ + The base URI for the Select2 i18n files. By default this points to the Cloudflare CDN. + + If you want to select the version of the JS library used, or want to serve it from + the local 'static' resources, add a line to your settings.py like so:: + + SELECT2_JS = 'assets/js/i18n' + + .. tip:: Change this setting to a local asset in your development environment to + develop without an Internet connection. + """ + + I18N_AVAILABLE_LANGUAGES = [ + 'ar', + 'az', + 'bg', + 'ca', + 'cs', + 'da', + 'de', + 'el', + 'en', + 'es', + 'et', + 'eu', + 'fa', + 'fi', + 'fr', + 'gl', + 'he', + 'hi', + 'hr', + 'hu', + 'id', + 'is', + 'it', + 'ja', + 'km', + 'ko', + 'lt', + 'lv', + 'mk', + 'ms', + 'nb', + 'nl', + 'pl', + 'pt-BR', + 'pt', + 'ro', + 'ru', + 'sk', + 'sr-Cyrl', + 'sr', + 'sv', + 'th', + 'tr', + 'uk', + 'vi', + 'zh-CN', + 'zh-TW', + ] + """ + List of available translations. + + List of ISO 639-1 language codes that are supported by Select2. + If currently set language code (e.g. using the HTTP ``Accept-Language`` header) + is in this list, Django-Select2 will use the language code to create load + the proper translation. + + The full path for the language file consists of:: + + from django.utils import translations + + full_path = "{i18n_path}/{language_code}.js".format( + i18n_path=settings.DJANGO_SELECT2_I18N, + language_code=translations.get_language(), + ) + + ``settings.DJANGO_SELECT2_I18N`` refers to :attr:`.I18N_PATH`. + """ + class Meta: """Prefix for all Django-Select2 settings.""" diff --git a/django_select2/forms.py b/django_select2/forms.py index 3627f9fb..d592ea4c 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -58,6 +58,7 @@ from django.forms.models import ModelChoiceIterator from django.utils.encoding import force_text from django.utils.six.moves.cPickle import PicklingError as cPicklingError +from django.utils.translation import get_language from .cache import cache from .conf import settings @@ -112,8 +113,10 @@ def _get_media(self): .. Note:: For more information visit https://docs.djangoproject.com/en/1.8/topics/forms/media/#media-as-a-dynamic-property """ + i18n_file = '%s/%s.js' % (settings.SELECT2_I18N_PATH, get_language()) + i18n_file = (i18n_file,) if get_language() in settings.SELECT2_I18N_AVAILABLE_LANGUAGES else () return forms.Media( - js=(settings.SELECT2_JS, 'django_select2/django_select2.js'), + js=(settings.SELECT2_JS,) + i18n_file + ('django_select2/django_select2.js',), css={'screen': (settings.SELECT2_CSS,)} ) diff --git a/tests/test_forms.py b/tests/test_forms.py index 11014446..1012094b 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -8,6 +8,7 @@ import pytest from django.core import signing from django.db.models import QuerySet +from django.utils import translation from django.utils.encoding import force_text from django.utils.six import text_type from selenium.common.exceptions import NoSuchElementException @@ -103,6 +104,27 @@ def test_empty_option(self, db): assert multiple_select.widget.allow_multiple_selected assert '' not in multiple_select.widget.render('featured_artists', None) + def test_i18n(self): + translation.activate('de') + assert Select2Widget().media._js == [ + '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js', + '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/i18n/de.js', + 'django_select2/django_select2.js' + ] + + translation.activate('en') + assert Select2Widget().media._js == [ + '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js', + '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/i18n/en.js', + 'django_select2/django_select2.js' + ] + + translation.activate('00') + assert Select2Widget().media._js == [ + '//cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js', + 'django_select2/django_select2.js' + ] + class TestSelect2MixinSettings(object): def test_default_media(self): diff --git a/tests/testapp/settings.py b/tests/testapp/settings.py index f3be9acb..c1b3a8c7 100644 --- a/tests/testapp/settings.py +++ b/tests/testapp/settings.py @@ -33,6 +33,11 @@ SITE_ID = 1 ROOT_URLCONF = 'tests.testapp.urls' +LANGUAGES = [ + ('de', 'German'), + ('en', 'English'), +] + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', @@ -44,6 +49,7 @@ SECRET_KEY = '123456' USE_L10N = True +USE_I18N = True if os.environ.get('TRAVIS'): CACHES = {