Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django site with 2 languages

I want to develop a site with 2 languages, a default one, my native language and an optional English. I plan to have my domains as such:

www.mydomain.com/tr/ www.mydomain.com/en/ 

By default, once a user enter mydomain.com. they will be redirected to /tr/ version and select to go to the /en/ if they want via a top menu. And here is my question.

What is the best Django way to maintain both languages, please note that I don't want automatic translation but I want to maintain texts for both languages myself.

Thanks

like image 861
Hellnar Avatar asked Apr 23 '12 12:04

Hellnar


People also ask

How does Django implement multi language?

You have to add {% load i18n %} at the top of the HTML file to use the translation templates tags. The {% trans %} template tag allows you to mark a literal for translation. Django simply executes the gettext function on the given text internally.

Can a website have multiple languages?

A multilingual website is any website that offers content in more than one language. For example, a Canadian business with English and French versions of its site. Google Search tries to find pages that match the language of the searcher.

How can I add two languages to my website?

Google Translate It is by far the easiest and more common way to add multiple language support to your website. To add Google Translate to your site, you simply sign up for an account and then paste a small bit of code to the HTML.


2 Answers

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!

like image 150
radtek Avatar answered Nov 11 '22 21:11

radtek


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> 
like image 21
jdotjdot Avatar answered Nov 11 '22 21:11

jdotjdot