In this section you will learn about helpers, their syntax, how to register and lot more.
Helpers are a key concept of Handlebars.java.
Through ahelper
you can add custom logic from a safe and controlled way.
Helpers are lightweight components that can be tested using tools like JUnit
There are two types of helpers:
{{name context? [argument]* [hash]*}}
Block helpers:
{{#name context? [argument]* [hash]*}}
...
{{/name}}
Name, context, argument, and hash are defined as follows:
name: qid;
context: expression;
argument: expression;
hash: id '=' expression;
expression: literal | qid;
qid
:
'../' qid
| id '[' .* ']' ('.' | '/') qid
| id '[' .* ']' qid
| id ('.' | '/') qid
| 'id'
;
id: idStart (idStart | idPart)*;
idStart: [a-zA-Z_$@];
idPart: [0-9];
literal
:
stringLiteral
| boolLiteral
| numberLiteral
| 'this'
| '.'
;
stringLiteral:'"' .* '"';
boolLiteral:'true' | 'false';
numberLiteral: '0'..'9'+;
There are two way of registering helpers in Handlebars.java:
The API for registering ahelper
is very similar to Handlebars.js
handlebars.registerHelper("blog", new Helper<Blog>() {
public CharSequence apply(Blog blog, Options options) {
return options.fn(blog);
}
});
Beside the differences between the languages, the code for registering a helper is very similar.
If you have a couple of helpers, you probably don't want to register eachhelper
one by one. This is where aHelper Source
makes more sense.
AHelper Source
is a class where any public method returning an instance ofjava.lang.CharSequence
get registered as ahelper.
Also:
public class HelperSource {
public String blog(Blog blog, Options options) {
return options.fn(blog);
}
public static String now() {
return new Date().toString();
}
public String render(Blog context, String param0, int param1,
boolean param2, Options options) {
return ...
}
}
handlebars.registerHelpers(new HelperSource());
handlebars.registerHelpers(HelperSource.class);
Now you know how to register a helper, let's see what you can do with it.
arg0
using thehelper
interface:
{{blog this "arg0"}}
...
public CharSequence apply(Blog blog, Options options) {
return options.param(0);
}
arg0
using ahelper
method:
{{blog this "arg0"}}
...
public CharSequence blog(Blog blog, String arg0) {
return arg0;
}
options
variable:
{{blog this "string" true 678}}
...
public CharSequence blog(Blog blog, Options options) {
String str = options.param(0);
boolean bool = options.param(1);
int num = options.param(2);
}
helper
method:
{{blog this "string" true 678}}
...
public CharSequence blog(Blog blog, String str, boolean bool, int num) {
}
{{blog this}}
...
public CharSequence blog(Blog blog, Options options) {
return options.param(0, "arg0");
}
{{blog this author}}
...
public CharSequence blog(Blog blog, Author author) {
return author.getName();
}
In the example above,author
is a value in the context stack. Ifauthor
isn't found anull
value will be injected in theauthor
variable.
stringParams: true
let you access to the parameter name when a context stack value isn't resolved:
handlebars.setStringParams(true);
...
{{blog this edgar}}
...
public CharSequence blog(Blog blog, Object author) {
return author instanceof String? author: author.getName();
}
name
using thehelper
interface:
{{blog this name="Blog"}}
...
public CharSequence apply(Blog blog, Options options) {
return options.hash("name");
}
options
variable:
{{blog this s="string" b=true n=678}}
...
public CharSequence blog(Blog blog, Options options) {
String str = options.hash("s");
boolean bool = options.get("b");
int num = options.get("n");
}
{{blog this}}
...
public CharSequence blog(Blog blog, Options options) {
return options.hash("arg0", "default value");
}
A helper method must return an instance of ajava.lang.CharSequence
ornull
.
For none null results, the value is HTML escaped.
You can unescape the HTML code in one of three ways:
{{&blog this}}
{{{blog this}}}
public CharSequence blog(Blog blog, Options options) {
return new Handlebars.SafeString("<div>Hello</div>");
}
...
{{blog this}}
From the three methods: Handlebars.SafeString is 100% safe, bc doesn't depends on how you invoke the helper.
If a helper isn't found ajava.lang.IllegalArgumentException
occurs.
You can change this by registering ahelperMissing
helper.
helperMissing
and return the template block (if any).
handlebars.registerHelper(Handlebars.HELPER_MISSING, new Helper<Object>() {
@Override
public CharSequence apply(final Object context, final Options options)
throws IOException {
return options.fn.text();
}
});
It is great if you can keep the inherited logic-less from Mustache. This is what will make your application easy to understand, change and evolve.
At the same time logic-less is hard to keep for medium/large size applications or probably you don't own the code and changing the model isn't an option.
In those cases Handlebars.java is here to help you. It wont let you add logic in the HTML but you can add as much logic as you need through helpers.
Thank you, for reading the Handlebars.java blog.