这是我想做的事情:我想以gettext兼容的方式使用'_'功能为zmi python脚本启用i18n支持。

这是我到目前为止所做的。在我的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。

最佳答案

首先,Zope已经以zope.i18n的形式为您提供了与gettext兼容的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>


其中localesconfigure.zcml文件所在目录的子目录。 zope.i18n希望在注册目录中找到<REGION>/LC_MESSAGES/yourdomain.mo<REGION>/LC_MESSAGES/yourdomain.po个文件; .po文件会根据需要自动编译为.mo文件。

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

如果需要手动翻译,请使用zope.i18n.translate函数:

from zope.i18n import translate

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


大多数Plone i18n manual适用于常规Zope应用程序。

如果您绝对必须将内容戳入__builtins__,则一定要直接操作RestrictedPython.Guards.safe_builtins;这是一本字典:

from RestrictedPython.Guards import safe_builtins

safe_builtins['_'] = t.gettext

关于python - Zope中用于Python脚本的i18n(受限python),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12641463/

10-10 05:46