Template tags in the play! framework are a simple, powerful way to share functionality between different pages. They have all the groovy goodness of regular templates, and you can pass variables into them easily.
But, as always, there’s always a but…
The functionality of the tags is determined by their implicit content and any parameters passed into them. Adding further configuration allows tags to have much more use as shared functions, but doing this is not obvious from the documentation.
As you can probably guess from the title, doing this is quick and easy.
The key comes from the play/groovy binding mechanism that allows variables to by dynamically declared.
Take the example of a vanilla tag which has a single argument, in a file called hello.html:
hello ${_name}
Note the use of the play convention that states variables passed into a tag are prefixed with an underscore.
This tag is invoked in the regular way:
{#hello name:'steve' /}
All well and good, but what if we want some default behaviour that can be over-ridden? For example, you may want the tag “hello” in its normal usage, but in 40% of the usages, to say “Good day” because someone in senior management can access the function and it’s felt that “hello” is far too informal. Stranger things have happened.
In this case we can rewrite the tag as:
%{ message = _formal == null ? 'Hello' : (formal ? 'Good day' : 'Hello') }%${message} ${_name}
_formal will be null if not declared in the calling tag, and so the message will be “Hello”. If it is declared, and it’s a boolean, the message will vary according to the value.
So, the existing tag call of
{#hello name:'steve' /}
will produce
Hello Steve
but
{#hello name:'steve' formal:true/}
will produce
Good day Steve
It should be noted there is another possibility in the example above – giving a value to “formal” which is not a boolean but nonetheless a not-null object will result in “Good day”. Take this into account when setting up your defaults, and rewrite the assignment of “message” if necessary to allow for this!