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

时间:2014-03-12 15:18:28

标签: python flask jinja2 babel

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

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

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

[python: **/**.py]
[jinja2: **/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
[javascript: **/**.js]
encoding = utf-8

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

#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...

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

任何提示?

2 个答案:

答案 0 :(得分:2)

我终于找到了一个解决方案,虽然我不确定它是否可行。我们的想法是将javascript代码包装在一个html模板中,该模板在呈现之前由Jinja2解释,并应用自定义的Jinja2过滤器来消除一些小问题。我试图分开保存js文件,但它不起作用。

似乎可以像这样使用gettext函数:

var helloWorld = {{gettext('Hello, world')}};

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

var helloWorld = Hello, world;

这就是我最终应用自定义过滤器的原因。一个工作的例子如下。

hello_world.html:

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

app.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()

希望这有帮助!

答案 1 :(得分:0)

在渲染的JavaScript中提供翻译有点脆弱。另外,我通常不使用Jinja生成JavaScript,因为它使用相同类型的括号,并且在被滥用时很容易变成乱七八糟的东西(总是可能有动态数据和静态JavaScript)。

另一种轻量级方法是执行相同的JSON技巧,但使用数据属性:

<div id="view-i18n" data-i18n='{{ view_i18n|tojson }}'> ... </div>

(注意:单引号!)

但是对于数量有限的翻译也有好处。

也许,最可靠的方法是在JavaScript中进行与Flask应用中相同的翻译。

借助名为pojson的实用程序,可以在构建过程中将po文件转换为json(例如,参见https://github.com/ZeWaren/flask-i18n-example)(例如,在制作{ {1}}个文件)。通过在mo的输出之前加上pojson,可以轻松地将翻译添加到一些足够独特的全局命名空间变量中。或将var some_unique_name =下的文件放入特定于语言环境的文件(例如staticstatic/view-es.json等)中,并通过ajax调用来获取它。

尽管有些事情要考虑。如果您确实想缩小JSON的大小,则可能需要通过控制babel提取选项将翻译域分为单独的Python和Javascript。同样,使用Javascript转换所有字符串都具有安全性。也许您不想公开某些短语,只有管理员认为对其他类别的用户开放。但是,对于不同的访问级别,则需要更多的翻译域。另外,可能还需要删除标题信息,以防止泄漏翻译者的电子邮件等。当然,这会使构建过程复杂化,但是JavaScript方面需要的翻译时间越长,自动化的收益就越高。