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.

Templates are stored in app/views directory, user defined tags are stored in app/views/tags/rythm directory by default. But both location could be configured. See Configuration Reference

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

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:

@myVar.escape()

If you want to escape variables in the middle of an expression, you must call JavaExtensions.escape:

@(JavaExtensions.escape(myVar) + "some other stuff")

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.html)
 
@// 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 about a dozen of built-in functions defined in Rythm, please go to Reference for details

Invoke tag

Yes “@” is also used to invoke tags:

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

Call a tag with body

To invoke tag which accept body, the user just use the common { } to include the body content:

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

Rythm also support the here document style symbol to mark tag body:

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

hmm... the here document style is my favorite however ;-)

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

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

@hello("Mr.", "Green)

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 "{" and "}" 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>");
}@

You can use a script to create a structure such as an iteration in your template:

<h1>Client @client.name</h1>
<ul>
@{
     for(Account account: client.accounts) {
}@
     <li>@account</li>
@{
     }
}@
</ul>

However, this is not encouraged because you have much more clean and powerful @for tag to use:

<h1>Client @client.name</h1>
<ul>
@for (Account account: client.accounts) {
    <li class="@account_parity">@account</li>
}
</ul>

Also 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.

Template inheritance

A template can inherit another template, i.e. it can be included as a part of an other template.

To inherit another template, use the @extends tag:

@extends(/main.html)
 
<h1>Some code</h1>

The main.html template is a standard template, but it uses the doLayout tag to include the content:

<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

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 parent template, say ‘main.html’:

<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
 
  <div id="header">
    <h1>@get("title')</h1>
  </div>
  
  <div id="sidebar">
    @renderSection("sidebar")
  </div>
  
  <div id="content">
    @renderBody()
  </div>
  
  <div id="footer">
    <p>Site footer - &copy; Santa Clause</p>
  </div>
  
</body>
</html>

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

@extends(/main.html)
 
@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 {
  <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>
}

Custom Tags

You can easily create specific tags for your application. A tag is a simple template file, stored in the app/views/tags/rythm directory. The template’s file name is used as the tag name.

To create a hello tag, just create the app/views/tags/rythm/hello.html file.

Hello from tag!

No need to configure anything. You can use the tag directly:

@hello

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:

@hello(name: "Bob")

or to pass parameter by position:

@hello("Bob")

Invoke tag body

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

For example:

Hello @_body!

And you can then pass the name as tag body:

@hello {
   Bob
}

Format-specific tags

In play’s groovy template, you can have different versions of tag for different content types. This is not supported in PlayRythm yet. There is a plan to add the support to content type based tag selection.

Define inline tags

There is no inline tag concept in Groovy (The #{set...} and #{get ..} tag could be used to implement static content include). Rythm provides inline tag definition to achieve a lightweight and light speed reuse method in one template.

@tag 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. At the moment Rythm does not support reuse inline tags across templates. With the support of @include tag implemented, reusing inline tags across templates will be very easy.

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

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

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

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.

Customized Java object extension

This is not supported at the moment but is a planned feature.

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

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 _properties variable. But please be noted that all stuff you get from _properties are Object type, and you need to explicitly cast them before accessing properties and methods of them:

@(((User)_properties.get("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