Django

Code

Ticket #7072 (closed: fixed)

Opened 5 months ago

Last modified 2 months ago

i18n gets active language inconsistently

Reported by: akaihola Assigned to: nobody
Milestone: 1.0 Component: Internationalization
Version: SVN Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

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.

Attachments

7072_i18n_context_processor_fix.diff (0.7 kB) - added by akaihola on 04/23/08 10:34:56.
patch for retrieving active language from get_language() instead of request.LANGUAGE_CODE in the i18n context processor

Change History

04/23/08 10:34:56 changed by akaihola

  • attachment 7072_i18n_context_processor_fix.diff added.

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

04/23/08 10:41:06 changed by akaihola

  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

A note about the patch:

The request.LANGUAGE_CODE -> settings.LANGUAGE_CODE fallback should work correctly also with the patched code, since translation.get_language() does the fallback internally.

06/14/08 07:01:47 changed by Simon Greenhill

  • has_patch set to 1.
  • stage changed from Unreviewed to Ready for checkin.

06/18/08 16:48:53 changed by telenieko

  • summary changed from i18n context processor misses post-middleware changes to active language to i18n gets active language inconsistently.
  • milestone set to 1.0.

Seems to be a bug, so marking for 1.0

07/06/08 00:25:55 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

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

Analysis and patch from akaihola.


Add/Change #7072 (i18n gets active language inconsistently)




Change Properties
Action