我想使用 django i18n 支持来翻译我的 javascript 文件。 我有以下 JavaScript 文件:
var test_text = gettext('example');
@withStyles(styles)
export default class HomePage {
static contextTypes = {
i18n: PropTypes.object
}
constructor() {
this.componentDidMount.bind(this);
this.handleCitySearch.bind(this);
}
render() {
return (
<Grid className="HomePage">
<Row className="HomePage-hero">
<Col md={8} style={{ textAlign: 'center' }}>
<Input ref="city" bsSize="large" type="text" />
<Button bsSize="large" bsStyle="default" onClick={this.handleCitySearch}>{gettext('button text')}</Button>
</Col>
<Col md={4}>
<ul>
<li>{gettext('SOME TEXT')}</li>
<li>{gettext('MORE TEXT')}</li>
</ul>
</Col>
</Row>
</Grid>
);
}
}
现在我运行 djangos makemessages 命令:
python manage.py makemessages -l de -d djangojs -v 3 -s
我希望创建的翻译文件有四个条目(“example”、“button text”、“SOME TEXT”和“MORE TEXT”),因为
gettext
在 js 文件中出现了 3 次。
但创建的语言环境文件只有两个“example”条目:
#: ../HomePage.js:1
msgid "example"
msgstr ""
#: ../HomePage.js:25
msgid "MORE TEXT"
msgstr ""
我也收到这个警告。但不知道这意味着什么(文件只有 32 行)
HomePage.js:33: warning: RegExp literal terminated too early
有谁知道为什么 django 会忽略其他条目? 也许是因为我使用了 jsx 语法或者因为我使用了 es6 类?
我发现这不是django的问题,而是
xgettext
的问题。
Django 使用以下命令调用 xgettext
:
xgettext --language=JavaScript --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --keyword=pgettext:1c,2 --keyword=npgettext:1c,2,3 --output=- --from-code=UTF-8 --add-comments=Translators ../HomePage.js
有没有
xgettext
专家可以帮助我?
我用最新版本的 Django (1.10.3) 尝试过这个。看起来效果很好。你能升级你的Django版本吗?
对我有用的代码在这里:https://github.com/guitarmanvt/stackoverflow-question-32403632
另外,请记住,您的 JavaScript 函数
gettext
需要在某处定义。当我上次查看时,有几个 JavaScript i18n 库,但没有几个能很好地与 xgettext 和 Django 配合使用。您可能需要自己动手。
或者,看看 Sentry 如何使用 JSX 进行 i18n 操作。 https://blog.sentry.io/2016/01/07/react-i18n.html
翻译愉快!
我之前使用的django版本是1.5.6,它可以完美地从.js中提取关键字。但升级到 1.11.15 后会抛出错误。例如
warning: unterminated string literal
、warning: RegExp literal terminated too early
经过很长时间我发现了一个事实:升级后 makemessages.py 发生了变化。该文件位于
/usr/lib/python2.7/site-packages/django/core/management/commands/makemessages.py
,1.5.6 和 1.11.15。
1.5.6中makemessage的流程为: 1.使用
prepare_js_for_gettext
形式django.utils.jslex
将js文件预处理成符合C语言语法的内容
2.将内容写入.c文件
3.使用xgettext从.c文件中提取关键字并指定语言为C
但在 1.11.15 中,它是: 1.检测xgettext版本,如果大于1.18.3,直接使用xgettext处理js文件,或者像1.5.6那样处理
我遇到的错误是由 xgettext 处理 js 文件的错误引起的。
所以我只是返回
True
行:77并且一切都像以前一样工作
# django/core/management/commands/makemessages.py
def is_templatized(self):
if self.domain == 'djangojs':
return True
# return self.command.gettext_version < (0, 18, 3)
elif self.domain == 'django':
file_ext = os.path.splitext(self.translatable.file)[1]
return file_ext != '.py'
return False
也许你可以尝试这个勾号或重写脚本
我参加聚会晚了几年,但万一有人觉得这有帮助......
你是对的,
xgettext --language=JavaScript
似乎不喜欢ES6/JSX。
使用一个简单的实用程序,例如 本文中所示的实用程序,而不是让
makemessages/xgettext
直接解析您的 ES6/JSX 文件可能会有所帮助。
gettext-extractor
,可用于将 .pot
文件写入 msgmerge
到您的 djangojs.po
文件中...我使用该库运行节点脚本(和 gettext-extractor-vue
对于我的特定用例)写 frontend/messages.pot
,然后是:
./manage.py makemessages $LANGUAGE_FLAGS $IGNORE_FLAGS
./manage.py makemessages -d djangojs $LANGUAGE_FLAGS $IGNORE_FLAGS
for LANGUAGE in ${LANGUAGES[*]}
do
PO_PATH=locale/${LANGUAGE}/LC_MESSAGES/djangojs.po
touch $PO_PATH
msgmerge -q --previous --update $PO_PATH frontend/messages.pot
done
./manage.py compilemessages
然后
compilemessages
生成适当的 .mo
文件,包括节点提取的字符串,并且 Django 在 /jsi18n/
目录请求中正确地提供它们。
您需要将 JavaScript 代码放入静态文件夹内的文件中才能生成
djangojs.po
。因为 Django 在处理 JS 文件时默认会查看这个目的地。