Play Framework - The template engine

In the previous post about Play Framework, we seen how to install Play and create a first simple application. In this post, we'll see how to customize the views and use the template engine of the framework to easily create web pages.

Play has its own template engine to generate HTML web pages. The template engine use Groovy as expression language. You will use Groovy language to create all the dynamic parts of the web pages. But there is no need to learn completely Grooxy, it's really close to Java and if you know already knows Java, there is no problem to use Groovy in your templates. All the templates are located in the app/views folder in your application. All the dynamic part of the web page is resolved during the execution of the template and the result is a part of the HTTP Response.

So first of all, we'll create a little application for our needs :

wichtounet@wichtounet-laptop:~/dev/play$ /usr/share/play/play new views

~        _            _ 
~  _ __ | | __ _ _  _| |
~ | '_ \| |/ _' | || |_|
~ |  __/|_|\____|\__ (_)
~ |_|            |__/   

~ play! 1.0.3, http://www.playframework.org
~ The new application will be created in /home/wichtounet/dev/play/views
~ What is the application name? Views
~ OK, the application is created.
~ Start it with : play run views
~ Have fun!
~

So we start to inspect what has been created by Play. If you go in app/views, you will see this structure :

  • Application : This folder is to store the templates of the Application controller
  • errors : This folder contains the templates for the HTTP Error pages (404, 500, ...)
  • main.html : This is the main template

If you open Application/index.html, you obtain this kind of code :

#{extends 'main.html' /}
#{set title:'Home' /}
#{welcome /}

The first line indicate that we extend an other template (main.html). The next line use a Play tag (set), to set the title of the page. A set tag has a brother, the get tag who get the value setted by the set tag. The last line use the welcome tag who print the content of the welcome page.

Now, let's see the main.html template :

<!DOCTYPE html>
<html>
    <head>
        <title>#{get 'title' /}</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <link rel="stylesheet" type="text/css" media="screen" href="@{'/public/stylesheets/main.css'}">
        #{get 'moreStyles' /}
        <link rel="shortcut icon" type="image/png" href="@{'/public/images/favicon.png'}">
        <script src="@{'/public/javascripts/jquery-1.4.2.min.js'}" type="text/javascript" charset="utf-8"></script>
        #{get 'moreScripts' /}
    </head>
    <body>
        #{doLayout /}
    </body>
</html>

There is some interesting things here :

  • #{get 'title' /} : return the value of the variable title (not a Java variable, only a HTML variable)
  • @{'/public/stylesheets/main.css'} : resolve the resource to its URL
  • #{doLayout /} : Indicate where the sub templates (template who extends main.html) will be rendered

Pass variables to the view

So let's go further. The first important thing is to know how to pass variables to the view from the controller. With Play Framework, this is really simple. just add the variables you need to the render() method of the controller. By example, to pass a String to the view :

package controllers;

import play.mvc.*;

public class Application extends Controller {
    public static void index() {
        String hello = "Hello World from Controller !";

        render(hello);
    }
}

The variable hello is now accessible from the view on the name "hello". To get it, you have to use ${variable_name} simply to display it :

#{extends 'main.html' /}
#{set title:'Home' /}
Hello from the view
<br />
${hello}

Easy, no ?

Let's try adding a simple class to our model :

package models;

public class Book {
    private final String title;

    public Book(String title) {
        super();

        this.title = title;
    }

    public String getTitle() {
        return title;
    }

And pass it to the view :

    public static void index() {
        Book book = new Book("Hello Play !");

        render(book);
    }

And then get it from the view :

#{extends 'main.html' /}
#{set title:'Home' /}
Hello from the view
<br />
I've a book for you "${book.title}". 

The property is getted using the JavaBeans convention, so you have to create a getTitle() method to get the title of the book.

All the dynamic content is directly escaped by the template engine to avoid XSS security exploits. If you really want to not escape something, you have to use the raw() method available on all the strings. By example, for our title :

${book.title.raw()}

But this is not a really good practice, and must be used only when it's necessary.

You can add comments to your templates if you want :

*{Will not be evaluated by the template engine}*

Iterate over a list

An important thing to do in template and that comes really soon is the iterate over a collection. By example, we can pass a list of books to the view from the controller :

    public static void index() {
        List<Book> books = new ArrayList<Book>(3);

        books.add(new Book("Hello Play !"));
        books.add(new Book("Hello Template !"));
        books.add(new Book("Hello Engine !"));

        render(books);
    }

And then, you can iterate over the list using the list tag :

#{extends 'main.html' /}
#{set title:'Home' /}
I've some books for your :
<ul>
    #{list items:books, as:'book'}
        <li>${book.title}</li>
    #{/list}
</ul>

And that will display a single little list in our web page. Not to complicated :)

Using scripts

If you have to make complicated things, you can using scripts in Groovy. In scripts, you can declare variables and use all the other variables. By example, you can make the title upper case in a script :

#{extends 'main.html' /}
#{set title:'Home' /}
I've some books for your :
<ul>
    #{list items:books, as:'book'}
        %{
           bookTitle = book.title.toUpperCase();
        }%
        <li>${bookTitle}</li>
    #{/list}
</ul>

But you can also do iterations, conditions and a lot of other things. But keep in mind that the templates are not the good place to make complicated things, for that you have the controller and the models. The template must be as simple as possible.

Define tags

There is lot of tags in Play Framework, but you can create your own tags. For that, you just have to create a folder tags in your views folder. By example, if you create booklist.html in views/tags and add the following code :

<ul>
    #{list items:_items, as:'book'}
        %{
            bookTitle = book.title.toUpperCase();
        }%
        <li>${bookTitle}</li>
    #{/list}
</ul>

The arguments are obtained using '_' following by the name of the arguments (_items in our example).

You can refactor the template index.html using the new tag :

#{extends 'main.html' /}
#{set title:'Home' /}
I've some books for your :
#{booklist items:books /}

You give arguments like in any other tag. This can help you to make cleaner templates and to avoid to copy/paste some codes.

So we've now covered the basis of the template engine of Play Framework. With all that we've seen, we can start to create simple Play Applications.

A really good resources for Play Developer is the Play Cheat Sheet. You can also consult the official documentation for more complete informations.

Comments

Comments powered by Disqus