如果请求的语言环境中的 msgstr 为空,让 Flask-Babel 使用默认语言环境的 msgstr

Let Flask-Babel use default locale's msgstr if the msgstr in the requested locale is empty

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

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

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

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

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

以下是我们在 Flask 应用程序中实现 flask-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() 只是一个 class 来处理我们的 headers,用一个方法来获取用户区域设置,这是由我们的授权提供的 header代理。)

我们的示例路由文件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 ..."

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

我想我找到了答案。

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

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