DEV Community

DoriDoro
DoriDoro

Posted on

Adding translation to Django Portfolio project

Introduction

To make your Django project accessible in multiple languages (German, French, and English), you need to internationalize (i18n) your project. This involves translating your templates and views, among other parts of your project. Here's a step-by-step guide to get you started:

Step 1: Enable Internationalization in Django

  1. Edit your settings.py: Make sure the following settings are configured:
# settings.py

LANGUAGE_CODE = "en-us"
TIME_ZONE = 'Europe/Paris'
USE_I18N = True
USE_L10N = True
USE_TZ = True
LANGUAGES = [
    ("en", _("English")),
    ("de", _("German")),
    ("fr", _("French")),
]
LOCALE_PATHS = [
    os.path.join(BASE_DIR, 'locale'),
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",  # add here
    "django.middleware.common.CommonMiddleware",
    ...
]
Enter fullscreen mode Exit fullscreen mode

LANGUAGE_CODE

  • LANGUAGE_CODE sets the default language of your Django project. When set to 'en-us', it means that the default language for your project is American English.
  • This setting is used for the initial language of the site before any language preference is determined by the user or by the middleware.

TIME_ZONE

  • TIME_ZONE sets the default time zone for your Django project. When set to 'Europe/Paris', it means that all date and time operations will be based on the Paris time zone by default.
  • This setting is particularly useful if your primary audience or your server is located in a specific time zone different from your language preference.

USE_I18N, USE_L10N and USE_TZ

  • USE_I18N = True and USE_L10N = True: These enable internationalization and localization support in Django.
  • USE_TZ = True: This enables timezone-aware datetimes.
  1. Install the gettext utility: Ensure you have gettext installed on your system. This utility helps with creating and managing translation files.

Step 2: Mark Strings for Translation

  1. Templates: Use the {% trans %} template tag to mark strings for translation in your HTML files.
   <h1>{% trans "Welcome to my portfolio" %}</h1>
Enter fullscreen mode Exit fullscreen mode
  1. Views and Other Python Code: Use the gettext function in your views and other Python files.
   from django.utils.translation import gettext as _

   def my_view(request):
       message = _("Welcome to my portfolio")
       return render(request, 'my_template.html', {'message': message})
Enter fullscreen mode Exit fullscreen mode

Step 3: Create Translation Files

  1. Generate .po files: Run the following command to extract strings marked for translation and generate .po files.
   django-admin makemessages -l de
   django-admin makemessages -l fr
Enter fullscreen mode Exit fullscreen mode

This will create django.po files in the locale/de/LC_MESSAGES/ and locale/fr/LC_MESSAGES/ directories.

  1. Translate .po files: Open the .po files and add your translations. For example, in locale/de/LC_MESSAGES/django.po:
   msgid "Welcome to my portfolio"
   msgstr "Willkommen auf meiner Portfolio Webseite"
Enter fullscreen mode Exit fullscreen mode

Do the same for French in locale/fr/LC_MESSAGES/django.po.

Step 4: Compile Translation Files

  1. Compile .po files to .mo files: After translating the .po files, you need to compile them into .mo files which Django uses at runtime.
   django-admin compilemessages
Enter fullscreen mode Exit fullscreen mode

Step 5: Use Locale Middleware to Detect Language

  1. Configure URL patterns (optional): If you want to use URL patterns to switch languages, you can add them to your urls.py:
# portfolio/urls.py

from django.conf import settings
from django.conf.urls.i18n import i18n_patterns
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
]

urlpatterns += i18n_patterns(
    path("portfolio/", include("projects.urls", namespace="projects")),
    prefix_default_language=False
)  # this is important

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Enter fullscreen mode Exit fullscreen mode
  1. Add a language switcher: To let users switch languages, you can create a language switcher in your templates:
# index.html

   <form action="{% url 'set_language' %}" method="post">
       {% csrf_token %}
       <input name="next" type="hidden" value="{{ redirect_to }}">
       <select name="language">
           {% get_current_language as LANGUAGE_CODE %}
           {% get_available_languages as LANGUAGES %}
           {% for lang in LANGUAGES %}
               <option value="{{ lang.0 }}" {% if lang.0 == LANGUAGE_CODE %}selected{% endif %}>
                   {{ lang.1 }}
               </option>
           {% endfor %}
       </select>
       <button type="submit">{% trans "Change language" %}</button>
   </form>
Enter fullscreen mode Exit fullscreen mode

Step 6: Test Your Translations

  1. Run your server and test: Start your Django development server and navigate through your website. Test switching languages and ensure that the translations appear correctly.
   python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

By following these steps, you'll be able to translate your Django project into German, French, and English, making it accessible to a wider audience.

Top comments (1)

Collapse
 
cof profile image
cof • Edited

Thanks for detailed guidance.

Just small information I had an issue following your guide on step 1 that I solved with official documentation: docs.djangoproject.com/en/5.1/topi...

If you define a custom LANGUAGES settings,... ...you can mark the language names as translation strings – but use gettext_lazy() instead of gettext() to avoid a circular import.
Here’s a sample settings file:
from django.utils.translation import gettext_lazy as _
LANGUAGES = [
('de', _('German')),
('en', _('English')),
]

Also, in html templates, seems is required at the beginning, the i18n line:
{% load i18n %}