django-internationalization
Description
A Django app used for translation and localization
Features
- Mixed translation system using both the gettext utility and database entries
- Easy to use translation file exporting and importing
Technologies Used
Installation
-
You need GNU text tools v0.15 or newer installed for the app to function successfully. You can find it here
-
Create your Django project and set up your virtual environment.
Install virtualenv
User guide
-
Install the app.
pip install django_internationalization
- Add your app to the INSTALLED_APPS in your settings file.
INSTALLED_APPS = [
...,
'django_internationalization'
]
- Add the locale middleware.
MIDDLEWARE = [
...,
'django.middleware.locale.LocaleMiddleware',
...,
]
- Set your default LANGUAGE_CODE and LANGUAGES variables.
LANGUAGE_CODE = 'en-US'
LANGUAGES = (
("en-US", "English"),
("bg", "Bulgarian"),
...
)
You can also import the LANGUAGES or LANGUAGES_LOCAL variable and assign it in your settings. LANGUAGES contains the language names in English, while LANGUAGES_LOCAL contains the language names in their local scripts.
from django_internationalization.config import LANGUAGES_LOCAL
...
LANGUAGE_CODE = 'en-US'
LANGUAGES = LANGUAGES_LOCAL
- Set your LOCALE_PATHS using the app's _LOCALE_PATHS variable
from django_internationalization.apps import _LOCALE_PATHS
...
LOCALE_PATHS = _LOCALE_PATHS
- Include the app urls to your project's urls.
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('django_internationalization.urls'))
]
- Put the following js and css files in the
head
tag of your main template:
<script src="https://code.jquery.com/jquery-3.7.1.slim.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<link rel="stylesheet" href="{% static 'django_internationalization/css/master.css' %}">
<script src="{% static 'django_internationalization/js/master.js' %}"></script>
- In your console, go to your project folder and use the deploy-translation-module command
cd your_project_name
py manage.py deploy-translation-module
Usage
The Language model
The Language model has two important boolean values - active and live.
active shows if the language is activated for the project, but should not yet be seen by the end users. Existing translations are created for that language based on existing ones on activation. Deactivating a language does not delete already existing translations.
live should be used when the language is ready to be presented to the end users. It gets shown in the language selector.
The general workflow should be activating a language, creating or updating the translations for it and finally setting it live.
Language Selector
The language selector is a form that displays the available live languages and switches the website language.
Usage
To use it, you need to follow the steps below:
- Pass the form in your view.
from django_internationalization.forms import LanguageSelector
class MyViwe(View):
def get(self, request, *args, **kwargs):
context = {}
context['language_selector'] = LanguageSelector()
return render(request, 'your_template.html', context)
- Include the template inside your own template.
{% include 'ecom_django_translations/language-selector.html' with form=language_selector %}
- If you have less than two languages set to live, the form will not be displayed.
Form parameters
The form has a few parameters that can be changed.
open_on_hover (bool) and open_on_click (bool) can be toggled and are set to True by default. They dictate how the submenu is opened.
style sets the class of the form. This is used mainly for switching between different UI styles.
Adding new languages to the project
To add a new language that does not exist, you need to append it to LANGUAGE_DATA inside the Language model.
You can do this by creating your ows Language model that inherits the original.
from django_internationalization.models import Language
from django.utils.translation import gettext_lazy
class MyLanguage(Language):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.LANGUAGE_DATA['your_language_code'] = {"name": gettext_lazy("Name in English"), "name_local": "Name in local script", "country": "CC"}
The country value should be one of the country codes in the django_internationalization/config/LIST_OF_COUNTRIES tuple
In your console, run makemessages and compilemessages:
py manage.py makemessages -l your_language_code
py manage.py compilemessages -l your_language_code
Translations
Adding translations to your models
If you want to have different language versions of an entry for your model, you can set the specific field as a foreign key
from django.db import models
from django_internationalization.models import Translation
class MyModel(models.Model):
content = models.ForeignKey('Translation', on_delete=models.CASCADE, related_name='translations', null=True, blank=True)
Downloading translation files
You can download translation files using TranslationFilesDownloadForm. It gathers both the Translation model entries and the contents of the gettext .po files.
- Pass the form in your view.
from django_internationalization.forms import TranslationFilesDownloadForm
class MyViwe(View):
def get(self, request, *args, **kwargs):
context = {}
context['translation_download_form'] = TranslationFilesDownloadForm()
return render(request, 'your_template.html', context)
- Include the template inside your own template.
{% include 'ecom_django_translations/translation-download.html' with form=translation_download_form %}
-
The Translation model currently exports both .xls. and ..xlsx. files, however currently only the latter is used.
-
The "Include system translations" toggle controls if the gettext .po files should be included into the exported file.
Uploading a translation file
You can upload translation files (one by one) using TranslationFilesUploadForm.
- Pass the form in your view.
from django_internationalization.forms import TranslationFilesUploadForm
class MyViwe(View):
def get(self, request, *args, **kwargs):
context = {}
context['translation_upload_form'] = TranslationFilesUploadForm()
return render(request, 'your_template.html', context)
- Include the template inside your own template.
{% include 'ecom_django_translations/translation-upload.html' with form=translation_upload_form %}
Showing translated conted in your templates
-
You still need to manualy query for the translations in your database that use the Translation model. This can be done in a variety of ways, depending on your specific use case.
-
If the Translation model content needs to display html, don't forget to add the 'safe' filter in the template that you're using.
{% your_html_translation|safe %}
Manually changing the website language
If you don't want to use the Language Selector, you can still change the website language by using the set_language utility function. The best use case here is including the function in the dispatch method of a View base class that's being used for all of your other views.
from django.views import View
from django_internationalization.utilities import set_language
class MyBaseView(View):
def dispatch(self, request, *args, **kwargs):
set_language(request, 'en-US')
return super().dispatch(request, *args, **kwargs)
class SomePageView(MyBaseView):
def get(self, *args, **kwargs):
context = {}
'''Do stuff'''
return render(request, 'my_template.html', context)
Other
Using the Django messages utility
Some of the forms have a set action pointing to a specific view, so we can't use form cleaning methods. This is why we've opted in for using django/contrib/messages for form errors. To see the messages, you need to:
- Make sure you have 'django.contrib.messages' in your INSTALLED_APPS
INSTALLED_APPS = [
...
'django.contrib.messages',
...
]
- Put the following snippet in your main template
{% if messages %}
<div class="messages">
{% for message in messages %}
<p class="{{message.tags}}">{{message}}</p>
{% endfor %}
</div>
{% endif %}
License
Mozilla Public License Version 2.0