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