[PYTHON] Arbeitsnotiz, die ich i18n mit Flask App ausprobiert habe

** Hinweis: ** Dies ist nur ein Hinweis. Bitte vergib mir, auch wenn ich keine nützlichen Informationen habe.


Einführung

Ich schreibe eine Flask-App als Hobby, möchte sie aber nach Möglichkeit bei der Arbeit nützlich machen. Das Problem ist jedoch Japanisch. Englisch ist besser für die Veröffentlichung auf GitHub oder GitLab, aber die traurige Realität ist, dass Sie es nicht auf Englisch verwenden können, wenn Sie versuchen, es bei der Arbeit zu verwenden.

Also i18n. vielleicht. i18n ist eine Abkürzung für Internationalisierung (?) Wie Sie wissen. Übrigens hat mir das Hyper Nikki System gefallen, aber die offizielle Website Domain h14m.org kommt von dort, oder? (Entgleisung) Vorerst war ich immer daran interessiert, wie man i18n macht, deshalb habe ich diese Gelegenheit genutzt, um es auszuprobieren, was der Inhalt dieses Artikels ist.

Vorbereitung

Dieser Artikel basiert im Wesentlichen auf [dieser Site (Englisch)] Link-1 und [dieser Site (Japanisch, Qiita)] Link-3. Es scheint üblich zu sein (oder kann ich sagen?), [Babel] Link-2 zu verwenden, um i18n-Dinge mit Flask of Python zu tun. Wenn Sie an Babel denken, denken Menschen, die Emacs verwenden, und Menschen, die JS verwenden, möglicherweise an etwas anderes (Entgleisung). Oder besser gesagt, ich konnte Babel nicht auf das Tag schreiben, weil es verwirrend zu sein scheint ... !!

Installieren Sie zuerst Babel selbst.

% pip3 install --user Babel flask_babel

Es war so.

Versuchen Sie zuerst, wie es aussieht

[Diese Seite (Japanisch, Qiita)] Versuchen Sie, das Github-Repository von Link-3 zu klonen und auszuführen. Sprechen Sie zuerst mit Telnet, ohne an etwas zu denken.

% telnet localhost 5000
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1

HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 11
Server: Werkzeug/0.12.2 Python/3.6.1+
Date: Wed, 14 Jun 2017 11:10:09 GMT

Hello WORLDConnection closed by foreign host.

Es war ein Ingurishu. Hallo. Die Reihenfolge ist umgekehrt, aber es scheint, dass die Sprachumschaltung durch Senden von Accept-Language im http-Anforderungsheader erfolgen kann. Also bat ich diesmal alle, in ihrem Lieblingsjapanisch zurückzukehren.

% telnet localhost 5000
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
Accept-Language: ja

HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 21
Server: Werkzeug/0.12.2 Python/3.6.1+
Date: Wed, 14 Jun 2017 11:14:39 GMT

Hello World Connection vom ausländischen Host geschlossen.

Wie geplant antwortete er auf Japanisch. Ich sehe, so funktioniert es. Es scheint, dass Accept-Language auch als gewichtete Liste übergeben werden kann.

Versuchen Sie, Babel in Ihre Flask-App aufzunehmen

Machen wir jetzt den ersten Schritt in Richtung i18n-Unterstützung. Die folgende Beschreibung wurde der Flask-App hinzugefügt. [Referenzseite (Englisch)] In Link-1 ist es in "__init __. Py" geschrieben, aber welches ist besser?

app/hoge.py


app = Flask(__name__)
app.config.from_object(__name__)

from flask_babel import Babel
babel = Babel(app)

from config import LANGUAGES

@babel.localeselector
def get_locale():
    return request.accept_languages.best_match(LANGUAGES.keys())

Als nächstes habe ich die folgenden Dateien vorbereitet.

config.py


# -*- coding: utf-8 -*-
#
# available languages
LANGUAGES = {
    'en': 'English',
    'ja': 'japanisch'
}

Es scheint, dass die Verwendung des Localeselector-Dekorators wie dieser es ermöglicht, auf Accept-Language zu reagieren. Und noch etwas, es scheint, dass die Einstellungsdatei von Babel selbst auch notwendig ist, also habe ich sie wie folgt erstellt. Die erste und zweite Zeile sind die zu übersetzenden Dateien, und die dritte Zeile scheint die Erweiterung von Babel zu aktivieren. Ich habe die Details der Erweiterung nicht untersucht.

babel.cfg


[python: **.py]
[jinja2: **/templates/**.tpl.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_

Eigentlich übersetzen

Berühren Sie die Vorlage

Lassen Sie uns zuerst mit der Vorlage spielen. In diesem Fall scheint "_ ()" ein Alias für "gettext ()" zu sein, daher habe ich die Stelle, an der es auf Englisch zu "Name" wird, wie folgt geändert.

show_person.tpl.html


      <tr>
        <td>{{ _('Name') }}</td>
        <td>{{ person.name }}</td>
      </tr>

Berühren Sie den Python-Code (2017-06-17 hinzugefügt)

Beim Übersetzen einer Nachricht, die geflasht werden soll, musste ich mich mit dem Code auf der Python-Seite herumschlagen, aber ich konnte ihn wie folgt implementieren.

hoge.py


from flask import flash

from flask_babel import gettext as _

@app.route('/logout')
def logout():

    session.pop('logged_in', None)
    flash(_("You were logged out"), 'success')

    return redirect(url_for('show_hoge'))

Oben wird gettext als _ importiert, um es an der Vorlagenseite auszurichten. Wenn Sie Zahlen usw. eingeben möchten

hoge.py


        flash(_("No Such Item with ID %(item_id)d", item_id=item_id), 'error')

Es scheint gut zu sein, es als zu tun.

Erstellen Sie eine Übersetzungsdatei

Als nächstes habe ich den folgenden Befehl ausgeführt.

% pybabel extract -F babel.cfg -o message.pot hoge

Dies scheint eine Vorlagendatei zu erstellen. Betrachten Sie den Inhalt der Ausgabe message.pot

message.pot


# Translations template for PROJECT.
# Copyright (C) 2017 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2017-06-14 20:54+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.4.0\n"

#: hoge/templates/show_person.tpl.html:10
msgid "Name"
msgstr ""

Es war so. Es scheint, dass es "Name" anstelle von msgid gibt, das früher für gettext verwendet wurde. Darüber hinaus scheint es eine Übersetzungsdatei zu erstellen, die auf dieser Datei basiert. Insbesondere habe ich den folgenden Befehl gedrückt.

% pybabel init -i message.pot -d hoge/translations -l ja
creating catalog hoge/translations/ja/LC_MESSAGES/messages.po based on message.pot

Die Po-Datei schien mit Poedit Poedit, das in [Referenzseite (Englisch)] Link-1 eingeführt wurde, einfach zu erstellen zu sein. Ich habe die generierte message.po geöffnet und "Name" als "Name" eingegeben, wie unten gezeigt.

poedit.png

In der bearbeiteten Datei wurde das Aktualisierungsdatum neu geschrieben, und natürlich wurde auch msgstr neu geschrieben, und X-Generator machte eine Selbstbehauptung. Ursprünglich scheint es danach "pybabel compile" zu machen, aber bei Verwendung von Poedit scheint es, dass automatisch eine Mo-Datei erstellt wird, die beim Speichern kompiliert wird (verwenden Sie Version 1.8.11).

In diesem Zustand wurde "Name" erfolgreich durch "Name" ersetzt, als die App im Browser angezeigt wurde. Außerdem konnte ich bestätigen, dass "Name" wieder angezeigt wird, wenn die englische Priorität in den Browsereinstellungen erhöht wird.

Was ist mit nachfolgenden Updates?

Beim Aktualisieren scheint die Po-Datei wie folgt aktualisiert zu werden.

pybabel extract -F babel.cfg -o message.pot hoge
pybabel update -i message.pot -d hoge/translations

Impressionen

Wenn es um Sätze geht, scheint es ziemlich schwierig zu sein, aber ich habe den Eindruck, dass es überraschend einfach ist, wenn es um Wörter geht. Es scheint mühsam zu sein, den Befehl beim Aktualisieren zu drücken, aber gibt es einen guten Weg?

Wie auch immer, es gibt kein Problem damit, es bei der Arbeit zu verwenden oder auf GitHub zu veröffentlichen !! Nun, das größte Problem ist, dass es bedeutungslos ist, wenn die Entwicklung der Anwendung selbst nicht voranschreitet !!

Verweise

Recommended Posts

Arbeitsnotiz, die ich i18n mit Flask App ausprobiert habe
Ich habe Linebot mit Flasche (Anaconda) + Heroku ausprobiert
[Python] Ein Memo, das ich versucht habe, mit Asyncio zu beginnen
Eine Geschichte, die nicht funktioniert hat, als ich versucht habe, mich mit dem Python-Anforderungsmodul anzumelden
Ein Memo, das ich schnell in Python geschrieben habe
Ich habe versucht, Keras in TFv1.1 zu integrieren
Ich habe Flask mit Remote-Containern von VS Code ausprobiert
Ich möchte mit einem Knopf am Kolben übergehen
Ich möchte mit einem Roboter in Python arbeiten.
Ein Memo, dass ich den Datenspeicher mit Python berührt habe
Beachten Sie, dass ich mich mit HTML in Beautiful Soup befasst habe
Ich habe versucht, eine Memo-App zu erstellen, die Pomodoro sein kann, aber eine Reflexionsaufzeichnung
Ich habe fp-Wachstum mit Python versucht
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, mit Elasticsearch Ranking zu lernen!
Ich habe versucht, easydict (Memo) zu verwenden.
Ich habe versucht, mit PyCaret zu clustern
Ich habe gRPC mit Python ausprobiert
Ich habe versucht, mit Python zu kratzen
Mezzanine-Einführungsnotiz, dass ich im Fluss stecken geblieben bin
Ich habe versucht, "ein Programm, das doppelte Anweisungen in Python entfernt"
Ich habe versucht, einen Artikel mit SQL Alchemy auf Wiki.js zu erstellen
Ich habe versucht, den Datenverkehr mit WebSocket in Echtzeit zu beschreiben
Ich habe die Bewegung Python3 ausprobiert, die die Richtung im Koordinatensystem ändert
Ich habe versucht, Sätze mit summpy zusammenzufassen
[Memo] Links bei der Entwicklung mit Flask
Ich habe maschinelles Lernen mit liblinear versucht
Ich habe versucht, WebScraping mit Python.
Führen Sie die App mit Flask + Heroku aus
Ich habe versucht, Essen mit SinGAN zu bewegen
Ich habe versucht, das Bild mit OpenCV im "Skizzenstil" zu verarbeiten
Ich habe versucht, DeepPose mit PyTorch zu implementieren
Ich habe versucht, GAN in Colaboratory auszuführen
Ich habe versucht, das Gesicht mit MTCNN zu erkennen
Hallo Welt mit Flasche [Passendes Memo]
Ich habe versucht, das Bild mit OpenCV im "Bleistift-Zeichenstil" zu verarbeiten
Ich habe ein Werkzeug ausprobiert, das Gochs Muster mit KI imitiert
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
Ich habe versucht, Prolog mit Python 3.8.2 auszuführen.
Ich habe Line Benachrichtigung in Python versucht
Ich habe die SMTP-Kommunikation mit Python versucht
Ich habe versucht, Sätze mit GPT-2 zu generieren
Ich habe versucht, mich automatisch mit Selen bei Twitter anzumelden (RPA, Scraping)
Ich habe versucht, LightGBM mit Yellowbrick zu lernen
Ich habe versucht, das Gesicht mit OpenCV zu erkennen
Ich habe versucht, Deep Learning zu implementieren, das nicht nur mit NumPy tiefgreifend ist
Ich habe versucht, eine Blockchain zu implementieren, die tatsächlich mit ungefähr 170 Zeilen funktioniert
Ich habe versucht, einen Formatierer zu entwickeln, der Python-Protokolle in JSON ausgibt
Ich war festgefahren, eine Kolbenanwendung mit einem Reverse-Proxy dazwischen umzuleiten
Ich habe versucht, PLSA in Python zu implementieren
Azure-Tabellenspeicher mit PTVS Flask-App
Ich habe eine multiple Regressionsanalyse mit Polypoly-Regression versucht
Ich habe versucht, eine SMS mit Twilio zu senden
Ich habe versucht, Amazon SQS mit Django-Sellerie zu verwenden
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe versucht, Permutation in Python zu implementieren
Stellen Sie die Kolben-App mit mod_wsgi bereit (mithilfe von pipenv).