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

Flask mehrsprachige Verarbeitung, Umschaltung und die Ausnahme 404 Seite nicht gefunden

In diesem Beitrag besprechen wir mehrere Bedingungen bei der Verarbeitung der Sprache in der URL, mit einer Standardsprache und mit einer Liste der verfügbaren Sprachen.

13 November 2019
post main image
https://unsplash.com/@sadswim

Wie Sie Flask mehrsprachig implementieren, ist in den Dokumenten Flask beschrieben, siehe Links unten. Aber das ist nur ein Ausgangspunkt. Sie benötigen ein tieferes Verständnis des Prozesses, um Sonderfälle wie das Zurückgreifen auf eine Standardsprache, die Sprachumschaltung und die Ausnahme 404 Seite nicht gefunden zu behandeln.

Annahmen

Im weiteren Verlauf dieses Beitrags verwenden wir einen Sprachcode,'lang_code', der in der URL verfügbar ist, es ist der erste Teil der URL, z.B:

https://www.example.com/en

https://www.example.com/en/login

Wir verwenden auch Flask-Babel für die Übersetzungen. Ich verwende blueprints und registriere sie in create_app() wie folgt:

    # authentication (shared)
    from shared.blueprints.auth.views import auth_blueprint
    app.register_blueprint(auth_blueprint, url_prefix='/<lang_code>/auth')

    # pages (shared)
    from shared.blueprints.pages.views import pages_blueprint
    app.register_blueprint(pages_blueprint, url_prefix='/<lang_code>')

Wir verwenden g.lang_code als Wert für die ausgewählte Sprache. Ich verwende keine Session-Variable, um mich an die Sprache zu erinnern, sondern verlasse mich bei jeder Anfrage auf die Verfügbarkeit der Sprache.

Flask mehrsprachige Verarbeitung

Die Art und Weise, wie Flask mehrsprachig auf eine Anfrage reagiert, ist wie folgt:

Zuerst wird url_value_preprocessor() aufgerufen, um die Sprache aus dem Beispiel url. zu extrahieren:

@pages_blueprint.url_value_preprocessor
def pull_lang_code(endpoint, values):
    # pop lang_code from url and set g.lang_code
    ...
    if 'lang_code' in values:
        g.lang_code = values.pop('lang_code')

Als nächstes wird Babels locale_selector() aufgerufen, um die Übersetzungen für die Seite bereitzustellen:

@babel.localeselector
def get_locale():
    return g.get('lang_code')

Schließlich wird url_defaults() aufgerufen, bevor die Seite erstellt wird, um <lang_code> durch lang_code in den URLs zu ersetzen, Beispiel:

@pages_blueprint.url_defaults
def add_language_code(endpoint, values):
    # stuff g.lang_code in urls
    ...
    values.setdefault('lang_code', g.lang_code)

Dies ist ziemlich einfach, aber wie Sie sehen können, können Bedingungen auftreten, bei denen der Sprachcode geändert wird, nicht verfügbar oder sogar ungültig. Das Wichtigste ist, dass g.lang_code immer auf eine gültige Sprache eingestellt ist, bevor localeselector() und url_defaults() aufgerufen werden. Im Folgenden werden einige Bedingungen erläutert.

Flask Mehrsprachige Verarbeitung: Besucher wechseln in eine andere Sprache

Um in eine andere Sprache zu wechseln, können wir ein GET zur aktuellen Anforderung mit einem zusätzlichen lang_code Parameter verwenden:

<a href="{{ request.script_root  +  request.path }}?lc=en">English</a>
<a href="{{ request.script_root  +  request.path }}?lc=de">Deutsch</a>

Wir müssen die Funktionalität des url_value_preprocessor() erweitern, um den Sprachwechsel zu unterstützen. Vereinfacht sieht dieser Zusatzcode wie folgt aus:

@pages_blueprint.url_value_preprocessor
def pull_lang_code(endpoint, values):
    ...
    request_lang_code = request.args.get('lc')
    if request_lang_code:
        g.lang_code = request_lang_code
    ...

Flask Mehrsprachige Verarbeitung: Sprache fehlt in der URL und Standardsprache.

Dies ist möglicherweise kein Fehler, da Sie möchten, dass der Besucher Ihre Domain-URL eingibt und auf die Standard-Sprachenseiten umgeleitet wird. Dies kann aber auch passieren, wenn ein Besucher eine falsche URL eingibt, ein (Such-)Bot ruft eine falsche URL auf. Auch dies können wir im url_value_preprocessor() behandeln. In diesem Fall setzen wir den lang_code auf den lang_code der Standardsprache:

@pages_blueprint.url_value_preprocessor
def pull_lang_code(endpoint, values):
    ...
    if g.get('lang_code') is  None:
        g.lang_code = default_lang_code

Flask Mehrsprachige Verarbeitung: Sprache nicht eine unterstützte Sprache

Unsere Anwendung unterstützt nur eine begrenzte Anzahl von Sprachen, z.B:

    available_lang_codes = ['en', 'de']

Auch hier können wir den ungültigen Sprachfall im url_value_preprocessor() behandeln. Wenn die Sprache nicht gültig ist, setzen wir den lang_code auf den lang_code der Standardsprache:

@pages_blueprint.url_value_preprocessor
def pull_lang_code(endpoint, values):
    ...
    if 'lang_code' in values:
        lang_code = values.pop('lang_code')
        if lang_code not in available_lang_codes:
            g.lang_code = default_lang_code

Flask mehrsprachige Verarbeitung: Seite nicht gefunden (404) Fehler

Dieser hat mir einige Kopfschmerzen bereitet, es hat mich etwas Debuggen gekostet, um zu sehen, dass der Ablauf in diesem Fall anders ist. Was hier passiert, ist, dass, wenn keiner der blueprints mit der Request-URL übereinstimmt, url_value_preprocessor() NIE aufgerufen wird. Wenn Sie beispielsweise den zuvor gezeigten blueprints verwenden, ist dies eine gültige URL:

http://127.0.0.1:8000/en/auth/login

aber diese URL gibt eine 404-Ausnahme:

http://127.0.0.1:8000/en/auth/login/something

Was kann man hier tun? Die Antwort ist, diese Bedingung in der Flask @before_request zu verarbeiten. Bei einem normalen Ablauf wird before_request() nach (!) url_value_preprocessor() aufgerufen:

    @pages_blueprint.url_value_preprocessor
    def pull_lang_code(endpoint, values):
        ....

    @app.before_request
    def before_request():
        ....

Im Falle einer 404er Ausnahme wird url_value_preprocessor() NICHT aufgerufen, aber before_request() wird weiterhin aufgerufen:

    @app.before_request
    def before_request():
        ....

Normalerweise setzt url_value_preprocessor() g.lang_code auf einen Wert, einen Sprachcode. Aber auf einem 404er wird url_value_preprocessor() nicht aufgerufen und g.lang_code wird nicht gesetzt. In before_request() überprüfen wir den Wert von g.lang_code. Wenn er nicht gesetzt ist, können wir die Anfrage-URL selbst bearbeiten. Wenn der erste Teil ein gültiger Sprachcode ist, nehmen wir an, dass wir dies benötigen und setzen g.lang_code. Andernfalls setzen wir g.lang_code auf die Standardsprache. Wenn dann der 404-Handler aufgerufen wird, kann die Seite in der richtigen Sprache angezeigt werden.

Zusammenfassung

Ich habe keine Session-Variable verwendet, um die ausgewählte Sprache zu speichern, sondern mich auf die Sprache in der URL verlassen. Das funktioniert gut, wenn wir alle Arten von Bedingungen wie eine fehlende Sprache behandeln. Am wichtigsten ist es, die Sprache in g einzustellen, bevor Sie alle anderen Verarbeitungen durchführen.

Links / Impressum

Flask Series: Internationalization
https://damyanon.net/post/flask-series-internationalization/

Flask-Babel
https://pythonhosted.org/Flask-Babel/

Using URL Processors
https://flask.palletsprojects.com/en/1.1.x/patterns/urlprocessors/

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.