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.

Play 2.0, Scala and the new way of doing things

Recently there’s been a (heated) discussion on the Play framework mailing list about Play 1.x vs Play 2.0, Scala, and the added level of complexity.

First off, some of these points are completely valid. For many Java hackers, Play 1.x was an enlightenment. While it’s true that it was a copy of Ruby on Rails in Java, it was the first framework which allowed agile web development on the JVM (i.e. hot-reloading, compile errors are shown in the browser, no XML configuration, and so on). With 1.1 and 1.2 it added most of the needed features while keeping a light style of development. Many people feel that with Play 2.0, this lightness has gone.

Why is that? Let me show you some examples.

Claim 1: You have to learn a new language

Play 2.0 is written in Scala, and even though it has a Java API, as a non-Scala developer you quickly encounter code you don’t understand. First and foremost, it’s the templating engine, which is based on Scala. The framework authors’ response is that you can switch out the templating engine. But why use a web framework if you have to switch out every component? And it’s obviously not the first thing you want to do when trying out something for the first time. I still don’t understand why they didn’t bundle the Groovy engine.

The build file is not only written in Scala, but even a Scala DSL. I initially found this to be an advantage since I already knew SBT. Well, at least I thought so. SBT 0.7 was a joy to use, but apparently it’s a fun exercise to completely change the DSL with every point-release. They should also have changed the name because this tool is anything but simple.

And for the record, the route files are written in Scala-style, too. However, this shouldn’t be a big a deal, as the route syntax is pretty limited.

Whether or not you like Scala itself is a very personal choice; you should at least give it a try. Yes it’s a complex beast, but it also allows you to write beautiful code, especially if you embrace the functional paradigm (see the examples below).

Claim 2: Compilation times are slower

This is what I found to be the biggest problem with Play 2.0. Agile development with fast tournaround times makes only half as much sense when one small change in a templates results in the recompilation of 60 classes and takes 10 seconds. Fortunately, the authors of Play and of SBT (the compiler being the main culprit here) are aware of that. So hopefully, compile times will improve in the near future.

Another annoyance was unexpected runtime errors (e.g. VerifyError) every now and then. This should vanish as the framework matures.

Conclusion?

So, is Play 2.0 a step in the wrong direction? Absolutely not. I used Play 2.0 with Scala for about three months (even before it reached RC status), and found it an an absolute joy to use. In short, this is because it supports a style of development I’d call Functional Web Programming. Let me show you what I mean by that.

Action Composition

Actions (i.e. the methods that are invoked by clicking a link or pushing a button) are composable, which means you can take one, and wrap it around another, and end up with a new action that is a combination of the two. This allows for powerful and scaling abstractions.

The basic action is called Action (no surprise here) and is essentially a function which maps a request to a result. For example, in our application we have pages that can only be accessed by an administrator. So the easiest way to protect those pages was to define an action called AuthenticatedAdmin which in turns calls Authenticated (whose only job is it to verify if the user is logged in), which in turn calls the actual action.

In terms of code it looks like this:

def Authenticated[A](p: BodyParser[A])(f: AuthenticatedRequest[A] => Result) = {
  Action(p) { implicit request =>
    request.session.get("email").flatMap(email => UserDAO.findByEmail(email)).map { user =>
      f(AuthenticatedRequest(user, request))
    }.getOrElse(Results.Ok(views.html.error("Not Authorized", "You have to log in to view the requested page")))
  }
}

def AuthenticatedAdmin[A](f: AuthenticatedRequest[AnyContent] => Result) = Authenticated { implicit request =>
  request.user.adminProfile match {
    case Some(profile: AdminProfile) => f(AuthenticatedRequest(request.user, request))
    case _ => Results.Ok(views.html.error("Not Authorized", "You need administrator privileges to access the requested page"))
  }
}

The Authenticated action reads the email from the session cookie. If the email is not there, the user has to log-in (which is an overlay in our app, otherwise you’d redirect to the log-in page). If the email is found it is used to find the actual user object (from the database or the cache) and put it in the request (a custom request called AuthenticatedRequest, essentially a case class containing the real request and the user). Now the AuthenticatedAdmin action can reuse these mechanics and add another layer around it. It only checks if the user has an admin profile (which is a simple role system of course) and only then execute the action function (called f) itself.

Finally we can use it in the controller like this:

def index = AuthenticatedAdmin { implicit request =>
  Ok(views.html.admin.index())
}

Take a look at the official documentation for more examples. In a future blog post I will show what kung fu you can do with them.

Templates are functions, too

The templating engine uses Scala code and mixes code and markup based on ASP.NET Razor. While I’d like to see a templating engine that completely separates code and markup (as in Lift or Enlive), this engine is also a pleasure to work with.

A template is a function. The first line of the template defines its input parameters, and the content is the return value. And as in a typical function, you can call other functions (or templates) from within. You can find some cool examples in the wiki.

Composable Framework

The framework itself is composable. You can use a different templating engine (e.g. the aforementioned Groovy engine), you are free to use whatever datastore you want, you can use Akka, or any other JVM library or SBT plug-in. Heck you can even dismiss the core framework and use only the templating engine and Anorm with Akka, BlueEyes or Spray.

Conclusion (now for reals!)

So far Play 2.0 was an enjoyable experience and I’m looking forward to seeing it mature and using it in future projects. I hope you’ll enjoy it, too.

What I like / dislike about the iPad

I’ve been using my iPad (now iPad 2) since for a year now and here are my collected thoughts about it.

Pros

  • More “intuitive” (yes, there is no such thing as intuitive), let’s say more consistent abstractions which are easier to learn for everybody (see how fast a child or old person can learn to use it)
  • Very nice on the couch, on the train, when travelling in general
  • Perfect for reading books and PDFs

Cons

  • There’s a global mute, which does not mute all applications however; you always have to both mute and set the volume to zero, which is quite bad
  • Volume is not loud enough
  • App switching is a pain, WebOS did that much better
  • Synching is often inconsistent
  • iTunes integration just plain sucks
  • Has problems with certain WLANs
  • It doesn’t support MacRuby :)