1

这是我正在尝试做的事情:我想以与 gettext 兼容的方式启用 i18n 对我的 zmi python 脚本的支持,并使用 '_' 函数。

这是我到目前为止所做的。在我的 Zope 产品模块中,我运行:

import gettext, __builtin__    
t = gettext.translation('myDomain', LOCALESPATH, languages=['de'], fallback=True)
__builtin__._ = t.gettext

在(不受限制的)外部方法中调用 _ 工作正常,它按预期返回翻译。

def testI18n():
  return _('text to be translated')

如果我在使用 RestrictedPython 执行其代码的 Zope“脚本(Python)”中尝试此操作,我会收到 NameError:“未定义全局名称 '_'”。

这是我的解决方法:

from myModule import myTranslator as _
print _('text to be translated')
return printed

效果很好(当然,必须允许 Python 脚本使用 myModule)。

但我很好奇是否有办法将 _ 作为受限 python 脚本中的内置函数,以及是否可以在 RestrictedPython.Guards 中扩展 safe_builtins。

4

1 回答 1

3

首先,Zope 已经为您提供了与 gettext 兼容的 i18n 包,格式为zope.i18n. 这已经是 Zope 本身的一部分,无需单独安装。

其次,不要与__builtin__; 只需消息工厂导入模块并命名即可_

在您的 Zope 产品__init__.py中,您为此添加了一个消息工厂:

from zope.i18nmessageid import MessageFactory
from AccessControl import ModuleSecurityInfo

YourDomainMessageFactory = MessageFactory('your.domain')

ModuleSecurityInfo('your.packagename').declarePublic('YourDomainMessageFactory')

现在您有了一个消息 id 工厂,可以将其导入到您的任何项目 python 文件中,包括受限文件:

from your.packagename import YourDomainMessageFactory as _

message = _('Your message to be translated')

请注意我们如何_在代码中仍然使用本地名称。

您使用少量 ZCML 注册您的消息目录:

<configure
    xmlns:i18n="http://namespaces.zope.org/i18n">

    <i18n:registerTranslations directory="locales" />

</configure>

wherelocales是文件所在目录的子目录configure.zcmlzope.i18n期望在注册目录中查找<REGION>/LC_MESSAGES/yourdomain.mo和可选的<REGION>/LC_MESSAGES/yourdomain.po文件;.po文件会根据需要自动编译.mo为您的文件。

ZPT 页面模板zope.i18n默认使用消息目录,请参阅ZPT i18n 支持

如果您需要手动翻译某些内容,请使用以下zope.i18n.translate功能:

from zope.i18n import translate

message = _('Your message to be translated')
print translate(message, target_language='de')

大多数Plone i18n 手册适用于通用 Zope 应用程序。

如果一定要能戳进去__builtins__,那一定要直接操作RestrictedPython.Guards.safe_builtins;这是一本字典:

from RestrictedPython.Guards import safe_builtins

safe_builtins['_'] = t.gettext
于 2012-09-28T16:52:14.803 回答