Wagtail snippets vertalen

Django en Wagtail bieden uitstekende vertaalmogelijkheden. Als we echter modelfragmenten (snippets) maken in onze editor, is vertaling minder voor de hand liggend. Deze tutorial toont een manier om dit te omzeilen.

12 juli 2020 08:47
Thema's: Meerdere talen

Tekst in modellen, weergaven, formulieren en templates kan worden vertaald met Django's vertaalopties. De inhoud van Wagtail-pagina's kan op andere manieren worden vertaald. Snippets in Wagtail zijn dat ook niet, dus we moeten een manier vinden om tekst te vertalen die we aan snippets toevoegen in onze editor. In eerdere tutorials hebben we snippets gebruikt, bij het definiëren van thema's of bij het maken van een menu. Voor het vertalen van pagina's hebben we vertrouwd op wagtailtrans; het zou mooi zijn als we dit pakket ook voor snippets zouden kunnen gebruiken. Hoewel daarover gedacht wordt, is dit nog niet mogelijk.

Een oplossing zou zijn om de trans-templatetag in onze template te gebruiken, b.v. {% trans item.title%}, waarbij item een ​​snippet-instantie is. Het nadeel is dat Django's hulpprogramma makemessages voor het vertalen van woorden en zinnen deze variabelen niet zal detecteren, zoals vermeld in de Django-documentatie. Dat betekent dat elke keer dat een dergelijk bestand wordt gegenereerd, handmatig alle mogelijke waarden van alle variabelen in het vertaalbestand ingevoerd moeten worden. Dit is duidelijk niet optimaal.

Onze aanpak zal zijn om het pakket django-modeltranslation te gebruiken. Ik moet vermelden dat er een nadeel is: het vertalen van de modelvelden moet gebeuren in Django admin. We zouden dit natuurlijk liever in Wagtail admin hebben. Het gerelateerde pakket wagtail-modeltranslation heeft Wagtail admin-integratie, maar vertaalt standaard Wagtail's Page-model, dat veel onnodige velden toevoegt, en er is geen gemakkelijke manier om dit te voorkomen. Forken en een simpele switch hiervoor toevoegen is een optie, maar heeft ook nadelen. Dus voor nu gaan we door met django-modeltranslation:

pip3 install django-modeltranslation

en voegen het toe onze requirements.txt en zetten modeltranslation in onze INSTALLED_APPS. In sommige configuraties (inclusief de mijne) werkt het alleen als je dit vóór django.contrib.admin plaatst, dus dat is wat we zullen doen. Controleer of USE_I18N = True in je instellingen en dat LANGUAGES de talen definieert die je nodig hebt. Maak nu een bestand translation.py aan in je app en voeg de modellen toe die je wilt vertalen, in ons geval:

from modeltranslation.translator import register, TranslationOptions
from .models import Theme, MenuItem, Menu

@register(Theme)
class ThemeTranslationOptions(TranslationOptions):
    fields = ('name',)

@register(MenuItem)
class MenuItemTranslationOptions(TranslationOptions):
    fields = ('link_title',)

@register(Menu)
class MenuTranslationOptions(TranslationOptions):
    fields = ('title',)

We moeten deze modellen toevoegen aan admin, zodat ze daar kunnen worden bewerkt. We zullen onze menu-items organiseren als inlines van onze menu's:

from .models import Theme, MenuItem, Menu
from django.contrib import admin
from modeltranslation.admin import TranslationAdmin, TranslationTabularInline

class ThemeAdmin(TranslationAdmin):
    model = Theme

class MenuItemInline(TranslationTabularInline):
    model = MenuItem

class MenuAdmin(TranslationAdmin):
    model = Menu
    inlines = [MenuItemInline,]

admin.site.register(Theme, ThemeAdmin)
admin.site.register(Menu, MenuAdmin)

Nu migreren we de database. Dit voegt extra velden toe voor elke taal en voor elk veld gespecificeerd in translation.py. Nadat we dat hebben gedaan, werken we de database bij met behulp van het commando update_translation_fields:

python3 manage.py update_translation_fields

Nu zijn we klaar om Django-admin te bezoeken en onze snippets te bekijken, er vertalingen aan toe te voegen of zelfs nieuwe items toe te voegen.

Als je geïnteresseerd bent om een taalschakelaar in je navigatie te bouwen, lees dan verder.

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