thoughtherder

multilingual site w/ django

A brief tutorial on how I setup a multilingual website using django. Be forewarned, this is a pretty rough draft. I will hopefully get some time to go over it. If you have any questions, contact me.

This tutorial is for translating your site based on the url you are accessing. In other words, /en/ for English, /fr/ for French, or /language_code/ for any language of your choice. However, most of the following is applicable for use with the proper state change by post method of translating the site.

I'll assume that you've got python / django up and running on your system and we can just begin with a django-admin.py startproject my_multi_site.

There's a few things that need to be setup in your settings.py file. Open that up and under LANGUAGE_CODE that should be defaulted to 'en-us', add these lines:

_ = lambda s: s

LANGUAGES = (
    ('en', _('English')),
    ('fr', _('Français')),
)

We've defined a dummy function for the language strings as suggested in the internationalization docs. You can obviously set any languages you'll need, just make sure that the language you want as your default comes first in the list.

The one stumper here is that I've added a UTF-8 character ( ç in Français ) in the settings file, which it complains about. Be sure to save the file w/ UTF-8 encoding. For those of you using Vim, like me, I was able to do this by adding # vim: set fileencoding=utf-8 : at the top of my file ( # vim: set encoding=utf-8 : seems to work on another system ). I went through this trouble, rather that just writing French, because I use the LANGUAGES list on my homepage and in the admin, and I want to use that spelling.

Next, make sure USE_I18N = True which it should be by default. You'll also need the context processor django.core.context_processors.i18n which, again, is there by default. Actually, by default, TEMPLATE_CONTEXT_PROCESSORS is missing from your settings.py file, meaning that you'd have to go out of your way to remove i18n support.

The last piece in the settings.py, for now, is to add django.middleware.locale.LocaleMiddleware to your MIDDLEWARE_CLASSES.

At this point in the docs, the suggestion is to add (r'^i18n/', include('django.conf.urls.i18n')), to your urls, and then you can post a form to /i18n/setlang/ with a 'language' var containing the language code you want to set and a 'next' var to where the page should redirect. Properly, you should only change the state of your site with a post. However, I would like to set the site language based on the url. In other words, /en/ for English, /fr/ for French.

Because this behaviour is frowned upon, we'll have to collect a django snippet to get it done. This snippet makes reference to an unknown CULTURES setting so I hacked it up to use the LANGUAGES we defined above. You can get the code at github. Place that package on your PYTHONPATH and add the middleware to your settings file. It should look something like i18nmiddleware.i18n.I18nUrlsMiddleware, following directory.file.class.

Now, you'll probably have noticed in the i18n.py file you downloaded above, that there's a section to be lifted in it for your urls. It should look like url(r'(?P<dj_culture>[\w-]+)/', direct_to_template, {'template' : 'intro.html'}, name="intro"),. Be sure to put your admin url string above that. If you create an intro.html template and place links in it to /en/ and /fr/, you should be able to alter your language by accessing those urls. You can expose {{ LANGUAGE_CODE }} in your template to see if its working.

We can now try a few translations. First, in your template, place {% load i18n %}. The template tag to wrap words to translate looks like this: {% trans "translate this text" %}. Scatter a few of those around your page and then jump back onto the command line. In order to create the .po file that django uses for the translations, I had to install gettext. I'm running Mac OS X, and for my package installer, I use homebrew. So, a quick brew install gettext got that going. Now, you'll need to create .po files for each language ( not the default, en ) specified in your settings file. You can break things down by project, app, or all of django if you're using a language not yet supported by django. Since django is already translated into French, I just ran this command from the root of my project django-admin.py makemessages -l fr. The "fr" being the language code for French. It asks that you create a directory called "locale" beforehand. This goes through all the .html files in your project and creates a .po file for you to enter your translations. The .po files lives in locale/fr/LC_MESSAGES/. Once you've entered all your translations in the .po file, compile it with django-admin.py compliemessages. You can always reexamine your files for any changes with django-admin.py makemessages -a. Now, refreshing your site with the above language switcher should translate your pages.

If everything's working, we can move on to your models.




blog comments powered by Disqus