Static content with django-multilingual flatpages

While working on a multilingual Django project I encountered the need to have pseudo-static pages, e.g. an about page or FAQ page, translated into multiple languages. In my earlier post I wrote about how to use the i18n tag library in templates to handle translations, and although this approach would work for static pages too it would not be a perfect fit.

Django comes bundled with the flatpages application, which rather cleverly hooks into the 404 errors generated by Django when it cannot find a page and maps the requested URL to a database list. If there’s an entry for the requested URL, it shows the page stored in the database for that URL instead of the 404 page.

The bundled flatpages application has no inherent multi-language support, and I was pretty close to adapting it for my needs before Google came to the rescue. Obviously, this had already been done by someone, and it’s distributed as a part of the django-multilingual module, which is a generic module for having translated fields in Django models. Here’s what I did to get it up and running, based on the steps described on the project wiki.

Step 1 — install django-multilingual
Check out the Subversion trunk for the project as described in the wiki, and make the checked out module available for Python somehow. I just copied the multilingual sub-folder to my project folder as if it were my own application.

Step 2 — edit settings.py
Add the list of languages you want to support to settings.py, and mark English as the default language (through its tuple index). The LANGUAGES setting is actually already defined in global_settings.py, but I don’t want to support all those languages so I override it.

LANGUAGES = (
    ('en', 'English'),
    ('sv', 'Swedish'),
)
DEFAULT_LANGUAGE = 1

Add the multilingual context processor to TEMPLATE_CONTEXT_PROCESSORS. This setting is not included by default in your settings.py file, but the first four core processors below are set as default in the global settings (for reference, see here and here):

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'multilingual.context_processors.multilingual',
)

Add the middleware classes in the order listed below to support language detection and for the actual mapping of 404s to flatpages to be triggered. Curiously, the FlatpageFallbackMiddleware is not mentioned in the official installation instructions, but you can deduce that it’s needed by its mentioning in the original flatpage documentation and, of course, the fact that nothing happens without it.

MIDDLEWARE_CLASSES = (
    ...
    'django.middleware.locale.LocaleMiddleware',
    'multilingual.middleware.DefaultLanguageMiddleware',
    'multilingual.flatpages.middleware.FlatpageFallbackMiddleware',
)

Add admin and the multilingual apps to INSTALLED_APPS:

INSTALLED_APPS = (
    ...
    'django.contrib.admin',
    'multilingual',
    'multilingual.flatpages',
)

Step 3 — activate admin in urls.py
Uncomment the three lines needed to activate admin in urls.py.

Step 4 — sync database
Create all database tables needed for admin and flatpages:

python manage.py syncdb

Step 5 — create template
Create a ./flatpages/ sub-folder in your template-root directory, and create a default.html template in it. This is the default template used for displaying the flatpages, but it can be overridden in admin (see the next step). Its context is populated by a flatpage variable with two fields: title and content. An example template is available here.

Step 6 — create pages in admin
Go to the flatpages section in your admin application (/admin/flatpages/multilingualflatpage/) and create all the pages and translations you want to serve using the flatpages application.

Step 7 — done!
We’re done! As before, you can test your work by modifying LANGUAGE_CODE in settings.py or changing the preferred-languages setting in your web browser.

Advertisements

6 responses to “Static content with django-multilingual flatpages

  1. Wow, thanks, exactly what I was looking for. Great write up.

  2. devdoodles

    Thank you, I’m glad you liked it!

  3. I just tried the aforementioned multilingual flatpages but I run into a problem and I don’t know if it’s me or the system is made to have a unique URL? I mean in the multilingual flatpage admin I can create a new flatpage with a URL of my choice and then I can enter title and content in different languages but there’s only one possible URL when I need a different URL for every language (say like ‘about us’ and its various tranlsations).

    I just wanted to check that you had the same setup to make sure I didn’t miss a setting or two… thanks!

  4. devdoodles

    You’re right that the flatpages URLs are independent of language. For example, an about page will have the URL /about/ regardless of whether it’s shown in English, French, or some other language. When using the LocaleMiddleware, Django detects which language to show the content for based on the language preferences set in the user’s web browser (which are sent to the server in the Accept-Language http header). You can try changing this yourself in Firefox by editing the language list in the Tools->Options->Content->Languages menu.

    Having different URLs for different languages will likely become a bit complicated, depending on your requirements. I have not tried to do this in Django so I have no good advice, but I would recommend that you think twice about whether it’s truly needed. Modifying flatpages for language-dependent URLs might be doable, but what about your dynamic pages? Maybe you can have a look at some of the Django content management systems out there to see if they support this.

  5. Thanks for the quick reply. I agree that different URLs for different languages will lead to a quite complex setup and I still have to find an advantage. My customer seems to see it more like a complete language integration for a seamless user experience and they also think Google will index the site better this way. I can understand their point of view, especialy about the user experience, a spanish reader having to go to ‘about’ won’t really feel home. I will keep looking at the features of various projects to see what they are up to and if I find something interesting I’ll come back here.

  6. About having different URLs for different languages…
    Address bar HAVE to be used JUST for type primary domains and sometimes secondary, like google.com. Other things have to be specialized in web pages.