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;"> [{{ 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/
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
