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

Hinzufügen von url_for()-Links zu Jinja Vorlagen einer Flask mehrsprachigen Website

In einer mehrsprachigen Website mit mehrsprachigen Slugs können wir <a href="{{ url_for('pages.about') }}">{{{ _('About') }}}</a> nicht mehr verwenden.

15 September 2019
post main image
unsplash.com/@andrewtneel
Bevor du weiterliest, solltest du vielleicht meine früheren Beiträge über Mehrsprachigkeit und Sprachrückfall lesen, siehe Links unten. Als ich mir den Auftrag gab, eine mehrsprachige Flask Website zu entwickeln und zu implementieren, SQLAlchemy wusste ich, dass es schwierig werden könnte. Ich habe mir nicht wirklich die Zeit genommen, alles vorher zu entwerfen, ich habe einfach viel über Mehrsprachigkeit im Internet gelesen und meine Erfahrung beim Schreiben von Code, der ohne großen Aufwand erweitert werden konnte, in das Design eingebracht. Dennoch kann man sich manchmal so sehr in die Arbeit mit Code einbringen, dass man einfache Dinge vergisst.

Das Problem: url_for() in Jinja Vorlagen

In den Seiten blueprint views.py hatte ich die Endpunkte für die Seite Kontakt, über, Nutzungsbedingungen und Datenschutz definiert:
@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')

Ich habe diese Zeilen entfernt, so dass der einzige verbleibende Endpunkt für Seiten die page_view-Funktion ist:

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

Dann haben die Seiten aufgehört zu funktionieren.... natürlich. An einigen Stellen in den Vorlagen habe ich noch url_for() verwendet, um den Link zu einer Seite zu generieren. So wurde beispielsweise das 'Read more' noch als:

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

Und auf der Registrierungsseite war der Link:

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

Beide scheiterten mit dem Berühmten:

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

Nichts Besonderes und ja, es wurde erwartet, aber wie kann man dies und noch wichtiger lösen, wie kann man dies mehrsprachig lösen?

Die Lösung: ein verschachteltes Diktat für jede gewählte Sprache.

Die Lösung ist nicht sehr schwierig: Wie ich bereits in früheren Beiträgen erwähnt habe, haben wir zwei Tabellen:

InhaltEintrag
InhaltEintragEintragÜbersetzung

ContentItem enthält einen'gemeinsamen' Namen. Zum Beispiel hat die Info-Seite einen gemeinsamen Namen'About' und dann enthalten die ContentItemTranslation-Datensätze den übersetzten Seitentitel, für die niederländische Sprache ist dies'Over ons' und der abgeleitete Slug ist'over-ons'. um der Funktion url_for() die richtigen Daten liefern zu können, müssen wir ein Dictionary mit der folgenden Struktur erstellen:

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

Dann brauchen wir den Kontextprozessor, um dieses Dictionary in die Vorlage zu bekommen, hier benutze ich app_template_slug als Dictionary-Namen. In der Jinja Vorlage können wir dies wie folgt verwenden:

* {{ _('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.') }}

Wir verwenden den "normalen" Namen, um den richtigen Titel und die richtige Kugel zu erhalten, also keine Sprachabhängigkeit. Wie bei anderen Funktionalitäten habe ich in der Funktion create_app das Objekt erstellt, das sich um die Generierung des verschachtelten Dictionary kümmert.

Links / Impressum

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

Einen Kommentar hinterlassen

Kommentieren Sie anonym oder melden Sie sich zum Kommentieren an.

Kommentare

Eine Antwort hinterlassen

Antworten Sie anonym oder melden Sie sich an, um zu antworten.