Django makemessages javascript (xgettext)

8

我希望使用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>
      );
  }
}

现在我运行Django的makemessages命令:
python manage.py makemessages -l de -d djangojs -v 3 -s

我希望创建的翻译文件包含四个条目('example','button text','SOME TEXT'和'MORE TEXT'),因为js文件中出现了三次gettext。 但是创建的语言环境文件仅有“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 专家呢?


1
你解决了吗? - Sassan
4个回答

1
我尝试了最新版本的Django(1.10.3),它似乎完美运行。您能升级您的Django版本吗?
这是对我有效的代码:https://github.com/guitarmanvt/stackoverflow-question-32403632 另外,请记住您的JavaScript函数gettext需要在某处定义。据我所知,有几个JavaScript i18n库可用,但很少有与xgettextDjango兼容的。您可能需要自己编写。
或者,看看Sentry如何使用JSX进行i18n。https://blog.sentry.io/2016/01/07/react-i18n.html 祝翻译愉快!

我在使用Django 1.10.6时遇到了同样的问题 - 因此仅更新Django版本是不够的... - bruno desthuilliers

0
你需要将JavaScript代码放在静态文件夹中的一个文件中,以便生成djangojs.po。因为Django在处理JS文件时默认会查找这个目标位置。

0
我之前使用的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.使用django.utils.jslex中的prepare_js_for_gettext将js文件预处理为符合C语言语法的内容。 2.将内容写入.c文件。 3.使用xgettext从.c文件中提取关键字,并指定语言为C。
但在1.11.15中,流程如下: 1.检测xgettext版本,如果大于1.18.3,则直接处理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

也许你可以尝试这个技巧或者重写一个脚本


0

虽然我晚了几年,但如果有人觉得这有帮助...

你是对的,xgettext --language=JavaScript 不太喜欢 ES6/JSX。

使用像 本文所示的工具 这样的简单实用程序,而不是让 makemessages/xgettext 直接解析你的 ES6/JSX 文件,可能会有所帮助。

或者,还可以使用类似 gettext-extractor 这样的节点包将一个 .pot 文件写入到您的 djangojs.po 文件中进行 msgmerge... 我使用该库运行一个节点脚本(以及 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/ 目录请求中提供它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接