0

我们想使用 Flask-Babel 来实现 Flask 应用程序的国际化。

我们的目标是为 msgid 使用像“example_demo_text”这样的唯一 ID 字符串,并将这个 msgid 翻译成多种语言。我们的流程是这样工作的:在 gettext(..) 函数中使用唯一的 msgid“example_demo_text”,提取所有 gettext 消息并将关联的消息字符串 (msgstr) 写入默认语言环境 (en) 的 .po 文件中。

到目前为止,整个过程都有效......

当请求希望消息字符串采用受支持的语言,但尚未完全翻译(可悲的是经常发生)并且此语言环境中的 msgstr 为空时,flask-babel 返回 msgid,该 msgid 不应显示给用户。

如果请求的语言环境中的 msgstr 为空,我们如何配置 flask-babel 以使用回退本地(在我们的例子中为 en)?

以下是我们在烧瓶应用程序中实现烧瓶 babel 的方式:
main.py

import ...

supported_locales = ("de", "en", "es", "fr", "hr", "it", "nl")

app = Flask(__name__)
app.register_blueprint(demos, url_prefix="/demos")
babel = Babel(app, configure_jinja=False, default_locale="en")


@babel.localeselector
def get_locale():
    user_local = RequestHeader(request).get_user_local()

    if user_local not in supported_locales:
        user_local = current_app.config["BABEL_DEFAULT_LOCALE"]

    return user_local

RequestHeader()只是一个处理我们的标头的类,具有获取用户区域设置的方法,该方法由我们的身份验证代理作为标头提供。)

我们的示例路由文件 demos.py:

import ...

demos = Blueprint("demos", __name__)

@demos.route("/translation-demo")
def demo_translation():

    first_translation = gettext("example_demo_text")
    second_translation = gettext("example_demo_text_param")
    third_translation = gettext("example_demo_text_paramtime")

    return {"message1": first_translation, "message2": second_translation, "message3": third_translation}

/en/messages.po

#: rest/demos/demos.py:121
msgid "example_demo_text"
msgstr "I am an english text, which can be translated"

#: rest/demos/demos.py:122
msgid "example_demo_text_param"
msgstr "I am an english text with parameters: Today's date is ..."

#: rest/demos/demos.py:123
msgid "example_demo_text_paramtime"
msgstr "The time this request was received is ..."

(例如example_demo_text/de/message.po 中 msgid 的 msgstr 为空,flask-babel 应返回 en 的 msgstr。)

4

1 回答 1

0

我想我找到了答案。

Flask-Babel 不支持我们希望的翻译方法。我们用来翻译的方式迫使我们使用文本字符串作为消息 ID (msgid) 而不是 id-strings。尽管有一些方法可以让它使用 id-strings 作为 msgid,但这些方法都不适合我们的标准翻译行为。

第一种方法是使用 id-strings 作为 msgid 并将文本字符串直接写入提取的 .po 文件中。这里的问题是 Flask-Babel 在请求的语言 .po 文件中搜索消息字符串 (msgstr)。如果此特定 msgid 没有 msgstr,它将使用 msgid 的字符串作为后备。所以,这种情况只有在我们每次发布前将每种语言都翻译到 100% 时才可用,这对我们来说是不现实的。否则,用户会得到一个乱码字符串作为响应。从 Babel 的代码库中检查这个问题。

于 2022-01-10T09:13:51.550 回答