scalaplayframeworkplayframework-2.6

Migrating to 2.6: lang is not being implicitly propagated out of the request


I have a simplified version of a Controller that looks like this (see the full file here):

@Singleton
class Application @Inject() (implicit
                             indexView: views.html.index,
                             deadbolt: DeadboltActions,
                             userService: UserService) extends InjectedController with I18nSupport {
  import scala.concurrent._

  def index =
    TryCookieAuthAction { implicit jContext =>
      deadbolt.WithAuthRequest()() { implicit request =>
        Future {
          implicit val lang = request.acceptLanguages.head
          Ok(indexView(userService))
        }
      }
    }
}

The issue I'm having is that if I comment the explicit extraction of lang then the view won't see it. Why is that? It used to work before Play 2.6 ...


Solution

  • Messages docs state that

    ...you can wrap a given Lang together with the MessagesApi to create a play.api.i18n.Messages instance.

    so consider refactoring views to take

    implicit messages: Messages
    

    instead of

    implicit messagesApi: MessagesApi, lang: Lang
    

    This way we do not have to explicitly handle Lang, because I18nSupport.request2messages implicit conversion will take care of that under the hood.

    For example, say we have the following view/index.scala.html

    @()(implicit messages: Messages)
    
    @messages("salutation")
    

    and and the following English externalised messages conf/messages.en

    salutation=live long and prosper
    

    and the following Italian externalised messages conf/messages.it

    salutation=vivi a lungo ed in prosperita
    

    and the following allowed languages conf/application.conf

    play.i18n.langs = [ "en", "it" ]
    

    then the controller does not need to explicitly handle Lang as long as we extend I18nSupport and have an implicit request in scope like so

    @Singleton
    class HomeController @Inject()(cc: ControllerComponents) 
        extends AbstractController(cc) with I18nSupport {
    
      def index = Action { implicit request =>
        Ok(views.html.index())
      }
    }
    

    Now HTTP request with Accept-Language: it header should respond with

    vivi a lungo ed in prosperita
    

    whilst one with Accept-Language: en with

    live long and prosper
    

    Also consider I18N API Migration guide.