Django site with 2 languages

You could use translatable URL patterns, which are available since 1.4.

https://docs.djangoproject.com/en/dev/topics/i18n/translation/#url-internationalization


So here is the long version to your question. Tested on Django 1.4 thru 1.7.1:

In settings.py …

Add to MIDDLEWARE_CLASSES, locale, it enables language selection based on request:

'django.middleware.locale.LocaleMiddleware',

Add LOCALE_PATHS, this is where your translation files will be stored:

LOCALE_PATHS = (
    os.path.join(PROJECT_PATH, 'locale/'),
)

Enable i18N

USE_I18N = True

Set LANGUAGES that you will be translating the site to:

ugettext = lambda s: s
LANGUAGES = (
    ('en', ugettext('English')),
    ('pl', ugettext('Polish')),
)

Add i18n template context processor, requests will now include LANGUAGES and LANGUAGE_CODE:

For Django <1.8 put it here:

TEMPLATE_CONTEXT_PROCESSORS = (
    ....
    'django.core.context_processors.i18n', # this one
)

For Django >= 1.8 put it here:

TEMPLATES = [
    {
        'OPTIONS':
            {'context_processors': [
                'django.template.context_processors.i18n',  # this one
            ]}
    }
]

Nest, in urls.py :

In url_patterns, add the below, it will enable the set language redirect view:

url(r'^i18n/', include('django.conf.urls.i18n')),

See Miscellaneous in Translations for more on this.

Add the following imports, and encapsulate the urls you want translated with i18n_patterns. Here is what mine looks like:

from django.conf.urls.i18n import i18n_patterns
from django.utils.translation import ugettext_lazy as _

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    url(r'^i18n/', include('django.conf.urls.i18n')),
)

urlpatterns += i18n_patterns('',
    (_(r'^dual-lang/'), include('duallang.urls')),
    (r'^', include('home.urls')),
)

Note: You can also drop your admin urls into the i18n_patterns.

Wrap your text with lazytext! import lazytext (as above) and wrap every string with it like so _('text'), you can even go to your other urls.py files and do url translation like so:

url(_(r'^dual_language/$'), landing, name='duallang_landing'),

You can wrap text that you want translated in your other files, such as models.py, views.py etc.. Here is an example model field with translations for label and help_text:

name = models.CharField(_('name'), max_length=255, unique=True, help_text=_("Name of the FAQ Topic"))

Django translation docs are great for this!

In your html templates...

Now you can go into your templates and load the i18n templatetag and use trans and transblock on the static stuff you want to translate. Here is an example:

{% load i18n %}

{% trans "This is a translation" %}<br><br>
{% blocktrans with book_t='book title'|title author_t='an author'|title %}
This is {{ book_t }} by {{ author_t }}. Block trans is powerful!
{% endblocktrans %}

Now run a makemessages for each of your locales:

./manage.py makemessages -l pl

And now all is left is to go into your /locales folder, and edit each of the .po files. Fill in the data for each msgstr. Here is one such example of that:

msgid "English"
msgstr "Angielski"

And finally compile the messages:

./manage.py compilemessages

There is a lot more to learn with translations and internationalization is closely related to this topic, so check out the docs for it too. I also recommend checking out some of the internationalization packages available for Django like django-rosetta, and django-linguo. They help translate model content, django-rosetta does not create new entries for this in your database, while django-linguo does.

I also created a django translation demo for those interested to look at a full working solution.

If you followed this you should be off to a good start. I believe this is the most standardized way to get your site running in multiple languages. Cheers!


As I see it, you have two main options here:

(1) You can keep two separate copies of the site as different Django apps and simply have your urlconf point to those apps-- so url(r'^/en/', include(myproject.en)) would be in your urlconf to point to your English app, and the other for the other language. This would involve maintaining different sets of urlconfs and different html templates, etc for the two apps, which could be useful if you're interested in having the URLs themselves also reflect the different languages (eg Spanish "/pagina/uno" vs English "/page/one").

(2) You record the language preference in a cookie (which you should really do anyway) using Django sessions, and then have the template deliver the appropriate version of the text however you like from that cookie. The code for this could be:

# views.py

# default to your native language
request.session['lang'] = 'tr'

# someone clicks the link to change to English
def switch_to_English_link(request):
    request.session['lang'] = 'en'

And then in the templates, to gather this information, you'd use:

<!-- my_django_template.html -->
<div>
  <span>
     {% if request.session.lang == "en" %}
        This is my text in English!
     {% else %}
        Şimdi benim sitede Türk var!
     {% endif %}
  </span>
</div>