i18n 错误:控制器和模板使用不同的隐式语言 [英] i18n error: controller and templates uses different implicit languages

查看:18
本文介绍了i18n 错误:控制器和模板使用不同的隐式语言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

控制器:

def test = Action { implicit request =>
    import play.api.i18n._
    val msg = Messages("error.invalid")
    implicit val langInController = lang(request)
    Ok(views.html.test(langInController, msg))
}

查看:

@(langInController: play.api.i18n.Lang, msg:String)(implicit request: Request[_])
<div>Lang from controller: @langInController, Message: @msg</div>
<div>Message from view: @play.api.i18n.Messages("error.required")</div>

消息资源,conf/messages.zh-CN:

error.required=该字段必填

尝试

  1. 使用英文 Firefox,它发送请求标头 Accept-Language:en-us,en;q=0.5 以访问 test 操作.结果是:

  1. Uses an English Firefox which sends the request header Accept-Language:en-us,en;q=0.5 to visit the test action. The result is:

Language from controller: Lang(en,), Message: This field is required
Message in view: 该字段必填

  • 使用中文谷歌浏览器发送请求头Accept-Language:zh-CN,zh;q=0.8来访问它.结果是:

    Language: Lang(zh,CN), Message: 该字段必填
    Message in view: 该字段必填
    

  • 从测试中,我们知道:

    1. 控制器中的隐式语言来自请求头的Accept-Language
    2. 模板中使用的隐式语言由操作系统决定

    环境:

    1. Play 2 是来自 GitHub 的最新 play2.1-SNAPSHOT (2012-03-16)
    2. 我的操作系统是 Windows 7 x64 中文版

    我认为 Play 2 应该对控制器和视图使用相同的隐式语言.我可以通过在 Build.sbt 中添加一些东西来修复它:

    I think Play 2 should use the same implicit language for controllers and views. I can fix it by adding something in Build.sbt:

    val main = PlayProject(...) (
        templatesImport ++= Seq("utilis.TemplateMixin._")
    )
    

    TemplateMixin 的位置:

    object TemplateMixin extends play.api.mvc.Controller
    

    (它扩展了Controller,只是为了复用一些方法,比如implicit def lang(request).)

    (It extends Controller and is just to reuse some methods, like implicit def lang(request).)

    但我认为应该由 Play 框架来完成.

    But I think it should be done by the Play framework.

    推荐答案

    play.api.i18n.Messages(key) 函数需要一个额外的 Lang.因此,当您编写 Messages("foo") 时,它会扩展为 Messages("foo")(l),其中 l 是一个值Lang 类型取自当前隐式作用域.

    The play.api.i18n.Messages(key) function takes an additional implicit parameter of type Lang. So when you write Messages("foo") it is expanded to Messages("foo")(l), where l is a value of type Lang taken from the current implicit scope.

    总是有一个可用的 默认隐式语言(它有一个 低优先级),使用您的 jvm 默认语言环境.

    There’s always an available default implicit lang (which has a low priority), using your jvm default locale.

    但是当你在一个 Controller,如果有隐式请求,可以找到优先级更高的隐式值.该值在请求的 Accept-Language 标头中查找.

    But when you are inside a Controller, an implicit value with a higher priority can be found if there is an implicit request. This value looks in the Accept-Language header of the request.

    当您在模板中时,将使用默认的隐式 lang,除非您的模板导入另一个隐式 lang.

    When you are inside a template, the default implicit lang will be used unless your template imports another implicit lang.

    这就是为什么在您的示例中,从 Controller 计算的消息使用 Accept-Language 请求标头,而从 View 计算的消息使用您的 jvm 默认语言环境.

    That’s why, in your example, messages computed from the Controller use the Accept-Language request header and messages computed from the View use your jvm default locale.

    如果您向模板中添加类型为 Lang 的隐式参数,则此参数将具有比默认 lang 更高的优先级,并将用于计算消息:

    If you add an implicit parameter of type Lang to your template, this parameter will have a higher priority than the default lang and will be used to compute messages:

    @(langInController: Lang, msg:String)(implicit request: RequestHeader, lang: Lang)
    
    <div>Lang from controller: @langInController, Message: @msg</div>
    <div>Message from view: @Messages("error.required")</div>
    

    当您从控制器操作调用模板时,将传递其隐式语言,因此您的视图和控制器将使用相同的语言.

    When you’ll call the template from a Controller action, its implicit lang will be passed, so the same lang will be used by both your Views and your Controllers.

    这篇关于i18n 错误:控制器和模板使用不同的隐式语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆