Modellen, views en templates vertalen in meerdere talen

Django biedt uitstekende ondersteuning voor meertalige sites. In deze tutorial laten we zien hoe je templates in meerdere talen vertaalt. We zullen ons richten op het vertalen van tekst die zich ergens in model, formulieren, views of templates bevindt. Meertalige sites hebben uiteraard ook pagina-inhoud (artikelen etc.) in meerdere talen; dit is het onderwerp van een andere tutorial.

8 juli 2020 08:05
Thema's: Meerdere talen

Het eerste om te doen, is Django via de instellingen vertellen dat we meerdere talen zullen gebruiken. Stel Engels is de primaire taal is en we willen ook Frans en Nederlands; voeg dan het volgende toe aan de instellingen (of controleer dat het er is):

LANGUAGE_CODE = 'en'

USE_I18N = True

LANGUAGES = [
    ('en', 'English'),
    ('fr', 'Français'),
    ('nl', 'Nederlands'),
]

Ook LocaleMiddleware moet toegevoegd worden. Voeg het toe aan de MIDDLEWARE-parameter, na SessionMiddleware en CacheMiddleware (indien aanwezig) en vóór CommonMiddleware:

'django.middleware.locale.LocaleMiddleware',

Nu gebruiken we het i18n-systeem voor het maken van verschillende urls voor verschillende talen, door de i18n_patterns-functie toe te voegen aan uw project urls.py-bestand vóór alle geïncludeerde URL's die we in meerdere talen willen hebben. In eerdere tutorials hebben we bijvoorbeeld URL's opgenomen voor een authenticatie-app; als we willen dat deze beschikbaar zijn in meerdere talen, dan plaatsen we het volgende in onze urls.py:

urlpatterns += i18n_patterns(
    path('accounts/', include('allauth.urls')),
    path('accounts/', include('userauth.urls')),
)

Opmerking: als je ook Wagtail gebruikt, plaats de Wagtail-URL's dan niet in de functie i18n_patterns; we zullen vertaalde Wagtail-pagina's op een andere manier behandelen. Bekijk het urls.py-bestand op Github.

Je kunt controleren of de voorvoegsels werken door naar een URL in het project te gaan met het opgegeven voorvoegsel. Laten we zeggen dat we een url /accounts/login/ hebben, ga dan naar /fr/accounts/login/, en dit zou de template moeten weergeven. De template is natuurlijk nog steeds in het Engels; Django doet dat niet voor ons, dus laten we dit zelf gaan doen. Maak een map met de naam locale in de projectdirectory en vertel Django dit door het volgende toe te voegen aan je instellingen:

LOCALE_PATHS = (os.path.join(BASE_DIR, 'locale'),)

Nu zijn we klaar om Django's makemessages opdracht te gebruiken. Deze opdracht gebruikt de gettext-toolset, dus je moet deze op je computer hebben geïnstalleerd. Voer dan het volgende commando uit:

django-admin makemessages -l fr

of welke taal je ook wilt vertalen. Alle tekenreeksen die zijn gemarkeerd voor vertaling in modellen, formulieren, views, templates enz., worden vervolgens gevonden en vermeld in een tekstbestand met de .po-extensie in de locale-directory. Het .po-bestand genereert ook tekenreeksen voor applicaties die je hebt geïnstalleerd, in ons geval allauth. Je kunt dat voorkomen door de vlag -i (negeren) te gebruiken om bestanden uit de env-map uit te sluiten:

django-admin makemessages -l fr -i env

Tekenreeksen markeren voor vertaling gebeurt op twee manieren. Gebruik in je .py-bestanden (modellen, formulieren, weergaven etc.) gettext of gettext_lazy. Gebruik in templates {% trans %} of {% blocktrans %}. In onze vorige tutorials hebben we beide consequent gedaan voor alle 'voor mensen leesbare teksten'.

Alle tekenreeksen in het .po-bestand moeten handmatig vertaald worden. Stel dat bijvoorbeeld op regel 11 in ons bestand models.py van onze userauth-app de tekenreeks "Date of Birth" staat, dan zou een passage in het .po-bestand zijn:

#: userauth/models.py:11
msgid "Date of Birth"
msgstr ""

Het toevoegen van de Franse vertaling zou dit veranderen in:

#: userauth/models.py:11
msgid "Date of Birth"
msgstr "Date de naissance"

Als een string te lang is, zal Django deze op de volgende manier splitsen:

#: userauth/templates/userauth/account/email_confirm.html:17
msgid ""
"Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail "
"address for user %(user_display)s."
msgstr ""

Onze msgstr-vertaling zou dan luiden:

msgstr ""
"Veuillez confirmer que <a href=\"mailto:%(email)s\">%(email)s</a> est une adresse "
"e-mail pour l'utilisateur %(user_display)s."

Kopieer, zoals in dit voorbeeld, alles wat niet tekst is letterlijk, zoals html-tags en variabele-namen. Als Django niet zeker is, zal het een regel toevoegen met het woord fuzzy, zodat je zelf kunt beoordelen hoe je daarmee om moet gaan. Als alle vertalingen klaar zijn, zijn we klaar om de .po-bestanden te compileren:

django-admin compilemessages --locale fr

Opmerking: wanneer je je aanmeldt met een sociaal account, moet je de callback-URL's toevoegen met de taalvoorvoegsels, anders kan de aanbieder van het sociale account de pagina niet vinden.

Na het inloggen worden we doorverwezen naar de profielpagina /accounts/profile/, maar deze URL heeft geen prefix, dus komen we op deze pagina terecht in de standaardtaal, wat niet is wat we willen. Om dit te herstellen, plaats het volgende in het instellingenbestand; dit vertaalt de urls via urls.py inclusief taalcode:

from django.urls import reverse_lazy

LOGIN_URL = reverse_lazy('account_login')
LOGIN_REDIRECT_URL = reverse_lazy('account_profile')

Telkens wanneer nieuwe tekenreeksen worden toegevoegd aan de .py- of .html-bestanden of bestaande tekenreeksen worden gewijzigd, voer dan de opdracht makemessages opnieuw uit, bewerk de .po-bestanden en voer de opdracht compilemessages opnieuw uit.

Zoals eerder vermeld, lees verder als je ook de inhoud van je webpagina's wilt vertalen.

Reageer op dit artikel (log eerst in of bevestig hieronder met naam en email)