Play 2.3.x Scala + i18n

29 views
Skip to first unread message

Ignacio Nieto

unread,
Apr 29, 2016, 1:49:05 PM4/29/16
to play-fr...@googlegroups.com, Maxi Sciuto
Hi all

How does the engine works?
Suppose I have 
    Accept-Language: en-US,es-AR;q=0.5
I have my application.conf configured as:
    application.langs="en,es,pt"
And my template:
    @(...)(implicit lang: play.api.i18n.Lang, request: play.api.mvc.Request[AnyContent])

I would like the framework to cascade languages. i.e:
· en-US, en-GB and en-** --> default to --> en (messages.en)
 ·es-AR, es-CL and es-** --> default to --> es (messages.es)

How can I achieve this behavior?

Another thing I noticed is that i18n doesn't default to "messages" (w/ no extension) file, they default to the first language defined in "application.langs"

Thanks,
Ignacio


Ignacio Nieto

unread,
May 2, 2016, 4:48:27 PM5/2/16
to play-fr...@googlegroups.com, Maxi Sciuto
We finally resolved it by doing this Filter:

package controllers.Filters

import play.api.Play
import play.api.Play.current
import play.api.http.HeaderNames
import play.api.i18n.Lang
import play.api.mvc._
import scala.concurrent.Future

object LangFilter extends Filter {


  def apply (nextFilter: (RequestHeader) => Future[Result]) (request: RequestHeader): Future[Result] = {
    val applicationLangs = Lang.availables
    val requestlangs: Seq[Lang] = request.acceptLanguages
    val countryLessLangs: Seq[Lang] = requestlangs.map(l => Lang(l.language))   //we use them as defaults for latam countries (es,pt,en)
    val maybeLangFromCookie: Option[Lang] = request.cookies.get(Play.langCookieName).flatMap(c => Lang.get(c.value))
   
    //First, read from cookie
    val l: Lang = maybeLangFromCookie.getOrElse {
      //Second, look for the lang in request headers
      requestlangs.collectFirst(Function.unlift { 
        lang => applicationLangs.find(_.satisfies(lang))
      }).getOrElse {
        //Third, we remove the COUNTRY from the headers, "pt-BR" -> "pt" and look for the lang
        countryLessLangs.collectFirst(Function.unlift {  
          lang => applicationLangs.find(_.satisfies(lang))
        }).getOrElse(applicationLangs.headOption.getOrElse(Lang.defaultLang))
           //Finally, we use the first on the application.conf list.
      }
    }
    //After finding the language, we set it as the "Accept-Language" Header while clonning the request.
    val newHeaders = new Headers { val data = (request.headers.toMap + (HeaderNames.ACCEPT_LANGUAGE -> Seq(l.code))).toList }
    nextFilter(request.copy(headers = newHeaders))
  }
}
Reply all
Reply to author
Forward
0 new messages