Python js中的Flask Babel本地化字符串

Python js中的Flask Babel本地化字符串,python,flask,jinja2,python-babel,Python,Flask,Jinja2,Python Babel,我对Python和Flask(使用Jinja2作为模板引擎)都很陌生,我不确定我是否用正确的方法来做。我正在使用Flask Babel扩展将i18n支持添加到我的web应用程序中。我想从我的js代码中获取本地化字符串,例如: var helloWorld = gettext('Hello, world'); console.log(helloWorld); //should log a localized hello world message 为此,我配置了babel(babel.cfg):

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

var helloWorld = gettext('Hello, world');
console.log(helloWorld); //should log a localized hello world message
为此,我配置了babel(babel.cfg):

其初始化为(为简单起见,省略导入):

Babel在构建POT/PO语言文件时标识了该字符串,但似乎我无法从js代码访问这些本地化字符串,因为没有定义gettext函数。金甲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>

希望这有帮助

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

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

<div id="view-i18n" data-i18n='{{ view_i18n|tojson }}'> ... </div>
。。。
(注:单引号!)

但它也适用于有限数量的翻译

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

在名为
pojson
的实用程序的帮助下,可以将po文件转换为json(参见示例),作为构建过程的一部分(例如,在生成
mo
-文件之后)。通过在
pojson
的输出前面加上
var some_unique_name=
以访问它,可以很容易地将翻译添加到某个足够唯一的全局名称空间变量中。或者将
static
下的文件放入特定于语言环境的文件中(例如
static/view es.json
static/view-fr.json
,等等),并通过ajax调用获取它


有些事情要考虑。如果您真的想使JSON更小,那么您可能需要通过控制babel提取选项将翻译域拆分为单独的Python和Javascript。另外,在Javascript中使用所有翻译字符串具有安全性。也许,您不想公开某些只有管理员才能看到的对其他类别用户开放的短语。但是,不同的访问级别需要更多的翻译域。此外,标题信息可能需要删除,以防止泄露译者的电子邮件等。当然,这在一定程度上使构建过程复杂化,但JavaScript方面的翻译需要的时间越多,自动化的效果就越高。

您是将JavaScript作为静态文件提供,还是通过添加到Flask应用程序的路径进行处理?它作为静态文件提供(在jinja2处理的html中)。我假设您的意思是静态文件由Jinja处理的HTML中的
标记引用。你按步骤进去了吗?没错。是的,我做过,但没有多大成功。如前所述,babel会检测到消息,但在解释js代码时,由于没有名为“gettext”的函数,解释器只会抛出一个引用错误。您需要使用
tojson
过滤器<代码>var helloWorld={{gettext('Hello,world')|tojson}如果您使用的是旧版本的Flask,那么您还需要在
tojson
之后包含
|safe
。嗯,
tojson
过滤器工作得很好,除了与
gettext
一起使用时,它似乎:
{{gettext('Hello,world')| tojson}导致
和#34;您好,world"
对我来说,当删除
gettext
时,会给出正确且未替换的JSON字符串引号。这仍然是推荐的解决方法还是现在有更好的方法?我在这里测试了javascript作为html的一部分,而tojson | safe就足够了。
<script type="text/javascript">
   var x = {{gettext('Hello, world')|generate_string|safe}};
   console.log(x);    //logs the localized hello world message
</script>
#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()
<div id="view-i18n" data-i18n='{{ view_i18n|tojson }}'> ... </div>