Flask-Babel在js中本地化了字符串

jar*_*daf 5 python jinja2 babel flask

我对Python和Flask都很陌生(使用Jinja2作为模板引擎)我并不确定我是以正确的方式做到这一点.我正在使用Flask-Babel扩展来为我的Web应用程序添加i18n支持.我想从我的js代码中获取本地化字符串,例如:

var helloWorld = gettext('Hello, world');
console.log(helloWorld); //should log a localized hello world message
Run Code Online (Sandbox Code Playgroud)

为此,我配置了babel(babel.cfg):

[python: **/**.py]
[jinja2: **/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
[javascript: **/**.js]
encoding = utf-8
Run Code Online (Sandbox Code Playgroud)

它的初始化是(为简单起见省略了导入):

#main Flask app
app = Flask(__name__)

#localization
babel = Babel(app)

LANGUAGES = {
    'ca': 'Catalan',
    'en': 'English',
    'de': 'Deutsch',
    'es': 'Español',
    'fi': 'Finnish',
    'it': 'Italian'
}

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

#some more stuff...
Run Code Online (Sandbox Code Playgroud)

Babel在构建POT/PO语言文件时识别该字符串,但似乎我无法从js代码访问这些本地化字符串,因为未定义gettext函数.似乎Jinja2忽略了这一部分.

任何提示?

jar*_*daf 2

我终于找到了解决方案,尽管我不确定这是否是正确的方法。这个想法是将 javascript 代码包装在 html 模板中,该模板在渲染之前由 Jinja2 解释,并应用自定义 Jinja2 过滤器来消除一些小问题。我尝试单独保存js文件,但没有成功。

看来 gettext 函数可以这样使用:

var helloWorld = {{gettext('Hello, world')}};
Run Code Online (Sandbox Code Playgroud)

但是,没有插入引号,因此 js 解释器会抛出错误:

var helloWorld = Hello, world;
Run Code Online (Sandbox Code Playgroud)

这就是为什么我最终应用了自定义过滤器。一个工作示例如下。

你好_世界.html:

<script type="text/javascript">
   var x = {{gettext('Hello, world')|generate_string|safe}};
   console.log(x);    //logs the localized hello world message
</script>
Run Code Online (Sandbox Code Playgroud)

应用程序.py:

#Jinja2 filters
from jinja2 import evalcontextfilter, Markup

#Mind the hack! Babel does not work well within js code
@app.template_filter()
@evalcontextfilter
def generate_string(eval_ctx, localized_value):
    if localized_value is None:
        return ""
    else:
        return Markup("\"" + localized_value + "\"").unescape()
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 这仍然是推荐的解决方法还是现在有更好的方法? (2认同)