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 ahelperyou 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 ahelperis 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 eachhelperone by one. This is where aHelper Sourcemakes more sense.
AHelper Sourceis a class where any public method returning an instance ofjava.lang.CharSequenceget 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.
arg0using thehelperinterface:
{{blog this "arg0"}}
...
public CharSequence apply(Blog blog, Options options) {
return options.param(0);
}
arg0using ahelpermethod:
{{blog this "arg0"}}
...
public CharSequence blog(Blog blog, String arg0) {
return arg0;
}
optionsvariable:
{{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);
}
helpermethod:
{{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,authoris a value in the context stack. Ifauthor
isn't found anullvalue will be injected in theauthorvariable.
stringParams: truelet 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();
}
nameusing thehelperinterface:
{{blog this name="Blog"}}
...
public CharSequence apply(Blog blog, Options options) {
return options.hash("name");
}
optionsvariable:
{{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.CharSequenceornull.
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.IllegalArgumentExceptionoccurs.
You can change this by registering ahelperMissinghelper.
helperMissingand 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.