跳转到主要内容

通过将一些.po文件放在zope 2实例的i18n目录中来覆盖翻译

项目描述

collective.recipe.i18noverrides

这是一个构建脚本。它会在你的构建脚本中创建一个i18n目录,并在一个或多个zope 2实例中复制一些.po文件。这些文件中的翻译将覆盖任何其他翻译。

Plone/Zope版本

此脚本已在Plone 3和Zope 2.10上进行了测试。它也应该适用于没有Plone的纯Zope网站,因为这个脚本没有针对Plone的特殊性。它也应该适用于所有之前的版本。

对于Plone 4和Zope 2.12,它没有影响:这些版本中没有再搜索实例i18n文件夹中的翻译的代码。你应该创建一个自己的包,并在其中注册一个包含翻译的locales目录。有关更多信息或问题,请参阅plone-internationalization邮件列表

用例

一个示例用例是

  • 在荷兰Plone翻译中,msgid 'Manager' 被翻译为 'Beheerder'。

  • 一个客户希望将其翻译为 'Site admin'。

  • 仅仅将这个翻译放在客户产品中的i18n目录中并不能保证它能正常工作,因为它取决于Zope启动时读取i18n文件夹的顺序:是CMFPlone/i18n还是Customer/i18n先被读取。

  • 当你在一个zope 2实例中创建一个i18n目录,并添加一个包含该msgid的po文件时,这可以保证它会被使用。

请注意,这应该适用于覆盖i18n目录中的翻译。覆盖locales目录中的翻译不是这个脚本的用例。

.po文件内容

.po文件应该包含什么?你需要所有通常在.po文件中的标题。所以,复制当前包含你想要覆盖的翻译的po文件的标题。然后,只需添加msgid和新的msgstr。文件名不重要。它应该对你有意义,并以'.po'结尾。在提到的用例中,将其命名为 plone-nl.po 是有意义的,因为这是来自plone翻译的原始文件名。内容可能如下(省略了一些不重要的标题行以提高清晰度)

msgid ""
msgstr ""
...
"Language-Code: nl\n"
"Language-Name: Nederlands\n"
"Domain: plone\n"

msgid "Manager"
msgstr "Site admin"

详细文档

支持选项

该脚本支持以下选项

source

包含要复制的.po文件的源目录。将复制所有的*.po文件。此选项是必须的。

egg

包含源目录的egg。如果指定了此选项,则源目录必须是相对路径。

package

当源在egg中找不到时可以指定,原因可能是:egg包含版本规范;egg的名称不等于已安装的包的名称;源在子包中。

destinations

目标目录或目录。这应该指向zope 2实例的目录。该脚本将在每个目标中创建一个i18n目录,并将源目录中的所有*.po文件复制到这些i18n目录中。此选项是必须的。

示例用法

我们将从创建一个使用该脚本的buildout开始。下面是一个模板,我们只需填写源和目标即可

>>> buildout_config_template = """
... [buildout]
... index = http://pypi.python.org/simple
... parts = i18noverrides
... versions = versions
...
... [versions]
... zc.buildout = 1.4.3
... zc.recipe.egg = 1.2.2
... setuptools = 0.6c11
... distribute = 0.6.14
...
... [i18noverrides]
... recipe = collective.recipe.i18noverrides
... source = %(source)s
... destinations = %(dest)s
... """

我们将从指定一些不存在的源和目标目录开始

>>> write('buildout.cfg', buildout_config_template % {
... 'source': '${buildout:directory}/translations',
... 'dest': '${buildout:directory}/instance'})

运行buildout给出了

>>> print system(buildout)
Installing i18noverrides.
While:
  Installing i18noverrides.
Error: path '/sample-buildout/translations' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.
<BLANKLINE>

源必须是一个目录

>>> write('translations', 'This is a file.')
>>> print system(buildout)
Installing i18noverrides.
While:
  Installing i18noverrides.
Error: path '/sample-buildout/translations' must be a directory.
<BLANKLINE>

现在我们删除这个文件,并尝试使用一个合适的目录

>>> remove('translations')
>>> mkdir('translations')
>>> print system(buildout)
Installing i18noverrides.
While:
  Installing i18noverrides.
Error: path '/sample-buildout/instance' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.
<BLANKLINE>

所以我们也设置一个目标,并首先尝试使用一个文件,然后再创建一个目录

>>> write('instance', 'This is a file.')
>>> print system(buildout)
Installing i18noverrides.
While:
  Installing i18noverrides.
Error: path '/sample-buildout/instance' must be a directory.
<BLANKLINE>
>>> remove('instance')
>>> mkdir('instance')
>>> print system(buildout)
Installing i18noverrides.
collective.recipe.i18noverrides: Warning: source '/sample-buildout/translations' contains no .po files.
<BLANKLINE>

现在源和目标已经正确设置,但我们收到一个警告,因为源目录没有翻译文件。我们首先添加一个不以 .po 结尾的文件。由于之前的 buildout 运行只收到警告并成功完成,现在的配方以更新模式运行,这与安装模式相同

>>> write('translations', 'not-a-po-file', 'I am not a po file')
>>> print system(buildout)
Updating i18noverrides.
collective.recipe.i18noverrides: Warning: source '/sample-buildout/translations' contains no .po files.
<BLANKLINE>
>>> write('translations', 'plone-nl.po', 'I am a Dutch plone po file')
>>> write('translations', 'plone-de.po', 'I am a German plone po file')
>>> print system(buildout)
Updating i18noverrides.
collective.recipe.i18noverrides: Creating directory /sample-buildout/instance/i18n
collective.recipe.i18noverrides: Copied 2 po files.
<BLANKLINE>

没有警告,没有错误,让我们看看最终结果是什么

>>> ls('translations')
-  not-a-po-file
-  plone-de.po
-  plone-nl.po
>>> ls('instance')
d  i18n

在实例中创建了一个 i18n 目录。在那个目录中,我们找到了我们的两个 po 文件

>>> ls('instance', 'i18n')
-  plone-de.po
-  plone-nl.po
>>> cat('instance', 'i18n', 'plone-de.po')
I am a German plone po file
>>> cat('instance', 'i18n', 'plone-nl.po')
I am a Dutch plone po file

如果目标目录由于某种奇怪的原因已经包含了一个 i18n 文件而不是目录,我们将失败

>>> remove('instance', 'i18n')
>>> write('instance', 'i18n', 'I am a file')
>>> print system(buildout)
Updating i18noverrides.
While:
  Updating i18noverrides.
Error: '/sample-buildout/instance/i18n' is not a directory.
<BLANKLINE>
>>> remove('instance', 'i18n')

也应该可以拥有多个目标

>>> write('buildout.cfg', buildout_config_template % {
... 'source': '${buildout:directory}/translations',
... 'dest': """
...     ${buildout:directory}/instance
...     ${buildout:directory}/instance2"""})
>>> print system(buildout)
Installing i18noverrides.
While:
  Installing i18noverrides.
Error: path '/sample-buildout/instance2' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.
<BLANKLINE>

好吧,我们也会创建那个目录

>>> mkdir('instance2')
>>> print system(buildout)
Installing i18noverrides.
collective.recipe.i18noverrides: Creating directory /sample-buildout/instance/i18n
collective.recipe.i18noverrides: Creating directory /sample-buildout/instance2/i18n
collective.recipe.i18noverrides: Copied 2 po files.
<BLANKLINE>

让我们检查结果

>>> ls('instance')
d  i18n
>>> ls('instance', 'i18n')
-  plone-de.po
-  plone-nl.po
>>> ls('instance2')
d  i18n
>>> ls('instance2', 'i18n')
-  plone-de.po
-  plone-nl.po
>>> cat('instance2', 'i18n', 'plone-de.po')
I am a German plone po file
>>> cat('instance2', 'i18n', 'plone-nl.po')
I am a Dutch plone po file

清理

>>> remove('instance')
>>> remove('instance2')

与plone.recipe.zope2instance的集成

由于配方通常用于向 zope 2 实例添加翻译,因此查找设置 zope 实例的 buildout 部件并取那些位置是有意义的。

>>> write('buildout.cfg', """
... [buildout]
... index = http://pypi.python.org/simple
... parts = instance instance2 zeoclient i18noverrides
... versions = versions
...
... [versions]
... zc.buildout = 1.4.3
... zc.recipe.egg = 1.2.2
... setuptools = 0.6c11
... distribute = 0.6.14
... plone.recipe.zope2instance = 3.9
... mailinglogger = 3.3
...
... [i18noverrides]
... recipe = collective.recipe.i18noverrides
... source = ${buildout:directory}/translations
...
... [instance]
... recipe = plone.recipe.zope2instance
... user = admin:admin
...
... [instance2]
... recipe = plone.recipe.zope2instance
... user = admin:admin
...
... [zeoclient]
... recipe = plone.recipe.zope2instance
... user = admin:admin
... """)

我们在 bin 目录中模拟一个 mkzopeinstance 脚本

>>> write('bin/mkzopeinstance', """
... import sys
... import os
... path = sys.argv[2]
... os.mkdir(path)
... os.mkdir(os.path.join(path, 'etc'))
... """)

我们不希望在测试中安装完整的 zope2 实例,因此我们不将其添加到 buildout 部件中。这意味着现在运行 buildout 会失败

>>> print system(buildout)
Getting distribution for 'plone.recipe.zope2instance==3.9'.
...
Installing instance.
Generated script '.../bin/instance'.
...
Installing i18noverrides.
collective.recipe.i18noverrides: Creating directory .../i18n
collective.recipe.i18noverrides: Creating directory .../i18n
collective.recipe.i18noverrides: Creating directory .../i18n
collective.recipe.i18noverrides: Copied 2 po files.
<BLANKLINE>
>>> ls('parts', 'instance')
d etc
d i18n
>>> ls('parts', 'instance', 'i18n')
-  plone-de.po
-  plone-nl.po
>>> ls('parts', 'instance2', 'i18n')
-  plone-de.po
-  plone-nl.po
>>> ls('parts', 'zeoclient', 'i18n')
-  plone-de.po
-  plone-nl.po

如果我们明确指定了目标,则忽略配方。

>>> write('buildout.cfg', """
... [buildout]
... index = http://pypi.python.org/simple
... parts = dummy i18noverrides
... versions = versions
...
... [versions]
... zc.buildout = 1.4.3
... zc.recipe.egg = 1.2.2
... setuptools = 0.6c11
... distribute = 0.6.14
... plone.recipe.zope2instance = 3.9
... mailinglogger = 3.3
...
... [i18noverrides]
... recipe = collective.recipe.i18noverrides
... source = ${buildout:directory}/translations
... destinations = ${buildout:directory}/dest
...
... [dummy]
... recipe = plone.recipe.zope2instance
... user = admin:admin
... """)
>>> mkdir('dest')
>>> print system(buildout)
Uninstalling ...
Installing i18noverrides.
collective.recipe.i18noverrides: Creating directory /.../dest/i18n
collective.recipe.i18noverrides: Copied 2 po files.
<BLANKLINE>
>>> ls('parts', 'dummy')
d etc
>>> ls('dest', 'i18n')
-  plone-de.po
-  plone-nl.po

清理

>>> remove('translations')

egg中的目录使用

我们首先创建一个使用该配方的 buildout。以下是一个模板,我们只需要填写源、egg 和目标

>>> buildout_config_template = """
... [buildout]
... index = http://pypi.python.org/simple
... parts = i18noverrides
... versions = versions
...
... [versions]
... zc.buildout = 1.4.3
... zc.recipe.egg = 1.2.2
... setuptools = 0.6c11
... distribute = 0.6.14
... # We need to pin this one because it still needs to be uninstalled.
... # If we do not pin, the uninstall code will get the latest version,
... # which depends on Zope2, which means we are hosed...
... plone.recipe.zope2instance = 3.9
... mailinglogger = 3.3
...
... [i18noverrides]
... recipe = collective.recipe.i18noverrides
... source = %(source)s
... egg = %(egg)s
... destinations = %(dest)s
... """

我们指定 eggsource

>>> write('buildout.cfg', buildout_config_template % {
... 'source': 'tests/translations',
... 'egg': 'collective.recipe.i18noverrides',
... 'dest': 'translations'})

我们准备目标目录

>>> mkdir('translations')

运行buildout给出了

>>> print system(buildout)
Uninstalling ...
Installing i18noverrides.
collective.recipe.i18noverrides: Creating directory translations/i18n
collective.recipe.i18noverrides: Copied 2 po files.
<BLANKLINE>

让我们检查结果

>>> ls('translations')
d  i18n
>>> ls('translations', 'i18n')
-  test-fr.po
-  test-nl.po
>>> cat('translations', 'i18n', 'test-fr.po')
Un fichier .po
>>> cat('translations', 'i18n', 'test-nl.po')
Een .po bestand

我们在 source 中指定 egg 和一个绝对路径

>>> write('buildout.cfg', buildout_config_template % {
... 'source': '/translations',
... 'egg': 'testegg',
... 'dest': 'translations'})

运行buildout给出了

>>> print system(buildout)
Uninstalling i18noverrides.
Installing i18noverrides.
While:
  Installing i18noverrides.
Error: Because egg option is provided,
source '/translations' should be relative, not absolute.
<BLANKLINE>

我们指定一个不包含配置的 sourceegg

>>> write('buildout.cfg', buildout_config_template % {
... 'source': 'translations',
... 'egg': 'zc.recipe.egg',
... 'dest': 'translations'})

运行buildout给出了

>>> print system(buildout)
Installing i18noverrides.
While:
  Installing i18noverrides.
Error: path '/sample-buildout/eggs/zc.recipe.egg.../zc/recipe/egg/translations' does not exist. You must list the i18noverrides part after all plone.recipe.zope2instance parts.
<BLANKLINE>

贡献者

莫里斯·范·里斯,作者

变更历史

collective.recipe.i18noverrides的历史

1.2 (2013-01-23)

  • 在出现错误时引发 zc.buildout.UserWarning。这就是应该这样做的方式。这比记录错误(可能不会真正被视为错误)并退出更明显。[莫里斯]

1.1 (2012-09-13)

1.0 (2010-08-25)

  • 添加了一个注释,警告此配方在 Plone 4(Zope 2.12)或更高版本中不会产生任何效果。你应该创建自己的包并在其中创建一个 locales 目录。[莫里斯]

0.4 (2009-09-08)

  • 只有当它们实际位于 buildout 的部分部分时,才将 buildout 部件考虑为包含在目标中。否则,你可能会遇到像这样的错误:错误:缺少选项:zptdebugger:__buildout_signature__ [莫里斯]

0.3 (2009-09-08)

  • 如果没有指定目标,我们将自动将 po 文件复制到所有使用 plone.recipe.zope2instance 的部分。[莫里斯]

0.2 (2009-08-12)

  • 允许指定一个 egg(带有可选的包),其中可以找到源目录。[gotcha]

  • 在主 buildout.cfg 和测试中的 buildout 中都固定包(至少是 zc.buildout),以避免测试运行期间由于使用的 zc.buildout 升级而导致的测试失败。[莫里斯]

0.1 (2009-06-05)

  • 初始实现是从一个一次性脚本迁移过来的。[莫里斯]

  • 使用 ZopeSkel 创建了配方[Maurits van Rees]

下载

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分发

collective.recipe.i18noverrides-1.2.zip (29.3 kB 查看散列)

上传于 来源

由以下支持