i18n错误:控制器和模板使用不同的隐式语言

Fre*_*ind 9 templates controller internationalization playframework-2.0

控制器:

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))
}
Run Code Online (Sandbox Code Playgroud)

视图:

@(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>
Run Code Online (Sandbox Code Playgroud)

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

error.required=?????
Run Code Online (Sandbox Code Playgroud)

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

    Language from controller: Lang(en,), Message: This field is required
    Message in view: ?????
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用中国谷歌浏览器发送请求标题Accept-Language:zh-CN,zh;q=0.8以访问它.结果是:

    Language: Lang(zh,CN), Message: ?????
    Message in view: ?????
    
    Run Code Online (Sandbox Code Playgroud)

从测试中我们知道:

  1. 控制器中的隐式语言来自请求标头 Accept-Language
  2. 模板中使用的隐式语言由OS确定

环境:

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

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

val main = PlayProject(...) (
    templatesImport ++= Seq("utilis.TemplateMixin._")
)
Run Code Online (Sandbox Code Playgroud)

TemplateMixin仅仅是:

object TemplateMixin extends play.api.mvc.Controller
Run Code Online (Sandbox Code Playgroud)

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

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

Jul*_*Foy 17

play.api.i18n.Messages(key)函数采用类型的附加隐式参数Lang.因此,当您编写Messages("foo")它时,它会扩展为Messages("foo")(l),其中lLang从当前隐式范围获取的类型值.

使用您的jvm默认语言环境始终存在可用的默认隐式语言(具有低优先级).

但是当您在Controller内部时,如果存在隐式请求,则可以找到具有更高优先级的隐式值.此值在Accept-Language请求的标头中查找.

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

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

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

@(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>
Run Code Online (Sandbox Code Playgroud)

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