通过将一些.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 ... """
我们指定 egg 和 source
>>> 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>
我们指定一个不包含配置的 source 的 egg
>>> 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)
已迁移到 github: https://github.com/collective/collective.recipe.i18noverrides [莫里斯]
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]
下载
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。