Play Framework 2.0 Templates – Part 1, Parameters

Intro

Play Framework 2.0 includes a new and improved templating engine, based on Scala (also known as Twirl). When you don’t know Scala, this can be a bit of a hurdle to overcome. But instead of switching to a different engine, I invite you to learn the basics of Play Scala templating, as it is quite powerful and a joy to use.

What is a Template

A template is essentially a function, mapping its input values to either HTML, XML or any other text output. Everything is compiled and type-checked, that’s why you always have to declare all input parameters. Templates are files inside the views folder and use the naming convention <template-name>.scala.<format>. By default html, xml and txt are the supported formats.

The basic concept is based on ASP.NET Razor and uses the @-sign to mark occurrences of code that will be interpreted by the templating engine. To help the templating engine understand what is code and what is not, you can surround a line of code with @(). This is necessary when a white-space would indicate end of code. A full block of code can be defined with @{} – however this is something I try to avoid as much as possible because it indicates the view is doing the controller’s work.

Templates are rendered by the controller as a response to a request. For example, if you have a template app/views/users/profile.scala.html, you render it from your Java controller
like this:

return ok(views.html.users.profile.render());

Likewise, you can call it from other templates (never forget, it’s just a function):

@users.profile()

For the rest of this article, I’m going to assume you have read (or at least skimmed) the templates articles from the Play wiki (Templates and Use Cases).

Parameters

The first line of every template contains the parameter list(s). In Scala, you can define as many parameter lists as you like (we’ll see an application for that later on). Unlike Java, the type of a parameter comes after the name: <name>: <Type>. A simple template parameter list might look like this:

@(message: String)

Parameters can have default values and can be called by their name. Imagine you have a template that should either display a user’s data as text or as an edit form (depending on some logic elsewhere), you could include a boolean to indicate whether or not the object is editable for the current user. Since you don’t always want to explicitly pass the parameter, you can define a default:

@(user: User, isEditable: Boolean = false)

Now if you call the template from another template (or a Scala controller), you can omit the second parameter. Or you can explicitly call each parameter by its name:

@users.profile(isEditable = true, user = user)

Scala makes heavy use of generics, a concept which is often underused in Java. Generics are defined with square brackets, a list of users would be defined like this: users: List[models.User]. In a Play template you can omit the models package qualification as it is already in scope.

Implicit Parameters

Scala has the concept of implicit parameters. These are parameters that don’t have to be passed explicitly to a function if an implicit value is found in scope. That means you call a function with fewer parameters than declared, and the compiler fills in the rest. In Scala you define both the implicit argument and the implicit value with the implicit keyword. It is important to know that implicit arguments are defined in a separate parameter list which must come last.

When you are using the Java API, you have “magical” access to the request, session and so on in your template. When you are using the Scala API, these appear in your parameter list as implicit parameters:

@(userForm: Form[User])(implicit request: RequestHeader, lang: Lang)

Note that implicit appears only once, but it is applied to the entire parameter list.

Input Helpers

As the Play wiki says, you can define implicit values in your template by using the word “implicit” as prefix. This can not only save you some typing when your template contains an implicit parameter, but also provides a form of dependency injection. A good example are the input helpers provided by Play. You can import them all at once using @import helper._ The underscore replaces Java’s * wildcard (and is used in many other places in Scala as a placeholder). Import statements must come after the parameter list and before the rest of the template.

There are input helpers for all input types like text fields, text areas, checkboxes, and so on (only a good multi-select is missing) which all use a common input helper. Obviously, one size cannot fit all, so how do you adapt the markup to your needs? Let’s take a look at the parameter list of inputText.scala.html:

@(field: play.api.data.Field, args: (Symbol,Any)*)(implicit handler: FieldConstructor, lang: play.api.i18n.Lang)

Ok, so the first item is the field itself (extracted from a play.data.Form for Java or play.api.data.Form for Scala), then comes a varargs list of tuples of Symbol and Any. A tuple is a mini-collection of just two values, usually used to define a key and a value, in this case typed to Symbol and Any. A Symbol is like a String, but unique and is declared in Scala with 'mySymbol. You might know it from languages like Ruby or Clojure, where it is ubiquitous. Any is like java.lang.Object, any type inherits from it. There is syntactic sugar in Scala for defining tuples, which goes like this: key -> value. This allows you to set individual HTML attributes in quite a readable way:

@inputText(field = userForm("lastName"), 'placeholder -> "Last Name")

Some attributes are reserved and must be called with an underscore, e.g. to change the id of the markup that surrounds the field, use '_id, to change the id of the field itself, use 'id.

The second, implicit parameter list takes a field constructor which is responsible for generating the markup. Play provides a default field constructor in case none is provided. To use a different constructor, just bring it in scope as an implicit value. To use the Twitter bootstrap field constructor, just import it:

@import helper.twitterBootstrap._

If you peek inside the file helper/twitterBootstrap/package.scala, you can see that it is defined as an implicit value.

The language (the second argument) can be changed in exactly the same way. However, since the language is passed from the controller to the template, you have to write your controller in Scala to provide the current language as an implicit value. In Java this is currently not as easy.

In some cases, there might not be one way to define all your inputs, but you have several field constructors that you want to mix. The problem in this case is that an implicit value must not be ambiguous, because it is not resolved by its name, only by its type. In this case, you can just pass the value explicitly:

@inputDate(field = ...)(fieldConstructor = myDateConstructor)

However now the compiler is complaining because the second implicit parameter, lang, must be passed explicitly too. In this case you have to use a special Scala function called implicitly, which resolves the implicit value for a given type. This results in the following code:

@inputDate(field = ...)(fieldConstructor = dateConstructor, implicitly[Lang])

Call-By-Name Parameters

Finally, there are also call-by-name parameters (not to be confused with the default naming stuff), which are only evaluated when used inside the function, instead of when the function is called (call-by-value). They are defined with an arrow (=> or in Unicode ) before the name: adminFooter: => Html. They are especially useful when you have content that is not always evaluated, so you can save some computation time.

What’s Next

This should cover most of the use cases regarding input parameters you can encounter when using Scala. The next post will show you how you can use Scala effectively in your template body and I will present some common use cases and pitfalls that we encountered.

Posted in Scala & Playframwork Tagged with: , ,
7 comments on “Play Framework 2.0 Templates – Part 1, Parameters
  1. DrCool says:

    First things first: great work! Thank you for that! 🙂

    But when I try to implicite load the RequestHeader (in Scala mode) I get “Cannot find any HTTP Request Header here “. Might be a stupid question: how to get this thing running?

    Thanks!

  2. marius says:

    If you call the template from Scala, make sure to have an implicit request in scope, like this:

    def myAction = Action { implicit request =>

  3. Craig says:

    “When you are using the Java API, you have “magical” access to the request, session and so on in your template.”

    What other magic is automatically included in the templates?

    Great article, BTW. Thoroughly helpful! I’m looking forward to part 2.

  4. marius says:

    You can find all the magic in here:

    Http.Context.Implicit.html

  5. godev999 says:

    Great article. Is there a Part 2 to this?

  6. Alin says:

    Thank you for your post. I am new to Play and you explained very well templates!

Leave a Reply to marius Cancel reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.