Community contributed extensions

PlayRythm User Guide

PlayRythm provides an alternative template processing engine for Play!Framework. The template engine uses Java as an expression language. A powerful tag system allows you to create reusable functions.

Unless marked explicitly, the content documented here also applies to using Rythm separately in a pure Java computing context (i.e. non-play environment).

Template Syntax

A template file is a text file, some parts of which have placeholders for dynamically generated content. The template’s dynamic elements are written using the Java language.

Dynamic elements are resolved during template execution. The rendered result is then sent as part of the HTTP response.

All template elements are started with the @ caret.

If you want to output a literal "@" character, you need to double it. E.g.

This is an email address in template: someone@@gmail.com

Comments

one line comment start with @//

@// this is one line comment

multiple lines comment are put inside @ * * @ block. yes it is the same as the new scala template

@*
    this is a multiple line comment.
    The text inside this block will be ignore by Rythm template processor
*@

Expressions

@user.name @// evaluate user's name property and print it out
@user.getName(), @// call a method on an object and print out the result

The bracket “( )” can be used to compose complicated expressions or to separate an expression from other part of the template:

@(1 + 5) @// print out the result of 1 + 5
@(user.name)_and_some_other_string @// use ( ) to separate expression from other part of the template

Null safe expression

You can use ? to create null safe expression:

@foo?.bar?.bee()

The above expression will not throw out NullPointerException if foo or foo.bar is null.

You cannot embed null safe expression into parameters like @foo?.bar(@x?.y)

Properties enhancement

This is Play-Rythm specific feature. To make it consistent with Play convention, calling to an application class instance public property will automatically get translated to the corresponding get/set method:

@myModel.name //@ equals to @myModel.getName()
@{myModel.name = "foo"} //@ equals to @{myModel.setName("foo")}

Properties enhancement is NOT like JavaBean invokation as documented in Velocity Case Subsitituion. It only happen when your model has a public field called “name”, otherwise the above statement will fail.

Escape an expression

Unlike Groovy template which all expressions are escaped by default, Rythm template won’t do that due to performance concern. You must explicitly call escape java object extension to escape the variable:

Start from v1.0, PlayRythm escape expressions automatically as html format if the template file name suffix is “.html”. To output an expression by raw data, one can do:

@myVar.raw()

If you have a block of code that you would like to turn of the default escape behavior, you can use

@raw() {
    echo @myVar @// this will not be escaped
}

In addition to HTML escape, PlayRythm provides escape to the following format as well:

  1. CSV: escape as csv format
  2. JS/JavaScript: escape as javascript format
  3. Java: escape as Java format
  4. XML: escape as XML format

And the user can use to these format like follows:

@{String s = "<a><b>foo</b></a>"}
@escape("XML") {
 @s
}

You can also use JavaExtensions to escape variable directly

@s.escapeXml()

Corresponding JavaExtension methods to escape formats are:

  1. CSV: escapeCsv()
  2. HTML: escapeHtml()
  3. Java: escapeJava()
  4. JavaScript: escapeJavaScript()

Call built-in function

@ is also used to invoke built-in functions. Built-in function could be treated as special type of tags. From the user’s perspective there is no difference between calling a built-in function and calling a tag (either built-in or custom)

@// indicate this template extends "/main.html" template
@extends(main)
 
@// declare the java package/classes needed in this template
@import play.util.*, play.templates.*
 
@// declare arguments used in this template
@args String name, int score
 
@// output some information for debugging purpose
@debug("the variable is %s", someVariable)

There are more than a dozen of built-in functions defined in Rythm, please go to Reference for details

Call user defined tag

Again @ can be used to call a user defined tag:

@greenscript("app<jqueryui<jquery", all:true)

The “tag” in Rythm is kind like “macro” in Velocity and WebMacro, which provides a way to enable template content reuse at runtime. However Rythm tag facility are more powerful than macro in Velocity and FreeMarker. See Tag invocation for more information. In addition, Rythm (start from 1.0 RC5) provides @macro and @exec for parsing time content reuse.

Tag or expression?

Because Rythm template engine use the same caret @ for both expression evaluation and tag invocation, there might be name conflict between invoking a tag and evaluating an expression. However in most cases this conflict could avoid. Suppose you have a tag file named hello.html, and you have a template defined with hello variable declared:

@args String hello;
@hello  @// this will evaluate the hello variable
@hello() @// this will invoke hello tag

But consider another case, when you have a tag file hello.html defined in a folder named who, and you happened to have a variable named who in a type Who which has a method named hello, then

@args Who who
@who.hello() @// name conflict happened here!

In the above code, rythm will not evaluate the method hello of variable who, instead the who.hello tag is invoked.

Scripting

Use @{...} to include arbitrary java source code into your template:

@{
    String fullName = client.name.toUpperCase() + " " + client.forname;
}
<h1>Client @fullName</h1>

A script can write dynamic content directly using p() function:

@{
    String fullName = client.name.toUpperCase() + " " + client.forname;
    p("<h1>").p(fullName).p("</h1>");
}

Bear in mind that a template is not a place to do complex things. So, use a tag when you can, or move the computations into the controller or the model object.

Process template content with decoration functions

Rythm 1.0 provides a useful feature to allow you to further process template content using decoration functions:

Tag in Rythm

Tag in Rythm is a powerful tool to reuse your template design. In Velocity and FreeMarker reusing is achieved via a tool named Macro. A Macro is roughly equals to inline tag provided in Rythm. Tag, however is much more powerful than it, and here enumerate some of the Tag advantages over Macro

So check more on

Tag invocation

Tag is a powerful tool to reuse your template definition in Rythm. To invoke a tag, use @ plus tag name and brace

@// call greenscript.js tag using parameters to declare a list of javascript files and output them all
@greenscript.js("app<jqueryui<jquery", all:true)
 
@// call verbatim tag with a tag body instead of parameters
@verbatim() {
    the content within verbatim body will not get parsed by Rythm
    @foo.bar()
}

You must append () to tag name even it does not require any parameter. The only exception to this rule is @return, @break and @continue. Because these three are Java reserved words and one cannot use them as variable/method names.

[Tip] You can recursively call the current tag with @this directive.

Call tag using relative and import path

Start from v1.0 you were able to invoke tag use relative path and import path. So suppose you have the following file system structure:

\---app
    \---rythm
        |   tag1.html
        |
        +---Application
        |   |   index.html
        |   |   tagA.html
        |   |
        |   \---bar
        |           tagB.html
        |
        \---foo
            |   tag2.html
            |
            \---zee
                    tag3.html

Now inside your app/rythm/Application/index.html, you call those tags like follows:

@Application.tagA() @// full path invocation
@Application.bar.tagB() @// full path invocation
@tagA() @// relative path invocation
@bar.tagB() @// relative path invocation

You can also save typing by using @import path:

@import foo.*
 
@foo.tag2() @// full path invocation
@foo.zee.tag3() @// full path invocation
@tag2() @// import path invocation
@zee.tag3() @// import path invocation

imports and relative path also apply to action invocation:

@import controllers.*
 
@Application.index()

To use import path you must explicitly import the packages, implicit imports has no effects.

Passing arguments to tag

Suppose you have defined a tag file hello.html:

@args String title, String who
 
Hello @title @who

And in another template you want to invoke hello.html. Like groovy template, you can pass an argument to a tag by name:

@hello(title = "Mr.", who = "Green")

or this is also good:

@hello(title: "Mr.", who: "Green")

Start from v1.0.0-20120808 you can have line breaks inside parameters:

@hello(
    title: "Mr",
    who: "Green")

Or using JavaScript style:

@hello({
    title: "Mr",
    who: "Green"
})

Unlike groovy template, you are free to pass arguments to tag by position in Rythm template:

@hello("Mr.", "Green")

Or even a mix of both:

@hello("Mr.", who: "Green")

Controller action invocation is a special kind of tag invocation. However you should NOT pass arguments by name when you invoke a controller action, instead, always pass argument by position when you invoke a controller action

Call a tag with body

To invoke tag with a body, just use the common { } to include the body content:

@greenscript.js() {
    $(function(){
        // do whatever needed
    })
}

Tag body is called “nested content” in FreeMarker.

Passing body to a controller action invocation has no effect.

Pass body callback parameter spec to tag call

With the introduction of callback extension, Rythm make it possible to pass in parameters when callback tag body:

@lookupRole(permission: "superuser").callback(List<Role> roleList) {
    <ul>superusers
    @for(Role role: roleList) {
        <li>role.getName()</li>
    }
    </ul>
}

and in your lookupRole tag:

@args String permission
 
@{
    List<Role> roles = Role.find("permission", permission).asList()
}
renderBody(roles)

Although callback could be used with a controller action invocation, however since there will be no way to callback a tag body, it will not function anyway

Tag invocation decoration

Rythm 1.0 add a feature called tag invocation decoration which allows you to manipulate the tag invocation result:

Tag invocation decoration feature is also available to an arbitrary template block via the @chain built-int tag

Tag invocation decoration features only process runtime result and thus is NOT available to @include built-in tag because it is evaluated at parsing time and executed at code generating time. For the same reason they are not applicable to Inline tags because inline tags are actually member functions of the underline template class, calling to inline tag are static linked.

Escape tag invocation result

It is possible to escape tag invocation result using specific format

@myTag().escape("csv")

escape tag invocation result is different from escape a template block contain the tag invocation.

@escape("csv") {
    @myTag()
}

The above code makes sure all expressions output within myTag call will be escaped using “csv” format, while @myTag().escape(“csv”) ensure the tag invocation result itself get escaped.

Cache tag invocation result

Start from v1.0 you can cache tag invocation result easily

@myTag(1, 2, "3").cache() @// cache using default TTL, which is 1 hour
@myTag(1, 2, "3").cache("1h") @// cache invocation result for 1 hour
@myTag(1, 2, "3").cache(60 * 60) @// cache invocation result for 1 hour

The above statement invoke tag myTag using parameter [1, 2, “3”] and cache the result for one hour. Within the next one hour, the tag will not be invoked, instead the cached result will be returned if the parameter passed in are still [1, 2, “3”].

So you see Rythm is smart enough to cache tag invocation against tag name and the parameter passed in. If the tag has body, the body will also be taken into consideration when calculating the cache key.

In some cases where the tag invocation result is not merely a function of the tag, parameter and body, but also some implicit variables, where you might expect different result even you have completely the same signature of tag invocation. Rythm provide way for you to take those additional implicit variable into account when calculating the cache key:

@{User user = User.current()}
@myTag(1, 2, "3").cache("1h", user.isAdmin())

The above statement shows how to pass additional parameter to cache decoration.

Also refer to @cache keyword for more on cache parameters

Assign tag invocation result

With .assign() extension it can assign the tag invocation result to a template variable for further processing or delayed output:

@tagX().assign("xResult")

Now you have a template variable xResult contains the content of tagX tag. You can process it and output it later on:

@xResult.toLowerCase().raw()

You can assign tag execution result to a final variable by passing additional parameter to assign extension:

@tagX().assign("xResult", true)

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

Chain tag invocation decoration functions

It is possible to chain tag invocation extension functions in one statement:

@tagX().raw().cache("1h").assign("xResult").callback(String name) {
    echo @name
}

Dynamic tag invocation

Dynamic tag invocation means the tag to be invoked is determined by a runtime variable, in this case, one can use @invoke keyword as shown below:

@args String platform @// could be pc, iphone, ipad ...
...
@invoke("designer." + platform)

So when platform is iphone, the above case has the same effect as calling @designer.iphone().

Usually when a tag been invoked cannot be found, Rythm will report an error. Sometimes it is expected that certain template/tag does not exists, in which case one can use .ignoreNonExistsTag() extension with invoke keyword:

Relative path/import path invocation and cache features also available to @invoke tag invocation

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

Invoke controller action method (Play specific)

It’s possible to invoke controller action method directly from within the template and fill the render result content in place:

@controllers.MyPortal.welcomePanel()

The above statement will invoke the controller @controller.MyPortal's action method welcomePanel, and fill the render result content in place of the statement

Because controller action invocation are treated as tag invocation, therefore caching tag invocation result also applies to controller action invocation. Please refer to Cache tag invocation result for details

See integration guide for more detail about invoking controller action method

Create tags

You can easily create specific tags for your application. Every template can be invoked as a tag. The template’s file path start from template root (in Play context it’s app/rythm) mapped into tag name by striping off the file extension and converting all path separator / into the dot ..

For example suppose you have a template with the following content located at app/rythm/util/hello.html:

Hello from tag!

From the any other template or even the template itself you can invoke the template as a tag:

@util.hello() @// the brace () is a must to call a tag

Retrieve tag parameters

Tag parameters are exposed as template variables which declared using @args tag.

For example:

@args String name
Hello @name !

And you can pass the name parameter to the tag:

@util.hello(name: "Bob")

or to pass parameter by position:

@util.hello("Bob")

Callback tag body

If your tag supports a body, you can include it at any point in the tag code, using the @renderBody() keyword.

For example:

Hello @doBody()! @// or Hello @renderBody()!

And you can then pass the name as tag body:

@util.hello() {
   Bob
}

Callback tag body with parameters

Rythm v1.0 support a new feature to callback tag body with parameters:

@doBody("superuser")

See Invoke tag with body to see how to invoke a tag which will callback body with parameters

Invoking a tag is different from callback tag body. The former is used by app developer (tag consumer) and the latter is used by tag developer (tag producer)

Pickup tag file based on content format

Like groovy template, you can have different versions of tag for different content types:

// javascript code to request a html page
$.get("/ui/userManager", function(data) {
   $('#manager-panel').html(data);
})
 
// javascript code to request a JSON data
$.getJSON("/data/userList", function(data)) {
   model.users = ko.mapping.fromJS(data);
}

Suppose both request will result in a tag invocation @user.list() in the template code as below:

//@ template code
@args List<User> users
...
@user.list()
...

When you have normal html page request, Rythm will try to look for app/rythm/user/list.html file when doing the tag invocation. If the request is for a json data, Rythm will pickup app/rythm/user/list.json first. If the preferred tag file cannot be found, then Rythm look for tag file for other formats in the following sequence:

  1. *.html
  2. *.json
  3. *.xml
  4. *.csv
  5. *.tag

Define inline tags

Rythm provides inline tag definition to achieve a lightweight and light speed reuse method in one template.

@def sayHello(String who, String title) {
  <p>Hello, @title @who</p>
}

And in the same template you can call the tag defined as usual:

@for (User user: users) {
  @sayHello(user.name, user.title)
}

Inline tag definition is some how like helper tool in Razor engine. With the @include you can easily reuse inline tag definition across multiple templates

Normal tag invocation decoration functions cannot be used on inline tag directly. But there are corresponding workaround for each decoration function to use:

@myInlineTag().cache("3h") @// this is NOT okay
@// the following is good
@cache("3h") {
    @myInlineTag()
}
@myInlineTag().raw().assign("myResult") @// this is NOT okay
@// the following is good
@chain().raw().assign("myResult") {
    @myInlineTag()
}

You cannot pass argument by name when invoking inline tag. ALWAYS pass parameter to inline tag by position:

@myInlineTag(varName: "value") @// this will cause compilation error
@myInlineTag("value") @// this is okay

Define return type of inline tag

Starting from v1.0.0-RC9 it can define return type of the inline tag:

@def boolean isMobile() {
@{ [script block no longer needed for inline tag with return type other than void]
UserAgent ua = getRenderArg(“userAgent”);
return ua.isMobile();
}
}

And later on it can be used as:

@if (isMobile()) {
   @mobileTag()
} else {
   @pcTag()
}

So this actually the scope from defining an inline tag to defining a reusable method. This feature allows developer to actually extends a template class and greatly improve the reusability.

The cool part of this feature is it allows developer to define inline tag in the parent (layout) template and used in the descendant templates. Furthermore, the inline tag method is also available to templates which included the template defined it.

Start from version 1.0.0-20121103, if an inline tag has return type other than void, the code inside tag body shall NOT be enclosed with @{", } pair. And Rythm is now intelligent to determine whether an inline tag is defined with return type of not, and hence makes proper process to the handling code:

@def foo() {
<p>Foo</p>
}
@def String bar() {
return "bar"
}
@foo() @// output foo() in generated code
@bar() @// output p(bar()) in generated code

Custom Java tags

Honestly creating Java tag is not so important in Rythm as it is in Groovy because Rythm template is running so fast that it is almost like a handwriting StringBuilder appended java code. However you might still want to do it because the logic in that tag is complicated and it is more easier to code in a Java source code than in a text template source.

There are 2 ways to creating Custom Java tags.

The old Play FastTags approach (Play specific)

PlayRythm provides a bridge to intercept a rythm tag call to FastTags call. So you are free to continue define FastTags as you did for Groovy template. See http://www.playframework.org/documentation/1.2.4/templates#fasttags for more details on how to create FastTags.

Developer cannot use all stuffs in FastTags. The constraints include Closure parameter and TagContext etc.

Implement Java Tag using Rythm’s new Java Tag interface (Play specific)

Another approach is to implement Java Tag using Rythm’s new com.greenlaw110.rythm.play.FastRythmTag:

import com.greenlaw110.rythm.play.FastRythmTag;
 
@play.templates.FastTags.Namespace("") // yes, you use the same Namespace annotation in Rythm Fast Tag definition
public class authenticityToken extends FastRythmTag {
    @Override public void call(ParameterList params, Body body) {
        p("<input type=\"hidden\" name=\"authenticityToken\" value=\"" + Scope.Session.current().getAuthenticityToken() + "\">");
    }
}

The above code shows how to implement Play’s authenticityToken tag in Rythm.

Pros and Cons of the two approach

The good side of FastTags approach is it’s compatible to Groovy template, and thus should be welcome by module developers who don’t need a PlayRythm copy to get their code compileds and distributed.

The only tiny problem with FastTags is that it uses reflection to lookup the method to be called, which might be a little bit more time consuming than using Rythm’s tag interface

Create Java Tag in non-play environment

Pure rythm user can also implement Java based Tag easily:

  1. Create a Java class, say MyTag, extends com.greenlaw110.rythm.template.JavaTagBase
  2. Call RythmEngine.registerTag(JavaTagBase) interface to register your Java tag class
/**
 * The Hello tag accept a name and output "hello @name"
 */
public class Hello extends com.greenlaw110.rythm.template.JavaTagBase {
  
    public Hello() {
    }
  
    @Override
    public String getName() {
        return "hello";
    }
  
    @Override
    public void call(ITag.ParameterList params, Body body) {
        Object o = params.getDefault();
        String name = null == o ? "who" : o.toString()
        p("Hello ").p(name);
    }
}
...
// register your java tag somewhere in your bootstrap code
Rythm.engine.registerTag(new Hello());

To use the Hello tag in your template file:

@hello("Rythm")

And it outputs:

Hello Rythm

Include other templates

Rythm support include other template inline:

@include("foo.bar")

The above statement will put the content of template foo.bar in place. “foo.bar” is translate into file name following tag invocation convention.

The difference between @include(“foo.bar”) a tag and call the tag via @foo.bar() is the former put the content of the template into the current template inline, while the latter invoke the template specified. It is some how like #include vs. function call in c language. @include is super fast to reuse part of template because it suppress the function invocation at runtime. It’s a inline function call if you speak c++. In other words, @include process happen at template parsing time, while tag invocation happen at template executing time.

Things you can achieve with @include but not tag invocation:

Things you can achieve with tag invocation but not @include

If you switch tag invocation to @include and found something has changed even there is no parameter call it might because you have @extended layout template in the tag template. include will NOT be able to include the layout template parts

Because @include are parsed at parsing time therefore it’s not possible to include template dynamically as shown below:

@// spec could be one of facebook, google
@args String spec
 
@include("page." + spec) @// THIS WON'T WORK
@invoke("page." + spec) @// THIS WORKS!

It is also not possible to apply Java invocation decorations to @include() for the same reason.

@include("my.common.tag.lib").cache().assign("someVariable").raw() @// THIS WON'T WORK
@my.common.tag.lib().cache().assign("someVariable").raw() @// this works
@// the following also works
@chain().cache().assign("someVariable").raw() {
    @include("my.common.tag.lib")
}

Reuse inline tag across multiple views

A good feature provided with @include is that you can import the inline tag definition from the template been included into the current template:

Suppose you have created a template named app/rythm/util.html with a set of inline tags:

@tag hi (String who) {
    Hi @who
}
 
@tag bye (String who) {
    Bye @who
}

Now in your normal template you can import all the inline tags [hi, bye] and call them like a local function:

@include("util")
@hi("rythm")
@bye("rythm")

While @tag provides an alternative to Helper in Razor, the @include provides an alternative to Reusing @helpers across multiple views. See Scott’s blog and search for "reusing @helpers across multiple views"

Define and execute Macro

Like @include, macro provides a way to reuse template content at parsing time, but inside a template file. Suppose you defined a macro called “myMacro”:

@macro("myMacro") {
content inside myMacro
}

Later on in the same template file you can invoke “macro-1” using the following code:

@exec("myMacro")

which produce the following output:

content inside myMacro

At first glance this effect could be achieved using inline tag or even assignment. However they are fundamentally different in that macro executing happen at parsing time while tag invocation and assignment are happened at runtime, which could result in subtle differences of content been rendered. Let’s take a look at the following code:

@macro("foo") {
    <foo>
        <bar>abc</bar>
    </foo>
}
@compact() {@exec("foo")}
@nocompact() {@exec("foo")}

So the above code will display “foo” content in compact and nocompact mode. If we change the implementation to:

@assign("foo") {
    <foo>
        <bar>abc</bar>
    </foo>
}
@compact() {@foo}
@nocompact() {@foo}

The result will not be expected. The reason is assignment will evaluate the content at runtime, and when “foo” content is assigned, the content is already produced and later on calling it in @compact and @nocompact block will not make any change. For the same reason the following code works neither:

@def foo() {
    <foo>
        <bar>abc</bar>
    </foo>
}
@compact() {@foo()}
@nocompact() {@foo()}

Macro will be expanded at parsing time, therefore it is very fast at runtime but will generate larger class byte codes, furthermore macro will guaranteed to be executed when invoked with @exec, this is unlike @assign, which is executed for only once when assignment happen.

Other methods to execute macro

You can also use @expand to execute macro:

@expand(myMacro)

Start from v1.0.0-20120719 you can invoke macro like invoke a tag:

@myMacro()

Macro has higher priority than tag. Meaning if you have both “foo” macro and “foo” tag defined, @foo() will invoke foo macro instead of foo tag

Template inheritance

Template inheritance is a good way to implement template layout management.

@// this type of extended template declaration is deprecated: @extends("main.html")
@extends("main")
<h1>Some code</h1>

The main template is the layout template, you can use the doLayout tag to include the content of the declaring template:

<h1>Main template</h1>
<div id="content">
    @doLayout()
</div>

You can also use renderBody in place of doLayout to include the content, which comes from Razor. render or renderSection without section name specified does the same thing with @doLayout()

You can even specify the default content if the sub template does not have any content provided:

<h1>Main template</h1>
<div id="content">
    @doLayout() {
        default content
    }
</div>

Extended template lookup

Before PlayRythm v1.0 you follow the same rule as groovy #extends tag, i.e. you need to pass the full path to extended template file starting from app/rythm folder: @extends(“main.html”)

Since v1.0 you have a clean and simple way to declare extended template, i.e. the way to declare a tag invocation. For example, if you want to extend app/rythm/layout/foo/bar.html, you can declare the extend statement as @extends(“layout.foo.bar”).

The relative path and include path declaration feature are also available:

@import layout.foo.*
@extends("bar")

See Call tag using relative and import path for more information on path lookup

Because extends are parsed statically you can omit the quotation mark when declaring extended templates:

@extends(main)
@extends(layout.foo.bar)

Define section and output section

Like Razor, Rythm provides a section concept to enable you to define sections in sub templates and output them in parent template.

In your layout template, say main.html:

<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
  <div id="header">
    <h1>@get("title')</h1>
  </div>
 
  <div id="sidebar">
    @// render "sidebar" section
    @render("sidebar")
  </div>
 
  <div id="content">
    @// render main content
    @render() @// or doLayout()
  </div>
 
  <div id="footer">
    @render("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>
    }
  </div>
</body>
</html>

And in your working template, say ‘index.html’:

@extends(main)
@set(title="Home page")
 
<h2>Welcome to my site</h2>
<p>This is our home page</p>
<p>Not super exciting is it?</p>
<p>Yada, Yada, Yada</p>
 
@section("sidebar") { @// define "sidebar" section
  <p>This sidebar has "Home Page" specific content</p>
  <ul>
    <li><a href="#">Link One</a></li>
    <li><a href="#">Link Two</a></li>
    <li><a href="#">Link Three</a></li>
  </ul>
}

In the above example people with sharp eyes can notice that the footer section render in the layout template is different from the sidebar section in that we supplied a default content to the former. So if user did not define the footer section in the sub template, the default content will be output instead. This is an new feature available in v1.0

Java object extensions in templates

Rythm template provides limited support for Java object extensions.

  1. You are allowed to use most Java object extensions defined in Play’s @play.templates.JavaExtensions.
  2. Java object extensions can only be processed when they are in the end of an expression
<ul>
@for(Product product: products) {
    <li>@product.name. Price: @product.price.format("## ###,00") €</li>
}
</ul>

The following expressions will not work because Java object extension “.escape()” is used in the middle of the expression.

@(myVal.escape() + myVal2.toString())
@someString.escape().length()

However you can chain java object extensions like:

@myVal.escape().capAll()

In the above expression, java object extension capAll and escape is chained together and both of they will be processed.

<a name="custom-java-extension>Customized Java object extension

Start from Rythm 1.0.0-RC5, you can use application defined Java extensions. Refer to the play documentation to understand how to define application java extensions.

Implicit objects available in a template

Unlike Play’s Groovy template that all objects added to the renderArgs scope are directly injected as template variables, you must declare them (and might need to import their class packages) to use them freely in your template. PlayRythm plugin automatically declare and set the following implicit objects so that you don’t need to do these job before using them:

Variable Description API documentation See also
errors Validation errors play.data.validation.Validation.errors() Validating HTTP data
flash Flash scope play.mvc.Scope.Flash Controllers - Session & Flash Scope
lang The current language (in java.lang.String) play.i18n.Lang Setting up I18N - Define languages
messages The messages map play.i18n.Messages Setting up I18N - Externalize messages
params Current parameters play.mvc.Scope.Params Controllers - HTTP parameters
_play Main framework class play.Play
request The current HTTP request play.mvc.Http.Request
session Session scope play.mvc.Scope.Session Controllers - Session & Flash Scope
_response_encoding encoding of the response object play.mvc.Http.Response
_rythmPlugin the RythmPlugin instance com.greenlaw110.rythm.play.RythmPlugin
_rythm the rythm template engine instance com.greenlaw110.rythm.RythmEngine

So as you can see most of these implicit variables are the same as those defined in Groovy templates. The only exception is Groovy’s implicit variable play has been renamed to _play. The reason for this is I want to allow user to use full qualified classes in play.* package.

If you have put something into your RenderArgs, and you didn’t declare it using @args statement, you are still able to access it via getRenderArg() method. But please be noted that all stuff you get via getRenderArg() call are Object type, and you need to explicitly cast them before accessing properties and methods of them:

@(((User)getRenderArg("user")).getName())

Implicit import statements

PlayRythm automatically insert the following import statements so that user can reference relevant classes without write manually @import statement:

  1. java.util.*
  2. java.io.*
  3. controller.*
  4. models.*
  5. play.templates.JavaExtensions

See also

  1. References manual
  2. Integrate PlayRythm into your Play project