Zizheng Tai
Zizheng Tai

Reputation: 6646

Scala Play 2.4 view render vs apply

I notice both views.html.myView.render(...) and views.html.myView(...) can be used to generate a page from the template. However, in case that we need to pass a implicit parameter list into the view, it seems only the apply version works while the render version does not compile.

I assume views.html.myView.apply probably delegates to views.html.myView.render (or the other way around) behind the scene, but I'm not sure and can't find anything related to this in the documentation. The only thing I can get from the Twirl documentation is that TemplateN traits all define the render method, but none of them mention apply.

Upvotes: 3

Views: 952

Answers (1)

Michael Zajac
Michael Zajac

Reputation: 55569

The render method is meant to be used from Java, and apply is meant to be used from Scala. Render delegates to apply, and they will have exactly the same signatures unless there are multiple parameter lists (from currying or implicits).

Let's say I have index.html.scala from the play-scala activator template, modified to add an implicit Int parameter:

@(message: String)(implicit i: Int)

It will get compiled to target/scala-2.11/twirl/main/views/html/index.template.scala. Here are the relevant pieces:

def apply(message: String)(implicit i: Int): play.twirl.api.HtmlFormat.Appendable = ...

def render(message: String, i: Int): play.twirl.api.HtmlFormat.Appendable =
    apply(message)(i)

The parameters in render are squashed into a single list. Since you cannot use implicits from Java (or multiple parameter lists), they need to be explicitly passed in a single list.

If I remove the implicit, they are the same:

def apply(message: String): play.twirl.api.HtmlFormat.Appendable = ...

def render(message:String): play.twirl.api.HtmlFormat.Appendable = apply(message)

Upvotes: 5

Related Questions