Welcome to django-robust-i18n-urls’s documentation!¶
Contents:
Rationale¶
django-robust-i18n-urls: is a Django application providing sane defaul behavior for internationalized urls.
The problem¶
For the case of this discussion let’s assume your urlpatterns
variable
contains a pattern like:
url(_(r'^hello/'), my_view, name='my_view')
If the pattern ^hello/
gets translated into Spanish ^ola/
the expected
behavior would be for the controller to be accessible using both urls.
Unfortunately this is not the case with Django. Urls get resolved in a
context of a single locale. This way, if a user with Accept-Language
header
set to en tries to access /ola/, he will be shown an error 404 page.
The solution¶
django-robust-i18n-urls
provides a middleware that, facing a response with status_code
set to 404
will try to resolve the url again in context of all currently installed
languages. In case of a first successful match, it will be returned instead
of the error, and a matched language will be set as default for current user’s
session.
Some other minor issues can arise when dealing with i18n urls, an this library deals with some of them. The default workings of these helpers is detailed in Details section.
Tutorial¶
Installing¶
You can install the most recent version directly from pypi:
pip install django-robust-i18n-urls
For development¶
If you want to develop the application yourself (or just like living on the bleeding edge) just checkout the code:
git checkout https://github.com/karolmajta/django-robust-i18n-urls.git
Install it as a code drop:
pip install -e .
Install development requirements (this will fetch Sphinx and Mock):
pip install -r requirements.txt
To run tests issue:
python setup.py test
Configuring¶
To make sure your users won’t get 404 responses when using urls for locales
other than reported by their browser just modify your MIDDLEWARE_CLASSES
setting, by adding robust_urls.middleware.RobustI18nLocaleMiddleware
.
If you plan on providing users with an url for changing their current language
just inlcude in your urls.py
:
import robust_urls.urls
# ...
urlpatterns += patterns(url(r'/i18n/', include(robust_urls.urls)))
Details¶
While django-robust-i18n-urls does not expose any particular APIs to end users (it’s designed as a plug&play app) it won’t hurt to know what is going on under the hood.
robust_urls.urls¶
This module contains urlpatterns variable that can be used as a drop-in replacement for urplatterns contained in django.conf.urls.i18n.
robust_urls.views¶
This module contains a single view that is used to change locale of current user, and can be used as a drop-in replacement for set_language view from django.views.i18n.set_language
set_language¶
set_language view works in a fasion similar to Django’s original one. The key differences are:
- It does not allow GET requests, they will result in a 405 response. Only POST method is allowed.
- If a URL path specified in request.REQUEST[‘next’] can be matched against a specific view, instead of issuing an immediate redirect, the set_language will first reverse the match to obtain a request path in language of user’s choosing.
- If a URL path specified in request.REQUEST[‘next’] cannot be matched to any view, a redirection will be issued to it anyway.
robust_urls.middleware¶
This module containse the RobustI18nLocaleMiddleware that, next to robust_urls.view.set_language is the app’s main component.
RobustI18nLocaleMiddleware¶
This middleware’s process_response method will touch only responses with status_code 404. It will try to match the URL using languages in order specified in LANGUAGES setting. If a match is not found, the response is returned unchanged. If a match is found, the result of rendering the view’s response is returned instead. This method also takes care to set proper (matched) locale in user’s session or language cookie.
robust_urls.utils¶
locale_context¶
This context manager will execute given block making sure that language provided as argument is active during execution. On exit will call translation.deactivate.
with locale_context('pl_PL'):
print _('Good Morning') # will print 'Dzień Dobry'
Warning! `locale_context` calls `transaction.deactivate` so it is ill suited for use inside views. In future versions it will probably hold to a locale used before the manager was endered, and activate it on exit instead of calling `transaction.deactivate`. This api will change!
try_uri_for_language¶
A simple helper that takes path, language and resolver arguments. Will try to resolve path using resolver, in context of given language. If no match is found will return None instead of raising an exception. If match is found will return whatever resolver returns (ResolverMatch instance).