Play Framework 2.4.0 and I18n with Scala

1k views Asked by At

I have a project with Play Framework 2.3.8 and I'm migrating in Play Framework 2.4 but I have a problem with I18n.

Now I have in a view code like this:

@Messages("components.navbar.text")(locale.MyLang)

where locale is:

object locale {
  var MyLang =Lang("it") 

  def changeLang(newLang:String): Unit ={
     MyLang=Lang(newLang)
  }
}

I would mantainer this structure without using implicit lang, is possible ?

I have some situation where I use in the same page different language and in this case is difficult and boring with the implicit lang.

1

There are 1 answers

1
Mikesname On BEST ANSWER

If I understand your question correctly, which is that you want to override the user's chosen language for certain blocks of the page, I would do this (for Play 2.4) using an implicit Messages object:

@()(implicit messages: Messages)

<!-- some section in the user's chosen language -->
<h1>@Messages("hello.world")</h1>

<!-- some section in a specific language -->
@defining(messages.copy(lang = play.api.i18n.Lang("it")) { implicit messages =>
  <h2>@Messages("something.in.italian")</h2>
}

That is, use defining to create a new (implicit) messages for certain nested blocks of HTML.

If you really wanted to go to town (and I wouldn't necessarily recommend this) you could add an italian method to Messages via an implicit class:

(in my.package.utils.i18n.MessagesExtensions.scala):

package my.packages.utils.i18n

import play.api.i18n.{Lang, Messages}

implicit class MessagesExtensions(messages: Messages) {
   def italian = messages.copy(lang = Lang("it"))

   // and an `as` method for good measure:
   def as(code: String) = messages.copy(lang = Lang(code))
}

To have that work in a view you need to add the class to your templateImport in your build.sbt:

templateImports in Compile ++= Seq(
  "my.packages.utils.i18n.MessagesExtensions"
)

Then in your templates you can just to this:

@()(implicit messages: Messages)

<!-- some section in the user's chosen language -->
<h1>@Messages("hello.world")</h1>

<!-- some section in a specific language -->
@defining(messages.italian) { implicit messages =>
  <h2>@Messages("something.in.italian")</h2>
  ....
}

<!-- or singly, in another language -->
<h3>@Messages("another.thing.in.french")(messages.as("fr"))</h3>

But that might be overkill, unless it really saves you a lot of boilerplate language switching.