I've written a template helper that inserts a link, fairly straightforward.
Handlebars.registerHelper('link_to', function(href, title) {
return new Handlebars.SafeString('<a href="/' + href + '">' + title + '</a>');
});
And its usage is like so:
{{ link_to 'articles' 'Articles' }}
However, it seems a bit redundant for me to specify a capitalised version in the second parameter if the href is self-describing. So I'd like to set this behaviour automatically if the title parameter is omitted. Something like the following:
Handlebars.registerHelper('link_to', function(href, title) {
if (!title) {
title = href.charAt(0).toUpperCase() + href.slice(1);
}
return new Handlebars.SafeString('<a href="/' + href + '">' + title + '</a>');
});
However, when rendered with {{ link_to 'articles' }}
I just get [object Object]
. It's not a big deal to keep the second parameter, but I was just wondering if there was a way around this.
Helpers accept an optional Hash as its final argument.If the template provides no hash arguments, Handlebars will automatically pass an empty object ({}).
[From https://handlebars-lang.github.io/docs/guide/block-helpers.html#hash-arguments ]
So, when you are having title in the helpers parameter list it is treated as the Hash object. You can check that by logging title in console. So for your code to work you can just check that if the type of title is String or not using the typeof operator.
if(!title || typeof title != 'String') {
title = href.toString().charAt(0).toUpperCase() + href.slice(1);
}
and it should work. Working example : http://jsfiddle.net/prabhat_rai/ve4h39vm/
The correct way to use the hash arguments in handlebars seems to be to check for the expected optional parameters in the hash
attribute of the options
argument (passed to any helper as last argument).
In the OP example this would look like this:
Handlebars.registerHelper('link_to', function(href) {
var options = arguments[arguments.length - 1];
var title = options.hash.title || href.toString().charAt(0).toUpperCase() + href.slice(1);
return new Handlebars.SafeString('<a href="/' + href + '">' + title + '</a>');
});
This way the helper can be used like this
{{ link_to 'articles' title='Articles' }}
or this
{{ link_to 'articles' }}
This has the advantage that you can add any number of optional template arguments and not just one. That is the above example could easily extended to provide an optional tooltip as well:
Handlebars.registerHelper('link_to', function(href) {
var options = arguments[arguments.length - 1];
var title = options.hash.title || href.toString().charAt(0).toUpperCase() + href.slice(1);
var tooltip = options.hash.tooltip || title;
return new Handlebars.SafeString('<a href="/' + href + '" title="' + tooltip + '">' + title + '</a>');
});
Now both title
and tooltip
can be specified independent of each other. I.e. you can specify a tooltip but no custom title:
{{ link_to 'articles' tooltip='Go to Articles' }}
fix your helpers. The options object makes this difficult. So by wrapping the functions with something that moves around the arguments you have more reasonable code assuming you will have multiple helpers with optional arguments
function fixHelper(func) {
return function(){
var aArgs=Array.prototype.slice.call(arguments, 0)
,opts=aArgs.pop();
aArgs.unshift(opts);
return func.apply(this, aArgs);
}
function link_to(options, href, title) {
title = title || href.ucfirst()
return new Handlebars.SafeString('<a href="/' + href + '">' + title + '</a>')
}
Handlebars.registerHelper('link_to', fixHelper(link_to))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With