Multilingual support¶
This package supports creating content in multiple languages. This feature is based on django-parler. Historical anecdote: django-parler was created to make this CMS multilingual.
The enable multiple languages, configuring django-parler is sufficient.
Configuration¶
LANGUAGES = (
('en', _("Global Site")),
('en-us', _("US Site")),
('it', _('Italian')),
('nl', _('Dutch')),
('fr', _('French')),
('es', _('Spanish')),
)
PARLER_DEFAULT_LANGUAGE_CODE = 'en' # defaults to LANGUAGE_CODE
SITE_ID = None
PARLER_LANGUAGES = {
None: (
# Default SITE_ID, all languages
{'code': lang[0]} for lang in LANGUAGES
),
2: (
# SITE_ID 2: only english/french
{'code': 'en',}
{'code': 'fr',}
),
'default': {
# This is applied to each entry in this setting:
'hide_untranslated': False,
'hide_untranslated_menu_items': False,
# 'fallback': 'en' # set by PARLER_DEFAULT_LANGUAGE_CODE
}
}
There are two extra values that can be used:
hide_untranslated
: if set toTrue
, untranslated pages are not accessible.hide_untranslated_menu_items
: is set toTrue
, untranslated pages are not visible in the menu.
These values can be used in the “default” section, or in each dictionary entry per site.
Accessing content¶
There are several ways to expose translated content.
One way is adding a subpath in the URL by using i18n_patterns()
:
Using i18n_patterns¶
Add the following to settings.py
:
MIDDLEWARE_CLASSES += (
'django.middleware.locale.LocaleMiddleware', # or your own override/replacement
)
Add to urls.py
:
from django.conf.urls import patterns, url
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from fluent_pages.sitemaps import PageSitemap
sitemaps = {
# Place sitemaps here
'pages': PageSitemap,
}
admin.autodiscover()
urlpatterns = patterns('',
# All URLs that should not be prefixed with the country code,
# e.g. robots.txt or django admin.
) + i18n_patterns('',
# All URLS inside the i18n_patterns() get prefixed with the country code:
# Django admin
url(r'^admin/', admin.site.urls),
# SEO API's per language
url(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
# CMS modules
url(r'', include('fluent_pages.urls')),
)
Using custom middleware¶
Nothing prevents you from writing custom middleware that sets the frontend language. For example:
Add the following to settings.py
:
LANGUAGE_CODE = 'en' # default, e.g. for the admin
FRONTEND_LANGUAGE_CODE = 'de'
MIDDLEWARE_CLASSES += (
'mysite.middleware.FrontendLanguageMiddleware',
)
The custom middleware code:
from django.conf import settings
from django.utils import translation
from django.urls import reverse_lazy
class FrontendLanguageMiddleware(object):
"""
Change the active language when visiting a frontend page.
"""
def __init__(self):
# NOTE: not locale aware, assuming the admin stays at a single URL.
self._admin_prefix = reverse_lazy('admin:index', prefix='/')
def process_request(self, request):
if request.path_info.startswith(str(self._admin_prefix)):
return # Excluding the admin
if settings.FRONTEND_LANGUAGE_CODE != settings.LANGUAGE_CODE:
translation.activate(settings.FRONTEND_LANGUAGE_CODE)
This could even include detecting the sub-domain, and setting the language accordingly.
All queries that run afterwards read the active language setting, and display the content is the given language.
You can take this further and make Django aware of the sub-domain in it’s URLs by
overriding ABSOLUTE_URL_OVERRIDES
in the settings.
The Page
provides a default_url
attribute for this specific use-case.
You’ll also have to override the sitemap, as it won’t take absolute URLs into account.