Question

I've been trying to force the locale into the Request object depending on the host name of the application. This is done by reading a configuration Map

package controllers

import play.api.mvc._
import play.api.i18n.Lang
import play.api.Play.current
import scala.actors.Future

object Global extends WithFilters(ForceLocalization)

object ForceLocalization extends Filter {

  override def apply(next: (RequestHeader) => Future[SimpleResult])
                    (rh: RequestHeader): Future[SimpleResult] = {
    val arr = models.DomainSettings.forDomain(rh.domain).locale.split("_") // -> "en_US"
    val language = arr(0) // -> "en"
    val country = if ( arr.length == 1 ) "" else arr(1) // -> "US"
    f(rh).map( _.withLang(Lang(language, country)) ) 
  }

}

The code doesn't compile. It says:

type mismatch:
  [error]  found   : play.api.mvc.PlainResult
  [error]  required: play.api.mvc.SimpleResult
  [error]     f(rh).map( _.withLang(Lang(language, country)) ) 

Any suggestion?

Notice: I might probably have used a bad approach to achieve my goal, so if you have something better to suggest, I'll be glad to have your advice.

Was it helpful?

Solution

Hmmm - seems like you've hit a bug related to Play's transitioning from PlainResult to SimpleResult.

When I look in the 2.2.0 codebase, PlainResult is:

sealed trait PlainResult extends Result with WithHeaders[PlainResult]

and SimpleResult is defined as:

case class SimpleResult(...) extends PlainResult

... which means that all of the WithHeaders methods will be returning PlainResults - which is wrong.

I note that in the 2.2.x codebase on GitHub, it's been rectified:

case class SimpleResult(...) extends PlainResult with WithHeaders[SimpleResult]

... and if you're happy to use a Release Candidate, you can use 2.2.2-RC1 that contains the fix, according to the release notes.

If not, employ a helper method to work around the problem, by doing what WithHeaders.withLang does anyway:

object ForceLocalization extends Filter {

  override def apply(next: (RequestHeader) => Future[SimpleResult])
                    (rh: RequestHeader): Future[SimpleResult] = {
    ...
    next(rh).map( withLang(_, Lang(language, country)) )
  }

  private def withLang(sr:SimpleResult, lang:Lang) = {
    sr.withCookies(Cookie(Play.langCookieName, lang.code))
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top