在控制器中没有发生Play Framework Lang的隐式转换

时间:2015-03-11 05:03:37

标签: scala playframework playframework-2.0

我有一个视图,它接受Play的Lang对象所需的隐式Messages。此视图的签名是:

@()(implicit lang: Lang)

然后我有一个需要创建视图的控制器:

def createView = Action { request =>
  Ok(views.html.showView())
}

然后我有一个隐式方法,我想调用它来创建视图所需的Lang

implicit def getLangFromRequest(request: RequestHeader): Lang = {
  request.cookies.get("lang") match {
    case Some(cookie) => Lang(cookie.value)
    case None => Lang("en") // Default
  }
}

换句话说,该方法应该从cookie中获取语言,否则使用默认值(我已经修剪了这个问题的错误处理)。

然而,这种隐式转换并未发生。我知道它能够隐式转换,因为通过在控制器中创建一个隐式变量起作用:

def createView = Action { request =>
  implicit val lang: Lang = request
  Ok(views.html.showView())
}

但我不想在任何地方添加这种锅炉板线。据推测,我必须显式调用该方法,因为在隐式转换之前会使用一些全局Lang对象。

我有什么选择可以避免在每个控制器中重复此implicit val lang: Lang = request

2 个答案:

答案 0 :(得分:2)

根据Play文档

  

如果您在范围内有隐式请求,则会提供   隐含的Lang值对应于提取的首选语言   来自Accept-Language标头并匹配其中一个应用程序   支持的语言。

所以你需要将你的行动改为

def createView = Action { implicit request =>
  Ok(views.html.showView())
}

它应该有用。

答案 1 :(得分:0)

为每个控制器调用implicit val lang: Lang = request似乎需要做很多工作但是当你考虑它时,实际上并没有,你已经调用了Action方法(它接受了{{1}作为参数无论何时创建新动作。

编写一个Request => Result,它可以完成查找语言的所有重要逻辑,将其混合到所有控制器中,而不是使用trait方法,使用您在该特征中编写的方法,接受Action函数,为语言执行逻辑,然后将函数参数应用于范围中的请求。像这样:

Request => Lang => Result

然后,只需混合特征并使用:

,而不是trait Internationalization { subj: Controller => def withLanguage(f: => Request[AnyContent] => Lang => Result) = Action { implicit request => val lang = request.cookies.get("lang") match { case Some(cookie) => Lang(cookie.value) case None => Lang("en") // Default } f(request)(lang) } }
def action = Action { ... }