Templates

1.2.3

Template – Implicit objects

errors
The validation errors raised in the controller

flash
Flash scope

lang
The negotiated language

messages
The map of localised messages

out
The output stream writer

params
Current parameters

play
Main framework class

request
The current HTTP request

session
The session scope

Template – Tag grammar

${ client.name }
Evaluates and outputs a variable

${ client?.name }
Displays client.name only if client not null

@{ Controller.action() }
Calculates URL relative path to action

@{ Controller.action().secure() }
Calculates URL relative HTTPS path to action

@@{ Controller.action() }
Calculates URL absolute path to action

@{'path/to/static_content'}
<img src="@{'/public/images/jpdf.png'}" class="center"/>

&{ message.key }
Message are maintained in conf/messages, supports i18

∗{ this is a comment }∗
What else to say?

%{ out.print("HelloWorld") }%
Groovy scripts for UI logic

#{ my.custom.tag /}
A typical custom tag – page context not shared

Template – Standard Tags

#{extends ʻpage.htmlʼ/}
#{doLayout /}
Master template decorators

#{get 'title'}Used if title not set#{/get}
#{set title:ʻHome Pageʼ}
Shared variables between page and master templates

#{include 'tree.html'/}
Includes fragment – page context is shared

#{script id:'myscript' , src:ʻscript.js', charset:'utf-8' /}
#{stylesheet id:'main', media:'print', src:'print.css' /}
Imports script & styles in the page

#{a @Application.logout() }Disconnect#{/a}
#{form @Client.create() , id:'form' enctype:'multipart/form-
data' } ... #{/form}
Handy tags to create anchors and forms

#{verbatim}${'&'}#{/verbatim}
Disables HTML escaping

#{i18n /}
Exports localized messages in Javascript

#{ifErrors} <p>Error(s) found!</p> #{/ifErrors}
Checks for validation errors

#{ifError 'user.name'} #{error 'user.name' /} #{/ifError}
Checks a given error

#{errors} <li>${error}</li> #{/errors}
Iterates over the current validation errors

#{if cond}...#{/if}#{elseif cond}...#{/elseif}#{else}...#{/else}
#{ifnot cond}...#{/ifnot}
Conditional constructs

#{list items:0..10, as:'i'}${i}#{/list}
#{list items:'a'..'z', as:'l'}${l} ${l_isLast ?'':'|' }#{/list}
#{list users}${_}#{/list}
Loop constructs

#{list items:task, as:'task'}${task}#{/list}
#{else}No tasks on the list#{/else}
Tip: Else can be used along with list

#{cache ʻkeyʼ, for:ʼ15minʼ}...#{/cache}
Caches content for 15 minutes

Template – Custom Tags

@FastTags.Namespace("domain")
public class RecaptchaTag extends FastTags {
public static void _recaptcha(Map args, Closure body, PrintWriter out, ExecutableTemplate template, int fromLine) { …

/app/view/tags/domain/mytag.tag
Custom tag can be called as {#domain.mytag/}

Template – Groovy extension

${ ['red', 'green', 'blue'].join('/') }
red/green/blue

${ (["red", "green", "blue"] as String[]).add('pink').join(' ') }
red green blue pink

${ (['red', 'green', 'blue'] as String[]).contains('green') }
true

${(['red', 'gr', 'blue'] as String[]).remove('gr').join(' ')}
red blue

${ ['red', 'green', 'blue'].last() }
blue

${ new Date(new Date().getTime() - 1000000).since() }
16 minutes ago

${new Date(1275910970000).format('dd MMMM yyyy
hh:mm:ss')}
07 June 2010 01:42:50

${ 1275910970000.asdate('dd MMMM yyyy hh:mm:ss') }
07 June 2010 01:42:50

${726016L.formatSize()}
709KB

${ 42.formatCurrency('EUR').raw() }
&euro; 42.00

${ 42.page(10) }
5

journ${ ['cnn', 'c+', 'f2'].pluralize('al', 'aux') }
journaux

${ "lorum ipsum dolor".capAll() }
Lorum Ipsum Dolor

${ "lorum ipsum dolor".camelCase() }
LorumIpsumDolor

${ "lorum ipsum dolor".capFirst() }
Lorum ipsum dolor

${ "lorum ipsum dolor".cut('um') }
lor ips dolor

${ "The <blink>tag</blink> is evil".escape().raw() }
The &lt;blink&gt;tag&lt;/blink&gt; is evil

${ "one\ntwo".nl2br() }
one<br/>two

${ '<' } ${ '<'.raw() }
&lt; <

${ " (') (\") ".escapeJavaScript().raw() }
(\') (\")

${ "".yesno('yes', 'no') }
no

${ "not empty".yesno('yes', 'no') }
yes

${"Stéphane Épardaud".noAccents()}
Stephane Epardaud

${ "The Play! frameworkʼs manual".slugify() }
the-play-framework-s-manual

${ "x".pad(4).raw() }
x&nbsp;&nbsp;&nbsp;