Tuesday, 17 September 2013

Make the ``django-localeurl`` rembember your language choice.

Guidelines for making the ``django-localeurl`` to rembember the chosen language and some tips of how to embed the code parts into your django templates.

Support for storing the language in session has been recently added to the ``django-localeurl`` package. Although it's not yet a part of release, the code works pretty well. There are some things you should do, though, in order to make it work. 

Tested with Django 1.5.2 and the django-localeurl version mentioned below.

This is the path I have followed.

1. Install django-localeurl from source (bitbucket) or pick a later commit from same place.


$ pip install hg+https://bitbucket.org/carljm/django-localeurl@764caf7a412d77aca8cc929988f333ee808719e6#egg=django-localeurl


UPDATE: django-localeurl on PyPI was recently updated to the version required. Use 

$ pip install django-localeurl==2.0.1


2. Update your django settings.py as follows.


Middleware classes should look as follows (order is critical). 

Note, that django's ``SessionMiddleware`` comes as first! And ``LocaleURLMiddleware`` should come before the django's ``CommonMiddleware``!

Note, that ``LOCALEURL_USE_SESSION`` is new.


MIDDLEWARE_CLASSES = (
   'django.contrib.sessions.middleware.SessionMiddleware',
   'localeurl.middleware.LocaleURLMiddleware',
   'django.middleware.common.CommonMiddleware',
   # ... the rest
)


LOCALEURL_USE_SESSION = True


3. Example of a template for language switcher.


In any case, your code would look similar to this. If you use the `menus` package that comes with `django-cms`, it would be as follows:


a. Create a directory `menu` in your django templates directory.
b. Create a file named `language_chooser.html` in it with the following content.


{% load i18n menu_tags %}
{% get_available_languages as languages %}
<div id="language-switcher">
   {% for language in languages %}
       {% language language.0 %}
           <a href="{% page_language_url language.0 %}"{% ifequal current_language language.0 %} class="current"{% endifequal %} rel="{{ language.0 }}">{{ language.1 }}</a>
       {% endlanguage %}
   {% endfor %}
   <form action="{% url 'localeurl_change_locale' %}" method="post">
       <div>
           {% csrf_token %}
           <input type="hidden" id="id_locale" name="locale" value="" />
       </div>
   </form>
</div>


If you’re not using the `menus` package, feed the ``LANGUAGES`` from your projects’ settings.py to the template context and your code would look similar to the following:


{% load i18n %}
<div id="language-switcher">
   {% for language in LANGUAGES %}
       <a href="{# Some URL #}" rel="{{ language.0 }}">{{ language.1 }}</a>


   {% endfor %}
   <form action="{% url 'localeurl_change_locale' %}" method="post">
       <div>
           {% csrf_token %}
           <input type="hidden" id="id_locale" name="locale" value="" />
       </div>
   </form>
</div>


4. Add the following code to your JavaScript file.


$(document).ready(function() {


   // ... some other code


   // Language switcher related
   $('#language-switcher a').click(function() {
       var el = $(this);
       $('#id_locale').val(el.attr('rel'));
       $('#language-switcher form').trigger('submit');
       return false;
   });
   // END language switcher related


   // ... some other code
});


5. CSS.

You are free to apply any styles you want, but in my case it was as follows.


/* Language switcher */
#language-switcher {
   display: inline;
}
   #language-switcher form {
       display: block;
       position: absolute;
       left: -9999px;
   }

6. Finally, include your template in your master template or if you have been using the ``menus`` package, your code will remain the same (assuming you have already used the {% language_chooser %} tag in your master template).

1 comment:

  1. Thank you very much. I've spent hours trying to make this to work until I got to your post. It's a pity that such a good library doesn't have a better documentation support.

    ReplyDelete