Community contributed extensions

PlayRythm Reference

Built-in Tags


Play specific tag. Lookup message string.


The above has the same effect of the following groovy template code:


You can also pass parameters:

@msg("some.message", "param1")


Play specific tag. Reverse lookup URL.


The above code is equal to the following groovy template code:


You can also reverse lookup static url



Play specific tag. Absolute reverse lookup URL.


The above code is equal to the following groovy template code:



Assign the enclosed block into a variable.

@assign("roleSelector") {
@for(Role role: Role.findAll()){
<option value="@role.getId()">role.toString()</option>
<label>select role</label>

The variable name specified in @assign must be unique across the context where @assign is put in. Otherwise you will expect a compilation exception

assign to a final variable

To assign to a final variable pass the second parameter true:

@assign("roleSelector", true) {
@for(Role role: Role.findAll()){
<option value="@role.getId()">role.toString()</option>

The benefit of final variable is that you can use it directly inside @for loop.


The args tag declare variables used in the template.

@args String var1, int var2, ...

or declare render arguments in multiple lines (start from 1.0.0-RC7):

@args {
    String var1, int var2
    boolean var3

args is one of few tags that are not invoked in @tag(...) style. At the moment please use “;” to terminate args statement. This limitation will be removed in the future, and line-break could be an natural way to terminate the statement

You can have any arbitrary number of args statement in any where of your template, all variables declared will be effective in your template.


PlayRythm specific tag. This is a clone of the authenticityToken tag in Play’s groovy template.


Rendered as:

<input type="hidden" name="authenticityToken"


PlayRythm specific tag. Use authenticityTokenValue when you want to put the authenticity token value inside a javascript code in your view:

    {authenticityToken: '@authenticityTokenValue()', ...},

Rendered as:

    {authenticityToken: "1c6d92fed96200347f06b7c5e1a3a28fa258ef7c", ...},


Break @for loop

@for(User user: users) {
	@if(theUserId.equals(user.getId())) {


Caches the tag body or use cached tag body

@cache("5min") {
    <p>This content will be cached for 5 minutes</p>
    including calling to any tags like:


@cache(null, new Random().nextInt()) {
    <p>[@(new Date().getTime())]this content will literally looks like not cached at all because the cache key changes every time</p>

Be cautious when you use @cache() with template blocks contains dynamic content or nested dynamic content via @include() or tag invocation. Cache key is calculated literally based on the content at parsing time, while dynamic content might changes at runtime. The rule of thumb is: if content or nested content via tag invocation or include varies dynamically, do not cache it, or you cache it and pass all variables used across the content and nested content via tag invocation and include directive

The cache decoration to tag invocation is safer than the @cache() directive, because “cache decoration” will check parameter value at runtime when generating cache key:

@myTag(someVariable).cache("1h") // safer cache, cache key will vary if someVariable value changes
@cache("1h"){ // even someVariable value changed, the cache key will be the same so the output will remain unchanged

h3. cacheOnProd

Same as “cache”, but cache happens only when play.Play.mode is "prod".

cacheOnProd is no longer available in v1.0. Use @cache instead. However
you can configure rythm not to cache in dev mode by using rythm.cache.prodOnly setting.
By default rythm.cache.prodOnly is set to true so cache is not enabled at dev mode


Chain the following decoration functions together:

  1. cache
  2. escape
  3. raw
  4. assign

In the example of assign, you found that it always needs to call raw() when you want to use the variable get assigned, by using chain you can do it at one time:

@chain.raw().assign("roleSelector") {
@for(Role role: Role.findAll()){
<option value="@role.getId()">role.toString()</option>
<label>select role</label>
@roleSelector @// no longer need raw() extension any more

And you even add cache() into the chain:

@chain.raw().assign("roleSelector").cache() {

The order of the chained function doesn’t matter as they are orthogonal concerns.


Mark a block of template to be output in compact mode without regarding to the global compact setting.

@compact() {
   All content here will be output
   in compact mode.

The above code will output the following content:

All content here will be output in compact mode

See also nocompact.


Continue current loop:

@for (User user: users) {
    @if (user.isAdmin()) {


AKA @tag, define an inline tag (helper in Razor, macro in velocity and freemarker) which can be invoked from within the same template, the parent template or children templates

@def sayHi(String who) {
    Hi @who

To use the tag defined just follow the common way:


or pass argument by name:

@sayHi(who: "Play!framework")

Inline tag must be defined before the invocation code. Otherwise you might get compilation error.

Define return type of inline tag:

@def boolean isMobile() {
        UserAgent ua = getRenderArg("userAgent");
        return ua.isMobile();

And later on it can be used as:

@if (isMobile()) {
} else {

See “defining inline tag” in the user guide


Used with template inheritance, this tag inserts the evaluated sub-template’s contents.

<!-- common header here -->
<div id="content">
<!-- common footer here -->

doLayout tag is an alias of render tag

An easier and clean way to @doLayout() is @render()

See also template inheritance


An alias of renderBody


PlayRythm specific tag. Outputs the validation error message, if present, for the field specified by the tag parameter.


You can use the optional parameter to use a different field’s error message. This is useful when you want several fields to share a common error message.

@error("contact.street", "contact.address")
@error("", "contact.address")
@error("", "contact.address")


PlayRythm specific tag. Outputs the text hasError if there is a validation error for the field specified by the tag parameter. This is useful for setting a CSS class for input fields with errors:

<input name="name" class="@errorClass("name")">

which is equivalent to:

<input name="name" class="@("name") ? "hasError" : '')">


Alias of errors. See below.


Corresponding to Groovy template’s errors. Iterates over the current validation errors.

@errors() {

The tag defines implicit variables in its body.

@errors() {
    <tr class="@error_parity"><td>@error_index</td><td>@error</td></tr>

You can also use the optional field parameter, or just the default parameter, to filter only the errors belonging to a certain field.

@errors("myField") {
    There where errors with the field myField<br />


Mark a block of template code default escape scheme:

    alert("Hello Rythm");

The above code set the default escape to JavaScript. The parameter passed to @escape() could be one of the following:

  1. RAW – do not escape. Same effect with @raw()
  2. CSV – escape as csv format
  3. HTML – escape as html format
  4. JS | JavaScript – escape as JavaScript format
  5. JAVA – escape as Java format
  6. XML – escape as XML format



Execute an macro. AKA exec.


See also Define and execute Macro


Expand an macro. AKA exec.


See also Define and execute Macro


Makes the template inherit another template.




You can pass parameter to extended template if the there are arguments declared.

Suppose you have a parent template defined as:

@args String style;
<div class="panel @style">

And in your extending template, you pass the argument style as:

@extends(panel, style: "span4")

or pass by position:

@extends(panel, "span4")


You can use debug tag to output debug message to your log file or screen:

@debug("this is a debug message for %s", myvar)


Use for to iterate a collection of objects. The syntax is the same as for loop in Java language:

@for (Product product: products) {

The tag defines implicit variables in it’s body. The variable names are prefixed with loop variable name:

@for (Product product: products) {
    <li class="@product_parity">@product_index. @product</li>
    @(product_isLast ? "" : "-")

If you refer to a local variable inside the loop, you need to make sure they are declared as final:

 String foo = "foo";
 final String bar = foo;
@for(MyModel model: myModels) {
    <p>@bar</p> @// this is okay
    <p>@foo</p> @// this line will cause compilation error

You can also use the second form of @for tag:

@for(int i = 0; i < 6; ++i) {
    <li>the current index is @i</li>


Retrieves value defined with a set tag. You may use the get/set mechanism to exchange values between templates, layouts and sub-templates.


You can provide a default value in the following way, which will display “Homepage”, if title has not been specified:

    <title>@get("title": "Homepage")</title>


Evaluates a given test, and if true, evaluate the tag body. The syntax is the same as if clause in Java language

@if ("en".equals(user.countryCode)) {
    Connect user is @user

You can also use else clause:

@if (null != user) {
    Connected user is @user
} else {
    Please log in

or else if clause

@if (tasks.size() > 1) {
    Busy tasklist
} else if (tasks.size() > 0) {
    One task in the list
} else {
    Nothing to do


Import package or class.

@import java.awt.*,*,...

or declare import statements in multiple lines (start from 1.0.0-RC7):

@import {
    static java.lang.Math.*


Do an inline include a template into the current template:


See Include other templates section for details


Enable dynamic tag invocation:

@invoke("designer." + platform).ignoreNonExistsTag()

See Dynamic tag invocation section for details4


@jsAction() is a play specific tag that returns a JavaScript function which constructs a URL based on a server action and free variables. It does not perform an AJAX request; these have to be done by hand using the returned URL.

Let’s see an example:

GET     /users/{id}

Now you can import this route client side:

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

Note at the moment @jsAction() tag in PlayRythm is no as convenient to use as the groovy #{jsAction /} tag that you must use a special @assign statement to get the url reverse lookup result before passing it to the @jsAction() tag:

var showUserAction = @jsAction(showUserUrl)

It’s desired the syntax could be simplified as:

var showUserAction = @jsAction(":id")) @// note this has NOT been implemented yet!


Define a template macro.

@macro() {
    macro content

See also @exec and Define and execute Macro


Mark a block of template to be output NOT in compact mode without regarding to the global compact setting.

@nocompact() {
All content here will be output
in nocompact mode.

The above code will output the following content:

All content here will be output
in compact mode

See also compact.


AKA doBody, renderBody is an alias of doLayout. is used to render the tag body.


If tag body is supplied along with callback extension, then you can pass parameters into renderBody call:


or by name:

@renderBody(role: user.role)


AKA renderSection and doLayout, used with template inheritance, this tag inserts the evaluated sub-template’s contents defined with section tag

<div id="sidebar">

When no section name specified this tag output the layout content:

@render() @// also @doLayout(), same effect as groovy's #{doLayout/}

Start from v1.0.0 Rythm support define default content for section:

<div id="footer">
    @renderSection("footer") {
        @// here we define default content for footer section
        @// if sub template failed to supply this section then
        @// the default content will be output instead
        <p>Site footer - &copy; Santa Clause</p>


Abort the template execution and return to caller:

@if(!user.isAdmin()) {
<p class="admin-panel">...


Define a block of template to be output in parent template’s named section.

@section("sidebar") {
        <li><a href="#">Link one</li>
        <li><a href="#">Link two</li>


Define a value which can be retrieved in the same template or any layout with the get tag.

@set(title: "Admin")
@set(style: "span6")

You can use any expression in set tag

@set(title:"Profile of " + user.login)

Unlike set tag in Groovy template engine, Rythm set tag does not accept tag body. You can use section tag to achieve the same result.


Alias of @def()

@tag is not used to invoke a tag. Check the user guide to see how to invoke a tag.


Call the current template itself as a tag

@args int max, int i, int j
@i @if (j < max) {
        int t = i;
        i = j;
        j = i + t;
    , @this(max, i, j) @// recursively call to this template
} else {
    <h3>Fibonacci tag template source</h3>
    <h3>Fibonacci tag java source</h3>


Mark a block of template code that by default output raw data for expression:

    String title = "<h1>title</h1>";
    String body = "<p>some news</p";
@raw() {

The above code has the same effect as below

    String title = "<h1>title</h1>";
    String body = "<p>some news</p>";


Output timestamp in place

now is @ts() @// produce somethign like "now is 134325875435"


Define a block of code that not to be parsed by Rythm.

@verbatim() {
    OK, anything inside this block is not parsed: @someTag, @someExpression, etc


Mark the current template as a simple template. A simple template is slightly faster than normal template and has the following constraint:

PlayRythm Configuration

PlayRythm provides all default configuration settings that cater for most common use cases.

configuration description default value
rythm.modeset rythm template engine to run in dev or prod modethe value of play.mode
rythm.compactOutputremove redundant space and line breakstrue in prod mode and false in dev mode
rythm.enableJavaExtensionsenable Java extension parsingtrue

See Also

  1. Integrate PlayRythm into your Play project
  2. Rythm Template User guide