Pyramid documentation告诉我们如何在视图中使用i18n(和templates as well)。但是如何在我们无权访问当前request
的视图和模板之外使用它(例如,在forms
和models
中)?
@Michael说要将request
传递给模特和表格。但这是对的吗?我的意思是如果表单字段在__init__()
方法调用之前定义,则与模型相同。他们没有从视图中看到任何参数...
在Pylons中,我们可以简单地使用get_lang()
和set_lang()
并在父控制器中定义首选语言,然后在我们想要的任何地方使用ugettext()
和ungettext()
,而无需调用它request
直接在每个可能的时间(在视图中)。
如何在金字塔中做到这一点?请注意,必须根据用户的设置(会话,cookie,数据库等)设置语言。
答案 0 :(得分:3)
我的解决方案是在需要localizer作为参数时创建表单类。例如
forms.py
class FormFactory(object):
def __init__(self, localizer):
self.localizer = localizer
_ = self.localizer
self.required_msg = _(u'This field is required.')
self.invalid_email_msg = _(u'Invalid email address.')
self.password_not_match_msg = _(u'Password must match')
def make_contact_form(self):
_ = self.localizer
class ContactForm(Form):
email = TextField(_(u'Email address'), [
validators.Required(self.required_msg),
validators.Email(self.invalid_email_msg)
])
content = TextAreaField(_(u'Content'), [
validators.Required(self.required_msg)
])
return ContactForm
当您需要使用表格
时@view_config(route_name='front_pages.contact_us',
renderer='myweb:templates/front_pages/contact_us.genshi')
def contact_us(request):
"""Display contact us form or send mail
"""
_ = get_localizer(request)
factory = FormFactory(_)
ContactForm = factory.make_contact_form()
form = ContactForm(request.params)
return dict(form=form)
如您所见,我们在视图中获取了本地化程序,并将其传递给FormFactory,然后使用该工厂创建表单。通过这样做,表单中的所有消息都被当前的语言环境替换。
同样,你可以对模型做同样的事情。
答案 1 :(得分:2)
你找到了pyramid.18n.get_localizer
吗?
http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/i18n.html#using-a-localizer
答案 2 :(得分:1)
其实我遇到了同样的问题。我最终做的是查看默认语言环境协商器如何工作 - 它在给定的请求对象上查找 LOCALE 属性。所以只需使用虚拟对象来创建定位器。如果需要,您也可以缓存此值
def my_get_localizer(locale=None):
request = Request({})
request._LOCALE_ = locale
return get_localizer(request)
或者,加入irc频道#pyramid @ freenode并在那里充分纠缠那些人将get_localizer的功能分成2个单独的文档函数(get_localizer和get_localizer_for_locale_name)供我们欣赏;)
另外,请注意Pyramid TranslationStrings是懒惰的,因此您可以根据需要进行翻译,例如。
class MyModel(Base):
description = TranslationString("My model number ${number}")
...
def view(request):
m = MyModel()
localizer = get_localizer(request)
description = localizer.translate(m.description, mapping={'number': 1})
旁白:pylons'i18n是我多年来打开的最糟糕的蠕虫。因为我们需要用他们的母语向用户发送电子邮件然后尝试恢复语言,所以set_lang,get_lang hack真的非常糟糕,而且很痛苦...而且,在请求之外翻译任何内容都是不可能的。当时不存在作为翻译或注册表的挂架程序。
答案 3 :(得分:0)
您可以制作本地化程序,然后相应地翻译模板。
制作本地化程序时,您可以传递所需的语言(无论您是从db还是其他语言)。希望它可以提供帮助。
为了清楚起见,我将其设置为 <强> 修改 强>
您也可以将此逻辑放入一个小函数from pyramid.i18n import make_localizer, TranslationStringFactory
from mako.template import Template
from mako.lookup import TemplateLookup
import os
absolute_path = os.path.dirname(os.path.realpath(__file__))
tsf = TranslationStringFactory('your_domain')
mako_lookup = TemplateLookup(directories=['/'])
template = Template(filename=template_path, lookup=mako_lookup)
localizer = make_localizer("fr", [absolute_path + '/../locale/'])
def auto_translate(*args, **kwargs):
return localizer.translate(tsf(*args, **kwargs))
# Pass _ pointer (translate function) to the context
_ = auto_translate
context.update({
"_": _
})
html = template.render(**context)
def get_translator(lang):
"""
Useful when need to translate outside of queries (no pointer to request)
:param lang:
:return:
"""
localizer = make_localizer(lang, [absolute_path + '/../locale/'])
def auto_translate(*args, **kwargs):
return localizer.translate(tsf(*args, **kwargs))
_ = auto_translate
return _