Here you will learn how to create a multilingual website using Django LiveView.
We using subdomains to define the language (en.example.com
, es.example.com
...), instead of using prefixes in addresses (example.com/en/blog/
, example.com/es/blog/
). They simplify SEO, maintain consistency in the Sitemap and are easy to test.
We will use the following structure:
example.com
anden.example.com
for English.es.example.com
for Spanish.
1. Configure the subdomains
In your settings.py
file, add all domains that will be used.
ALLOWED_HOSTS = ["example.com", "en.example.com", "es.example.com"]
2. Configure the languages
And add or modify the following settings in the same file (settings.py
).
# Languages
# Enable internationalization
USE_I18N = True
# Default language
LANGUAGE_CODE = "en"
# Available languages
LANGUAGES = [
("en", _("English")),
("es", _("Spanish")),
]
# Locale paths
LOCALE_PATHS = (BASE_DIR / "locale/",)
3. Redirection with Middleware
Create a middleware that redirects the user to the correct subdomain and sets the language. If the user enters en.example.com
or example.com
, English language will be activated. If the user enters es.example.com
, Spanish language will be activated. And if the user enters en.example.com
, it will be redirected to example.com
.
Create a file called middlewares.py
in your project folder and add the following code.
from django.utils import translation
from django.conf import settings
from django.utils.translation import get_language
from django.http import HttpResponseRedirect
def language_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
# Set the language based on the domain
# Example:
# "example.com" and "en.example.com" -> en
# "es.example.com" -> es
# Get the domain from the request
domain = request.META["HTTP_HOST"]
# Get the subdomain
domain_list = domain.split(".")
subdomain = domain_list[0] if len(domain_list) == 3 else None
# Set the language
if get_language() != subdomain:
translation.activate(subdomain)
# Redirect default language to main domain
# Example: "en.example.com" -> "example.com"
if subdomain == settings.LANGUAGE_CODE:
return HttpResponseRedirect("http://example.com")
response = get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
return middleware
Now, add the middleware to the MIDDLEWARE
list in settings.py
.
MIDDLEWARE = [
...
"middlewares.language_middleware",
]
4. Set multilingual texts
In any of your HTML templates, you can use translation tags to display multilingual texts.
{% load i18n %}
<h1>{% trans "Hello" %}</h1>
<p>{% blocktrans %}This is a multilingual website.{% endblocktrans %}</p>
For titles and descriptions, you can use the meta
dictionary in the action with _("text")
to translate the texts.
from liveview.context_processors import get_global_context
from django.conf import settings
from liveview.utils import (
get_html,
update_active_nav,
enable_lang,
loading,
)
from django.utils.translation import gettext as _
from django.templatetags.static import static
from django.urls import reverse
...
context.update(
{
"url": settings.DOMAIN_URL + reverse("home"),
"title": _("Home") + " | Home",
"meta": {
"description": _("Home page of the website"),
},
}
)
...
For the url of the page, you can edit the urls.py
file to include the language.
from django.urls import path
from django.utils.translation import gettext as _
from .views import home
urlpatterns = [
path(_("home") + "/", home, name="home"),
path(_("about") + "/", about, name="about"),
]
5. Make messages
Create the locale
folder in the root of your project and run the following commands.
./manage.py makemessages -l en
./manage.py makemessages -l es
The files locale/en/LC_MESSAGES/django.po
and locale/es/LC_MESSAGES/django.po
will be created. You can edit them with a text editor or use a translation tool like Poedit.
6. Compile messages
After translating the texts, compile the messages.
./manage.py compilemessages
Your multilingual website is ready. You can test it by entering example.com
, en.example.com
and es.example.com
.
7. Selector of languages
You can create a selector of languages in the header of your website.
{% load i18n %}
{% get_current_language as CURRENT_LANGUAGE %}
{% get_available_languages as AVAILABLE_LANGUAGES %}
<ul>
{# Display the current language #}
<li>
<a href="#" disabled>{{ CURRENT_LANGUAGE }}</a>
</li>
{# Display the other languages #}
{% for language in AVAILABLE_LANGUAGES %}
{% if language.0 != CURRENT_LANGUAGE %}
<li>
<a href="http{% if request.is_secure %}s{% endif %}://{{ language.0 }}.{{ DOMAIN }}">
{{ language.0 }}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
The above code will create a list of languages with the current language disabled.
Or also simple links with the subdomain.
<a href="http://en.example.com">
English
</a>
<a href="http://es.example.com">
Español
</a>
{% endfor %}