Flask,Jinja2,“$”字符上的 Babel 错误

Flask, Jinja2, Babel error on "$" character

我已将我的代码从 webapp2 迁移到 Flask。 (我在 Google App Engine 中部署我的代码)

但是,我不能再使用这个字符串:"Error: Max %1$d characters"

初始化

flask_app = Flask(__name__)
babel = Babel(flask_app, default_domain='strings')

Html 模板

<div class="...">{{ _('error_long_value') | replace('%1$d', '200') }}</div>

我知道这不是最佳用途,但我需要保留 %1$d 作为占位符。 (它与 webapp2 一起工作)

日志:

...
File ".../libs/flask/templating.py", line 135, in render_template
context, ctx.app)
File ".../libs/flask/templating.py", line 117, in _render
rv = template.render(context)
File ".../libs/jinja2/environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File ".../libs/jinja2/environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File ".../app/templates/filename.html", line 567, in top-level template code
<div class="invalid-feedback">{{ _('error_long_value') | replace('%1$d', '200') }}</div>
ValueError: unsupported format character '$' (0x24) at index 29

我已经尝试在 HTML 模板中的“_('error_long_value')”之后使用“|e”或“|safe”,删除 replace()。

很难从你的问题中判断到底发生了什么,但看起来你在 'error_long_value' 变量下的 Babel 配置中有错误消息 "Error: Max %1$d characters",你想显示 "Error: Max 200 characters" 在输出的 html 中。出于某种原因,某些东西不喜欢“$”字符。您可以将占位符更改为不包含“$”的内容。这将至少解决一个问题。至于为什么它在 webapp2 中工作,它可能是不同版本的 Babel 或 python 或者谁知道是什么。 您可以检查的另一件事是用 _('error_long_value') 调用的确切函数是 babel gettext() 吗?变量名赋值在哪里?

这是一个双重问题,因为 flask(更具体地说 jinja)在从模板解释文本和应用过滤器 and/or 上下文处理器时,它自由使用 string % something 操作。

此操作将 %1$d 文本解释为格式字符串,这是导致错误的无效字符串。所以你需要做的是替换你在模板中所做的两个操作,因为 flask 提供的操作(及其扩展,通常)很可能会因为前面提到的模数操作而导致错误。

首先,您可以直接使用 babel gettext 创建上下文处理器:

from flask_babel import gettext
#...
@app.context_processor
def my_gettext():
  return {'my_gettext': gettext}

现在文本替换过滤器:

@app.template_filter()
def my_replace(text, old, new):
  return text.replace(old, new)

有了这个,在您的模板中您将使用:

<div class="...">{{ my_gettext('error_long_value') | my_replace('%1$d', '200') }}</div>