简体   繁体   English

Django makemessages javascript (xgettext)

[英]Django makemessages javascript (xgettext)

I want to use django i18n support to translate my javascript files.我想使用 django i18n 支持来翻译我的 javascript 文件。 I have the following javascript file:我有以下 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>
      );
  }
}

Now I run djangos makemessages command:现在我运行 djangos makemessages 命令:

python manage.py makemessages -l de -d djangojs -v 3 -s

I would expect that the created translation file has four entries ('example', 'button text', 'SOME TEXT', and 'MORE TEXT'), because gettext appears three times in the js file.我希望创建的翻译文件有四个条目(“示例”、“按钮文本”、“一些文本”和“更多文本”),因为gettext在 js 文件中出现了 3 次。 But the created locale file has only two entry for "example":但是创建的语言环境文件只有两个“example”条目:

#: ../HomePage.js:1
msgid "example"
msgstr ""

#: ../HomePage.js:25
msgid "MORE TEXT"
msgstr ""

I also get this warning.我也收到此警告。 But have no clue what it means (the file has only 32 lines)但不知道它是什么意思(文件只有 32 行)

HomePage.js:33: warning: RegExp literal terminated too early

Does anyone know why django ignores the other entries?有谁知道为什么 django 会忽略其他条目? Maybe it's because I use the jsx syntax or because I use es6 classes?也许是因为我使用了 jsx 语法还是因为我使用了 es6 类?

UPDATE:更新:

I found out that this is not a problem of django but of xgettext .我发现这不是 django 的问题,而是xgettext的问题。 Django calls xgettext with the following command: 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

So is there any xgettext expert who can help me?那么有没有xgettext专家可以帮助我?

I tried this with the latest version of Django (1.10.3). 我使用最新版本的Django(1.10.3)进行了尝试。 It seemed to work just fine. 它似乎工作正常。 Can you upgrade your Django version? 您可以升级Django版本吗?

The code that worked for me is here: https://github.com/guitarmanvt/stackoverflow-question-32403632 对我有用的代码在这里: https : //github.com/guitarmanvt/stackoverflow-question-32403632

Also, bear in mind that your JavaScript function gettext needs to be defined somewhere. 另外,请记住,您的JavaScript函数gettext需要在某处定义。 When last I looked, there were several JavaScript i18n libraries out there, but not many played well with xgettext and Django . 当我最后看时,那里有几个JavaScript i18n库,但是使用xgettextDjango的情况并不好。 You may have to roll your own. 您可能需要自己动手。

Alternatively, take a look at how Sentry does i18n with JSX. 或者,看看Sentry如何使用JSX进行i18n。 https://blog.sentry.io/2016/01/07/react-i18n.html https://blog.sentry.io/2016/01/07/react-i18n.html

Happy translating! 翻译愉快!

The django version I used previously is 1.5.6, it can extract keywords from .js perfectly. 我以前使用的Django版本是1.5.6,它可以完美地从.js中提取关键字。 But it throw errors after upgrading to 1.11.15. 但是升级到1.11.15后会抛出错误。 Eg warning: unterminated string literal , warning: RegExp literal terminated too early 例如, warning: unterminated string literal warning: RegExp literal terminated too early warning: unterminated string literalwarning: RegExp literal terminated too early

After much time I dig out the fact: The makemessages.py changed after upgrading. 经过很多时间,我发现了一个事实:makemessages.py在升级后发生了变化。 The file is located in /usr/lib/python2.7/site-packages/django/core/management/commands/makemessages.py , both 1.5.6 and 1.11.15. 该文件位于/usr/lib/python2.7/site-packages/django/core/management/commands/makemessages.py ,分别为1.5.6和1.11.15。

In 1.5.6, the flow of makemessage is : 1. use prepare_js_for_gettext form django.utils.jslex to pre-processing js files into content that conforms to C language syntax 2. write content to .c file 3. use xgettext extract keywords from .c file and specify language to C 在1.5.6中,makemessage的流程是:1.使用django.utils.jslex形式的prepare_js_for_gettext将js文件预处理为符合C语言语法的内容2.将内容写入.c文件3.使用xgettext extract关键字从.c文件并为C指定语言

But in 1.11.15, it is: 1. detect xgettext version, if greater than 1.18.3, use xgettext process js file directly, or process like 1.5.6 但是在1.11.15中,它是:1.检测xgettext版本,如果大于1.18.3,则直接使用xgettext处理js文件,或者像1.5.6这样处理

The error I got is caused by a bug in xgettext processing js files. 我得到的错误是由xgettext处理js文件中的错误引起的。

So I just return True line: 77 and all working as before 所以我只返回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

Maybe you can try this tick or rewrite an script 也许您可以尝试打勾或重写脚本

I'm few years late to the party, but in case anyone finds this helpful...我参加聚会晚了几年,但万一有人发现这有帮助......

You are correct, xgettext --language=JavaScript doesn't seem to like ES6/JSX.你是对的, xgettext --language=JavaScript似乎不喜欢 ES6/JSX。

Using a simple utility such as the one shown in this article rather than letting makemessages/xgettext parse your ES6/JSX files directly might help.使用简单的实用程序(例如 本文中显示的实用程序)而不是让makemessages/xgettext直接解析您的 ES6/JSX 文件可能会有所帮助。

Alternatively there are node packages such as gettext-extractor which can be used to write a .pot file to msgmerge into your djangojs.po files... I run a node script using that library (and gettext-extractor-vue for my particular use case) to write frontend/messages.pot , then this:或者,还有诸如gettext-extractor类的节点包,可用于将.pot文件写入msgmerge到您的djangojs.po文件中......我使用该库运行节点脚本(以及gettext-extractor-vue用于我的特定用途case) 来写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

And compilemessages then generates the appropriate .mo files including the node-extracted strings, and Django correctly serves them in /jsi18n/ catalogue requests.然后compilemessages生成适当的.mo文件,包括节点提取的字符串,Django 在/jsi18n/目录请求中正确地为它们提供服务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM