diff --git a/django/conf/urls/i18n.py b/django/conf/urls/i18n.py new file mode 100644 index 0000000000..00e2d6017b --- /dev/null +++ b/django/conf/urls/i18n.py @@ -0,0 +1,5 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('', + (r'^setlang/$', 'django.views.i18n.set_language'), +) diff --git a/django/core/template/defaulttags.py b/django/core/template/defaulttags.py index 2207682154..f1ed28d4da 100644 --- a/django/core/template/defaulttags.py +++ b/django/core/template/defaulttags.py @@ -290,6 +290,16 @@ class WidthRatioNode(Node): return '' return str(int(round(ratio))) +class GetAvailableLanguagesNode(Node): + + def __init__(self, variable): + self.variable = variable + + def render(self, context): + from django.conf.settings import LANGUAGES + context[self.variable] = LANGUAGES + return '' + class I18NNode(Node): def __init__(self, cmd): @@ -803,6 +813,28 @@ def do_widthratio(parser, token): raise TemplateSyntaxError("widthratio final argument must be an integer") return WidthRatioNode(this_value_var, max_value_var, max_width) +def do_get_available_languages(parser, token): + """ + This will store a list of available languages + in the context. + + Usage is as follows:: + + {% get_available_languages as languages %} + {% for language in languages %} + ... + {% endfor %} + + This will just pull the LANGUAGES setting from + your setting file (or the default settings) and + put it into the named variable. + """ + + args = token.contents.split() + if len(args) != 3 or args[1] != 'as': + raise template.TemplateSyntaxError("'get_available_languages' requires 'as variable' (got %r)" % args) + return GetAvailableLanguagesNode(args[2]) + def do_i18n(parser, token): """ translate a given string with the current @@ -837,3 +869,4 @@ register_tag('now', do_now) register_tag('templatetag', do_templatetag) register_tag('widthratio', do_widthratio) register_tag('i18n', do_i18n) +register_tag('get_available_languages', do_get_available_languages) diff --git a/django/utils/translation.py b/django/utils/translation.py index 6362a5923e..e4de5a8c64 100644 --- a/django/utils/translation.py +++ b/django/utils/translation.py @@ -274,6 +274,19 @@ def ngettext(singular, plural, number): gettext_lazy = lazy(gettext, str) ngettext_lazy = lazy(ngettext, str) +def check_for_language(lang_code): + """ + This function checks wether there is a global language + file for the given language code. This is used to decide + wether a user-provided language is available. + """ + from django.conf import settings + globalpath = os.path.join(os.path.dirname(settings.__file__), 'locale') + if gettext_module.find('django', globalpath, [to_locale(lang_code)]) is not None: + return True + else: + return False + def get_language_from_request(request): """ analyze the request to find what language the user @@ -284,29 +297,14 @@ def get_language_from_request(request): from django.conf import settings globalpath = os.path.join(os.path.dirname(settings.__file__), 'locale') - if request.GET or request.POST: - lang_code = request.GET.get('django_language', None) or request.POST.get('django_language', None) - if lang_code is not None: - lang = gettext_module.find('django', globalpath, [to_locale(lang_code)]) - if lang is not None: - if hasattr(request, 'session'): - request.session['django_language'] = lang_code - else: - request.set_cookie('django_language', lang_code) - return lang_code - if hasattr(request, 'session'): lang_code = request.session.get('django_language', None) - if lang_code is not None: - lang = gettext_module.find('django', globalpath, [to_locale(lang_code)]) - if lang is not None: - return lang_code + if lang_code is not None and check_for_language(lang_code): + return lang_code lang_code = request.COOKIES.get('django_language', None) - if lang_code is not None: - lang = gettext_module.find('django', globalpath, [to_locale(lang_code)]) - if lang is not None: - return lang_code + if lang_code is not None and check_for_language(lang_code): + return lang_code accept = request.META.get('HTTP_ACCEPT_LANGUAGE', None) if accept is not None: diff --git a/django/views/i18n.py b/django/views/i18n.py new file mode 100644 index 0000000000..7bb2f00b2f --- /dev/null +++ b/django/views/i18n.py @@ -0,0 +1,22 @@ +from django.utils import httpwrappers +from django.utils.translation import check_for_language + +def set_language(request): + """ + Redirect to a given url while setting the chosen language in the + session or cookie. The url and the language code need to be + specified in the GET paramters. + """ + lang_code = request.GET['language'] + next = request.GET.get('next', None) + if not next: + next = request.META.get('HTTP_REFERER', None) + if not next: + next = '/' + response = httpwrappers.HttpResponseRedirect(next) + if check_for_language(lang_code): + if hasattr(request, 'session'): + request.session['django_language'] = lang_code + else: + response.set_cookie('django_language', lang_code) + return response