Opened 17 years ago

Closed 17 years ago

Last modified 13 years ago

#7072 closed (fixed)

i18n gets active language inconsistently

Reported by: Antti Kaihola Owned by: nobody
Component: Internationalization Version: dev
Severity: Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no
Pull Requests:How to create a pull request

Description

Here is a snippet from the current code for django.core.context_processors.i18n:

    if hasattr(request, 'LANGUAGE_CODE'):
        context_extras['LANGUAGE_CODE'] = request.LANGUAGE_CODE
    else:
        context_extras['LANGUAGE_CODE'] = settings.LANGUAGE_CODE
    context_extras['LANGUAGE_BIDI'] = translation.get_language_bidi()

The bi-directionality of the active language is retrieved from the translation.get_language_bidi() function, which in turn calls translation.get_language() to get the active language.

On the other hand, the language code is looked up in the request, where it was copied from a session variable by LocaleMiddleware.process_request:

        language = translation.get_language_from_request(request)
        translation.activate(language)
        request.LANGUAGE_CODE = translation.get_language()

Now, if the active language is ever changed after the middleware by calling translation.activate(some_language_code), things get out of sync:

  • the LANGUAGE_CODE context variable indicates the language resolved from the request
  • LANGUAGE_BIDI will reflect the bi-directionality of the newly set language instead
  • calling translation.get_language() will return the new language

This causes no problem if Django's default i18n mechanisms are used: whenever the language is changed, the user is re-directed back to a content page, and request.LANGUAGE_CODE == context.LANGUAGE_CODE.

But if one wants to implement the language code as part of the URL, as suggested e.g. in a h3h.net article, there's no need to re-direct when changing the language. Language selection is simply done with links pointing to a URL which contains the new language code. No session variable nor request.LANGUAGE_CODE is needed, since translation.activate() and translation.get_language() can be used instead.

A simple change to the i18n context processor would adapt Django to a multi-lingual URL scheme without backwards incompatible side effects. If the LANGUAGE_CODE template context variable is retrieved by calling get_language(), any change to the active language at the URL resolution or even view processing stage is taken into account.

Change History (6)

by Antti Kaihola, 17 years ago

patch for retrieving active language from get_language() instead of request.LANGUAGE_CODE in the i18n context processor

comment:1 by Antti Kaihola, 17 years ago

A note about the patch:

The request.LANGUAGE_CODE -> settings.LANGUAGE_CODE fallback should work correctly also with the patched code, since [source:django/trunk/django/utils/translation/trans_real.py@7206#L230 translation.get_language()] does the fallback internally.

comment:2 by Simon Greenhill, 17 years ago

Has patch: set
Triage Stage: UnreviewedReady for checkin

comment:3 by Marc Fargas, 17 years ago

milestone: 1.0
Summary: i18n context processor misses post-middleware changes to active languagei18n gets active language inconsistently

Seems to be a bug, so marking for 1.0

comment:4 by Malcolm Tredinnick, 17 years ago

Resolution: fixed
Status: newclosed

(In [7843]) Fixed #7072 -- More logical and robust language settings in the i18n context processor.

Analysis and patch from akaihola.

comment:5 by Jacob, 13 years ago

milestone: 1.0

Milestone 1.0 deleted

Note: See TracTickets for help on using tickets.
Back to Top