i18n gets active language inconsistently
|Reported by:||akaihola||Owned by:||nobody|
|Cc:||Triage Stage:||Ready for checkin|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
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)
Changed 7 years ago by akaihola
comment:1 Changed 7 years ago by akaihola
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
comment:2 Changed 7 years ago by Simon Greenhill
- Has patch set
- Triage Stage changed from Unreviewed to Ready for checkin
comment:3 Changed 7 years ago by telenieko
- milestone set to 1.0
- Summary changed from i18n context processor misses post-middleware changes to active language to i18n gets active language inconsistently
comment:4 Changed 7 years ago by mtredinnick
- Resolution set to fixed
- Status changed from new to closed