Scala I18n即插即用框架2.4.0

Scala I18n即插即用框架2.4.0,scala,playframework,Scala,Playframework,这是我的路由文件: GET /:lang controller.Application.index(lang: String) GET /:lang/news controller.Application.news(lang: String) 请注意,它们都以/:lang开头 目前,我将Application.scala编写为 def index(lang: String) = Action { implicit val messages: Messages = play.api

这是我的
路由
文件:

GET /:lang      controller.Application.index(lang: String)
GET /:lang/news controller.Application.news(lang: String)
请注意,它们都以
/:lang
开头

目前,我将
Application.scala
编写为

def index(lang: String) = Action {
  implicit val messages: Messages = play.api.i18n.Messages.Implicits.applicationMessages(
    Lang(lang), play.api.Play.current)
  Ok(views.html.index("title"))
}

通过这种方式,我必须编写与
操作
一样多的
隐式消息
。有没有更好的解决办法

只传递
Lang
是更简单的选择:

def lang(lang: String) = Action {
    Ok(views.html.index("play")(Lang(lang)))
}

//template
@(text: String)(implicit lang: play.api.i18n.Lang)
@Messages("hello")
通过使用动作组合、定义包装请求和动作,您可以重用某些代码:

case class LocalizedRequest(val lang: Lang, request: Request[AnyContent]) extends WrappedRequest(request)

def LocalizedAction(lang: String)(f: LocalizedRequest => Result) = {
    Action{ request =>
      f(LocalizedRequest(Lang(lang), request))
    }
}
现在,您可以像这样重复使用
LocalizedAction

//template
@(text: String)(implicit request: controllers.LocalizedRequest)
@Messages("hello")

//controller
def lang(lang: String) = LocalizedAction(lang){implicit request =>
    Ok(views.html.index("play"))
}
def lang(lang: String) = LocalizedAction(lang) { implicit request =>
    Ok(views.html.index("play"))
}

最后,我用下面的方法解决了这个问题

正如@Infinity所建议的,我将包装请求和操作定义为:

case class LocalizedRequest(messages: Messages,
                            request: Request[AnyContent])
  extends WrappedRequest(request)


object Actions {
  def LocalizedAction(lang: String)(f: LocalizedRequest => Result) = {
    Action { request =>
      f(LocalizedRequest(applicationMessages(Lang(lang), current), request))
    }
  }

  object Implicits {
    implicit def localizedRequest2Messages(implicit request: LocalizedRequest): Messages = request.messages
  }
}
现在我可以像这样使用
LocalizedAction

//template
@(text: String)(implicit request: controllers.LocalizedRequest)
@Messages("hello")

//controller
def lang(lang: String) = LocalizedAction(lang){implicit request =>
    Ok(views.html.index("play"))
}
def lang(lang: String) = LocalizedAction(lang) { implicit request =>
    Ok(views.html.index("play"))
}
但是,为了省略
Messages
implicit
参数,它应该是
play.api.i18n.Messages
,我在模板中添加了一行:

@import controllers.Actions.Implicits._

这看起来不错,但在模板中是否可以只编写
@Messages(“hello”)
?是的,在这两种情况下,您都可以省略
@Messages(“hello”)
之后的第二个括号,我已经编辑了答案。第一种情况很好。但是在第二种情况下,我必须编写
@Messages(“hello”)(request.Messages)
,否则我将得到一个编译错误
无法找到参数Messages的隐式值:play.api.i18n.Messages
。注意:在播放2.4中,
Messages
的第二个参数已被
play.api.i18n.Messages
替换。这可能会有所帮助。您可以将
@import controllers.Actions.Implicits.\u
放在build.sbt中的任意位置,设置
TwirlKeys.templateImports++=Seq(“controllers.Actions.Implicits.”