5

Pyramid 文档向我们展示了如何在视图(以及模板)中使用 i18n 。但是如何在我们无法访问当前的视图和模板之外使用它request(例如, informsmodels)?

@Michael 说要传递request给模型和表单。但这样做对吗?我的意思是如果表单字段在__init__()方法调用之前定义,与模型相同。他们从视图中看不到任何参数...

在 Pylons 中,我们可以简单地在父控制器中使用get_lang()set_lang()定义首选语言,然后在我们想要的任何地方使用ugettext()和,而无需每次都直接调用它(在视图中)。ungettext()request

如何在金字塔中做到这一点?请注意,必须从用户的设置(会话、cookie、数据库等)中设置语言。

4

4 回答 4

4

我的解决方案是在需要使用 localizer 作为参数时创建表单类。例如

表格.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,然后使用该工厂创建一个表单。通过这样做,表单中的所有消息都被替换为当前的语言环境。

同样,您可以对模型执行相同的操作。

于 2012-05-12T15:21:21.297 回答
2

你找到pyramid.18n.get_localizer了吗?

http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/i18n.html#using-a-localizer

于 2012-04-29T17:41:27.937 回答
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 真的很糟糕,而且很痛苦,因为我们需要用他们的母语向用户发送电子邮件,然后尝试恢复语言……此外,翻译请求之外的任何内容都是不可能的当时不存在作为翻译器或注册表的 pylons 程序。

于 2012-05-09T19:43:06.103 回答
0

您可以制作本地化程序,然后相应地翻译模板。

在制作本地化器时,您可以传递您想要的语言(无论您是从 db 还是其他)。希望它可以提供帮助。

为了清楚起见,我将在下面将其设置为“fr”

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 _
于 2016-10-13T15:13:49.890 回答