这是我想做的事情:我想以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>
其中
locales
是configure.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/