Privacy Policy
Snippets index

  Django language switching

file "settings.py"

MIDDLEWARE_CLASSES = [
    ...
    'django.middleware.locale.LocaleMiddleware',
]

file "urls.py"

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

file "base.html"

{% load i18n %}

{% block extrastyle %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap-select.min.css' %}" media="all">
    ...

{% block extrajs %}
    <script type="text/javascript" src="{% static 'js/bootstrap-select.min.js' %}"></script>
    ...


<div class="header-content">

    <form action="{% url 'set_language' %}" method="post">
        {% csrf_token %}
        <input name="next" type="hidden" value="/" />

        <select class="selectpicker" name="language" style="width: auto;" onchange="this.form.submit()">
          {% get_current_language as LANGUAGE_CODE %}
          {% get_available_languages as LANGUAGES %}
          {% get_language_info_list for LANGUAGES as languages %}
          {% for language in languages %}

              <option
                value="{{ language.code }}"
                {% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}
                data-content='<img src="/static/images/flags/{{ language.code }}.gif"></span>
                <span style="display:inline-block; width:100px; padding-left: 10px; text-shadow:none">
                  {{ language.name_local }}
                  <!-- span style="color:#999;">&nbsp;[{{ language.code }}]</span -->
                </span>'>
                {{ language.code }}
              </option>

          {% endfor %}
        </select>
    </form>

</div>

Here we'se using bootstrap-select to display flags inside language select widget.

Flag icons can be downloaded from:

http://www.famfamfam.com/lab/icons/flags/

Embed language switcher in Bootstrap navbar (show only flag)

<div id="navbar" class="navbar-collapse collapse">
  <ul class="nav navbar-nav navbar-right">

    ...

    {% get_current_language as LANGUAGE_CODE %}
    {% get_available_languages as LANGUAGES %}
    {% get_language_info_list for LANGUAGES as languages %}
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown"><img src="/static/img/flags/{{LANGUAGE_CODE}}.png">&nbsp;<span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu" id="language-list">
        {% for language in languages %}
            <li>
              <a href="{% url 'set_language' %}" data-language-code="{{ language.code }}">
                {% if language.code == LANGUAGE_CODE %}&#10003;{% else %}&nbsp;&nbsp;{% endif %}
                <img src="/static/img/flags/{{ language.code }}.png">
                {{ language.name_local }}
              </a>
            </li>
        {% endfor %}
      </ul>
    </li>

    ...
  </ul>
</div>

then:

$('#language-list a').on('click', function(event) {
    event.preventDefault();
    var target = $(event.target);
    var url = target.attr('href');
    var language_code = target.data('language-code');
    $.ajax({
        type: 'POST',
        url: url,
        data: {language: language_code},
        headers: {"X-CSRFToken": getCookie('csrftoken')}
    }).done(function(data, textStatus, jqXHR) {
        reload_page();
    });
});

where:

function getCookie(name) {
    var value = '; ' + document.cookie,
        parts = value.split('; ' + name + '=');
    if (parts.length == 2) return parts.pop().split(';').shift();
}

function reload_page() {
    window.location.reload(true);
}

Embed language switcher in Bootstrap navbar (show language select)

This examples uses https://github.com/snapappointments/bootstrap-select to include flag images in the select widget:

<div id="navbar" class="navbar-collapse collapse">
  <ul class="nav navbar-nav navbar-right">
    ...

    <li class="dropdown" id="language-switcher">
        <form action="{% url 'set_language' %}" method="post">
            {% csrf_token %}
            <input name="next" type="hidden" value="/" />

            <select class="selectpicker" name="language" style="width: auto;" onchange="this.form.submit()">
              {% get_current_language as LANGUAGE_CODE %}
              {% get_available_languages as LANGUAGES %}
              {% get_language_info_list for LANGUAGES as languages %}
              {% for language in languages %}

                  <option
                    value="{{ language.code }}"
                    {% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}
                    data-content='<img src="/static/img/flags/{{ language.code }}.png">
                    <span style="display:inline-block; width:100px; padding-left: 10px; text-shadow:none">
                      {{ language.name_local }}
                      <!-- span style="color:#999;">&nbsp;[{{ language.code }}]</span -->
                    </span>'>
                    {{ language.code }}
                  </option>

              {% endfor %}
            </select>
        </form>
    </li>

    ...
  </ul>
</div>
#language-switcher .bootstrap-select {
    width: 120px;
    margin-top: 10px;
    margin-left: 8px;
}

#language-switcher .bootstrap-select button {
    padding-top: 3px;
    padding-bottom: 3px;
}

Alternative using emoji flags

Requirements:

pip install emoji-country-flag

File navbar.html:

{% load static i18n languages_helpers %}

<style>

    #language-switcher select {
        width: auto;
        background-color: transparent;
        font-size: 28px;
        border: 0px solid;

        /*remove arrow*/
        -webkit-appearance: none;
        -moz-appearance: none;
        text-indent: 1px;
        text-overflow: '';

        /*remove focus border*/
        outline: none;
    }

</style>

...

<!-- navbar buttons-->
<div class="navbar-btns">
    <div class="navbar-btns-inner">

        <div id="language-switcher" class="navbar-btn collapsed">
            <form action="{% url 'set_language' %}" method="post">
                {% csrf_token %}
                <input name="next" type="hidden" value="/" />
                <select name="language" onchange="this.form.submit()">
                    {% for language in request|get_language_info_list_ex %}
                        <option value="{{ language.code }}" {% if language.is_current %} selected="selected"{% endif %}>
                            <span class="flag">{{ language.flag }}</span>
                            {# {{ language.code }} #}
                        </option>
                    {% endfor %}
                </select>
            </form>
        </div>

where:

file frontend/templatetags/languages_helpers.py:

from django import template
from django.utils import translation
from django.conf import settings
import flag


register = template.Library()


@register.filter
def get_language_info_list_ex(request):
    """
    Sample result:

        [{'bidi': False,
        'code': 'en',
        'flag': '🇬🇧',
        'is_current': False,
        'name': 'English',
        'name_local': 'English',
        'name_translated': 'Inglese'},
        {'bidi': False,
        'code': 'it',
        'flag': '🇮🇹',
        'is_current': True,
        'name': 'Italian',
        'name_local': 'italiano',
        'name_translated': 'Italiano'},
        {'bidi': False,
        'code': 'es',
        'flag': '🇪🇸',
        'is_current': False,
        'name': 'Spanish',
        'name_local': 'español',
        'name_translated': 'Spagnolo'}]
    """
    data = []


    # From django.templatetags.i18n.GetLanguageInfoListNode
    def get_language_info(language):
        # ``language`` is either a language code string or a sequence
        # with the language code as its first item
        if len(language[0]) > 1:
            return translation.get_language_info(language[0])
        else:
            return translation.get_language_info(str(language))

    flag_map = {
        'en': 'gb',
    }

    # Es: 'es'
    current_language = translation.get_language()

    # Es: [('en', 'Inglés'), ('it', 'Italiano'), ('es', 'Español')]
    #languages = [(k, translation.gettext(v)) for k, v in settings.LANGUAGES]
    for language in settings.LANGUAGES:
        # Es: {'bidi': False, 'code': 'es', 'name': 'Spanish', 'name_local': 'español', 'name_translated': 'Español'}
        info = get_language_info(language)

        code = info['code']
        info['is_current'] = (code == current_language)

        # This requires emoji-country-flag Python package
        info['flag'] = flag.flag(flag_map.get(code, code))
        data.append(info)

    return data