How to set default arguments for Handlebars templates?

handlebars helpers
handlebars if string contains
handlebars tutorial
express-handlebars
handlebars combine templates
pass variable to handlebars template
handlebars control flow
handlebars custom function

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 http://handlebarsjs.com/block_helpers.html ]

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/

Expressions, Handlebars expressions are the basic unit of a Handlebars template. In Handlebars, the values returned by the {{expression}} are HTML-escaped. This expands the default behavior of stripping lines that are "standalone"� Handlebars provides the power necessary to let you build semantic templates effectively with no frustration. Mustache-compatible In most cases it is possible to swap out Mustache with Handlebars and continue using your current templates.

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' }}

Block Helpers, Block helpers make it possible to define custom iterators and other functionality with a parameter, it is invoked with whatever context the template passed in. block helpers can accept an optional Hash as its final argument. The keys in hash arguments must each be simple identifiers, and the values are Handlebars expressions. This means that values can be simple identifiers, paths, or Strings. If we pass the below input to the template, the value of person.url can be obtained from the person object.

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))

Personalizing Templates with Handlebars – Iterable Support Center, When editing the HTML source of a message template, adjust the Handlebars Display default value if no value exists for a parameter (defaultIfEmpty). So far, we've used templates that are defined inside the code. However, it is not the only option. We can also read templates from text files. Handlebars.java provides special support for reading templates from the classpath, filesystem or servlet context. By default, Handlebars scans the classpath to load the given template:

Helpers parameter list should not change based off calling context , some template stuff. However, lets say that both param1 and param2 are optional, as in, the caller can pass them only if it wants to. by the way this helper is set up, but in the example above (and others), it will. For as long as I have used Handlebars, that's been the parameter signature of a helper. For a member function of a non-template class, the default arguments are allowed on the out-of-class definition, and are combined with the default arguments provided by the declaration inside the class body. If these out-of-class defaults would turn a member function into a default, copy, or move constructor the program is ill-formed.

Writing Helpers - Templates, Helpers are most useful for transforming raw values from models and components into a format more Let's create a format-currency helper that takes an integer count of cents and turns it into formatted dollars. import Ember from ' ember'; export default Ember. Helper.helper(function(params) { let value = Handlebars. Working of default arguments How default arguments work in C++. We can understand the working of default arguments from the image above: When temp() is called, both the default parameters are used by the function. When temp(6) is called, the first argument becomes 10 while the default value is used for the second parameter.

Handlebars, A Handlebars template is just some text that contains Handlebars helper is so useful that Handlebars will actually use it as the default helper if you create a The function may accept any number of arguments from the template, which may � Handlebar.compile() can be used to produce a templating function. A template string with expressions must be passed into Handlebar.compile().That function then takes an object as an argument, interpolates the object’s values into the template expressions, and returns a completed HTML string.

Comments
  • Not sure this will work, when the second param is passed (as a string) the call to options.hash.title will fail with Cannot read property 'title' of undefined.
  • @doublejosh all optional arguments need to be passed in the way <arg>=<value> otherwise handlebars will shift the options argument to the right and break the helper.
  • Sure. I'm referring to how to you inspect the options param within the helper. Since options can be a string when a second param is present, then referencing that nested property causes an error.
  • @doublejosh to cope for an arbitrary number of arguments you could use the arguments object inside the helper function. The options object will always be arguments[arguments.length - 1]. I adapted my answer accordingly.
  • That's wonderful information!!! This portion of Handlebars is undocumented.