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


The args tag declare variables used in the template.

@args String var1, int var2, ...;

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.


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")


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" : '')">


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

@errors() {

The tag defines implicit variables in its body.

@errorList() {
    <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.

@errorList("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



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 ? "" : "-")

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


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!


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