You are viewing the documentation for Play 1. The documentation for Play 2 is here.

Play 1.0.1 — Release notes

play 1.0.1 is a maintenance release of the play 1.0 branch. It fixes a lot of small bugs, provides a better binding for persistent JPA objects, auto-escaping of HTML and Javascript code in templates to avoid XSS security problems.

play 1.0.1 is a maintenance release and is fully compatible with the 1.0 version. If you encounter any problems please ask us on the Google Group.

You can read about the fixed bugs on the 1.0.1 roadmap page. The most important changes are highlighted in this page:

Automatic escape of HTML code in templates

Now all dynamic expressions are escaped by the template engine to avoid XSS security issues in your application. So the title variable containing <h1>Title</h1> is now escaped:

${title} --> &lt;h1&gt;Title&lt;/h1&gt;

If you really want to display it in an unescaped way, you need to explicitely call the raw() method:

${title.raw()} --> <h1>Title</h1>

Also, if you want to display a large part of raw HTML, you can use the #{verbatim /} tag:

    ${title} --> <h1>Title</h1>

Of course, as this feature can break existing applications, it is not enabled by default. You can enable it by adding the following line to your application.conf file:


This line is added to new applications created with the 1.0.1 release.

@javax.inject.Inject support

You can now use the @Inject annotation if you are using a Dependency Injection container like the one provided by the Spring module. The the @Inject annotation automatically injects defined beans in your controllers, jobs and mailer. It works on static fields.

For example to inject a PriceWatcher service defined in Spring to one of your controller, just do:

public class Application extends Controller {
    static PriceWatcher prices;
    public static void index() {
        prices.getAll(); // prices is defined here

Auto-reload should work as expected.

Better binding for JPA objects

Previously there was no way to automatically bind a JPA object using the HTTP to Java binding. For example:

public static void save(User user) {; // fail in 1.0

User being a JPA entity class, this code failed because user was a transient object created by the Binder and not yet managed by Hibernate.

The old way was to use the edit() method, like:

public static void save(Long id) {
    User user = User.findById(id);
    user.edit(params);; // ok

Now you can provide the field yourself in the HTTP parameters. When Play find the id field, it loads the matching instance from the database before editing it. The other parameters provided by the HTTP request are then applied. So you can save it directly.

public static void save(User user) {; // ok with 1.0.1

Of course as this feature can break existing applications it is not enabled by default. You can enable it by adding the followin line to your application.conf file:


This line is added to new applications created with the 1.0.1 release.

Framework id can be set from the command line

The framework id allows you to run different configurations for a same play! application (ie dev, test, staging, production, etc...).

Using the command line, you can now specify the application framework id the application will use. For example, to run an application in production mode:

play run --%production

With these lines defined in the application.conf file:


It is compatible with all the existing commands using the framework id information. The default id is still defined using the play id command.

By the way ,play test is then equivalent to:

play run --%test

Custom validation

You don’t find the validator you need in the package? Write your own. You can use the generic @CheckWith annotation to bind your own Check implementation.

For example:

public class User {
    public String password;
    static class MyPasswordCheck extends Check {
        public abstract boolean isSatisfied(Object user, Object password) {
            return notMatchPreviousPasswords(password);

Test runner update

We’ve updated selenium to the 1.0.1 final version and improved the UI. Selenium tests now run in fullscreen. And some new functionalities like the “Run all tests” have been added.

Also local documentation is now available when you run your application in test mode.

HTML5 as default doctype and JQuery in new applications

New applications come with a default HTML skeleton. Previously it was a XHTML 1.0 Transitional formatted HTML. Now it comes with a HTML5 doctype by default:

<!DOCTYPE html>
        <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.3.2.min.js'}" type="text/javascript" charset="utf-8"></script>
        #{get 'moreScripts' /}
        #{doLayout /}

It’s just the default and you can of course change it to any doctype if you wish. However HTML5 is surely the future and is way simpler.

The default template comes with the JQuery Javascript library. This is because modern web applications need a good Javascript framework and we love JQuery. Again it is just the default and you can of course override it with whatever Javascript library you want.

Oh, and it comes with 2 default placeholders to inject even more scripts and/or styles. For example, add in your view:

#{set 'moreScripts'}
<script src="@{'/public/javascripts/gears_init.js'}" type="text/javascript" ></script>

And the gear Javascript library will be accessible in your view.

Improved #{list} tag

The items parameter is now optional and can be replaced by the default arg argument.

So you can rewrite:

#{list items:users, as:'user'}


#{list users, as:'user'}

The as parameter is now optional as well. It uses _ as default variable name:

#{list users}

New #{jsAction /} tag

The #{jsAction /} tag allows to import a server-side defined route as a Javascript function. It is very useful if you need to call an URL with an AJAX call using free variables.

Let’s see an example:

GET     /users/{id}

Now you can import this route on the client side:

<script type="text/javascript">
    var showUserAction = #{jsAction':id')}
    var displayUserDetail = function(userId) {
        $('#userDetail').load( showUserAction({id: userId}) )

As you see you use the :ame syntax to declare free variables. You can mix free and fixed variables together. The #{jsAction /} tag generates a Javascript function. This function takes a Javascript object as parameter that must define all the free variables.

New sample application: 'booking'

The booking application is a port of the well known booking application from the JBoss seam framework.

It demonstrates how you can manage complex states client side in a RestFul way with a stateless web framework.

Eclipse plugin is on his way

We are working hard to provide a dedicated eclipse plugin. The current status is alpha but already usable. You can find it in the support/eclipse directory of your play installation.

Support for IntelliJ IDEA

Play! framework now supports IntelliJ IDEA out of the box!

To convert your Play! application into an IntelliJ IDEA project, use the idealize command:

# play idealize myApp

You can use the Run and Debug using the context menu.