angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Het toevoegen van url_for() links naar Jinja sjablonen van een Flask meertalige website

In een meertalige website met meertalige slakken kunnen we geen gebruik meer maken van <a href="{{ url_for('pages.about') }}">{{{ _('Over') }}</a>.

15 september 2019
post main image
unsplash.com/@andrewtneel
Voordat je verder leest, wil je misschien eerst mijn eerdere berichten over meertaligheid en taalfasen lezen, zie onderstaande links. Toen ik mezelf de opdracht gaf om een meertalige Flask website te ontwikkelen en te implementeren wist SQLAlchemy ik dat het moeilijk zou kunnen worden. Ik heb niet echt de tijd genomen om alles van te voren te ontwerpen, ik heb alleen maar veel gelezen over meertaligheid op het internet en vertrouwde op mijn ervaring om te ontwerpen terwijl ik code schreef die zonder al te veel moeite kon worden uitgebreid. Toch kun je je soms zo betrokken raken bij het aan de praat krijgen van de code dat je eenvoudige dingen vergeet.

Het probleem: url_for() in Jinja sjablonen

In de pagina blueprint views.py had ik de eindpunten voor het contact, over, de gebruiksvoorwaarden en de privacy policy pagina gedefinieerd:
@pages_blueprint.route('/contact')
def contact():
    return page_view('contact')


@pages_blueprint.route('/about')
def about():
    return page_view('about')

@pages_blueprint.route('/terms-of-use')
def terms_of_use():
    return page_view('terms-of-use')


@pages_blueprint.route('/privacy-policy')
def privacy_policy():
    return page_view('privacy-policy')

Ik heb deze regels verwijderd zodat het enige overgebleven eindpunt voor pagina's de page_view functie zou zijn:

@pages_blueprint.route('/<slug>', methods=['GET', 'POST'])
def page_view(slug):
    ...

Toen stopte de pagina's met werken .... natuurlijk. Op sommige plaatsen in de templates heb ik nog steeds url_for() gebruikt om de link naar een pagina te genereren. Zo werd bijvoorbeeld de 'Lees meer' nog steeds als volgt gespecificeerd:

<a href="{{ url_for('pages.about') }}">{{ _('Read more') }}</a>

En op de Registreer pagina stond de link:

* {{ _('See our') }} <a href="{{ url_for('pages.privacy_policy') }}" class="link">{{ _('privacy policy') }}</a> {{ _('how we process and protect your personal data.') }}

Beiden faalden met de beroemde:

werkzeug.routing.BuildError: Could not build url for endpoint ...

Niets bijzonders en ja, het werd verwacht, maar hoe lost u dit op en belangrijker nog, hoe lost u dit op een meertalige manier op?

De oplossing: een genesteld dictaat voor elke gekozen taal

De oplossing is niet erg moeilijk. Zoals ik in eerdere posten al zei, hebben we twee tabellen:

Inhoud Item
InhoudItemItemItemVertaling van de inhoudItemTranslation

ContentItem bevat een 'gewone' naam. De Over-pagina heeft bijvoorbeeld een gemeenschappelijke naam 'Over' en vervolgens bevat de ContentItemTranslation records de vertaalde paginatitel, voor de Nederlandse taal is dit 'Over ons' en de afgeleide slak is 'over-ons'. Om de juiste gegevens aan de url_for() functie te kunnen leveren, moeten we een woordenboek maken met de volgende structuur:

{
    'About': { 'title': title, 'slug': slug },
    'Privacy policy': { 'title': title, 'slug': slug },
    ... 
}

Dan hebben we de context processor nodig om dit woordenboek in het sjabloon te krijgen, hier gebruik ik app_template_slug als de naam van het woordenboek. In de Jinja template kunnen we dit op de volgende manier gebruiken:

* {{ _('See our') }} <a href="{{ url_for('pages.page_view', slug=app_template_slug['Privacy policy']['slug']) }}" class="link">{{ app_template_slug['Privacy policy']['title'] }}</a> {{ _('how we process and protect your personal data.') }}

We gebruiken de 'gewone' naam om de juiste titel en slak te krijgen, dus hier is niets afhankelijk van de taal. Net als bij andere functionaliteiten heb ik het object gemaakt dat zich bezighoudt met het genereren van het geneste woordenboek in de create_app functie.

Links / credits

Multilanguage fallback revisited and a page footer with multilanguage links
/en/blog/multilanguage-fallback-revisited-and-a-page-footer-with-multilanguage-links

Refining multilanguage: adding language fallback as an option
/en/blog/refining-multilanguage-adding-language-fallback-as-an-option

Laat een reactie achter

Reageer anoniem of log in om commentaar te geven.

Opmerkingen

Laat een antwoord achter

Antwoord anoniem of log in om te antwoorden.