我对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忽略了这一部分。
任何提示?
答案 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 =
下的文件放入特定于语言环境的文件(例如static
,static/view-es.json
等)中,并通过ajax调用来获取它。
尽管有些事情要考虑。如果您确实想缩小JSON的大小,则可能需要通过控制babel提取选项将翻译域分为单独的Python和Javascript。同样,使用Javascript转换所有字符串都具有安全性。也许您不想公开某些短语,只有管理员认为对其他类别的用户开放。但是,对于不同的访问级别,则需要更多的翻译域。另外,可能还需要删除标题信息,以防止泄漏翻译者的电子邮件等。当然,这会使构建过程复杂化,但是JavaScript方面需要的翻译时间越长,自动化的收益就越高。