30

Can I specify a default value for a Handlebars` template placeholder?

<script type="x-handlebars-template" id="menu-edit-form-tpl">
    <form method="{{method}}" action="{{action}}" class="menu-edit-form">
...                     
    </form>
</script>

Can I specify default values for {{method}} and {{action}} and skip them in the object that is passed to the compiled template?

MTVS
  • 2,046
  • 5
  • 26
  • 37
  • If you have other various handlebars helper needs, there's a big library of helper functions here: https://github.com/helpers/handlebars-helpers#default - you can use it as `require('handlebars-helpers')({ handlebars });` and then `{{default method 'POST'}}` – Matt Fletcher Nov 23 '21 at 14:15

4 Answers4

48

Handlebars has no "default values".
You should use {{#if}} statement to check property is set.

<script type="x-handlebars-template" id="menu-edit-form-tpl">
    <form method="{{#if method}}{{method}}{{else}}POST{{/if}}" action="{{#if action}}{{action}}{{else}}/{{/if}}" class="menu-edit-form">
...
    </form>
</script>

Or if you want a bit cleaner syntax, use the simple helper:

Handlebars.registerHelper('safeVal', function (value, safeValue) {
    var out = value || safeValue;
    return new Handlebars.SafeString(out);
});

which allows you to write like this:

<script type="x-handlebars-template" id="menu-edit-form-tpl">
    <form method="{{safeVal method 'POST'}}" action="{{safeVal action '/'}}" class="menu-edit-form">
...
    </form>
</script>
Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192
raidendev
  • 2,729
  • 1
  • 22
  • 23
  • 7
    For me it only works when if write `{{#if}}` instead of `{{if}}` (I'm using metalsmith) – hgoebl Oct 20 '16 at 06:33
  • Another option is to use or from ember truth helpers, giving the syntax of: {{or method 'POST'}} Using the ember truth helpers from: https://github.com/jmurphyau/ember-truth-helpers – Rob Dawson Jul 20 '17 at 03:42
  • 2
    That's why I hate Handlebars... you are forced to create 'a simple helper' for something that it's BUILT IN in JS. In JSX {a || b} JustWorks. – gotofritz Aug 12 '18 at 14:25
9

Here is my simple solution

first we create a very basic helper called 'choose'

    Handlebars.registerHelper('choose', function (a, b) {return a ? a : b;});

then we use it in the template :)

<p>
{{choose valueFromData 'default-value-in-template'}}
<p>

or of course we can do

    <p>
    {{choose valueFromData defaultValueFromData}}
    <p>

So in your case:

<form method="{{choose method 'get'}}" action="{{choose action 'action.php'}}" class="menu-edit-form">
...                     
    </form>

Hope it helps someone else since this is from 2014 :)

Nick Panov
  • 2,597
  • 1
  • 14
  • 9
7

This question and its accepted answer are quite old and a lot of new features and functionality have been added to handlebars since they were written.

I managed to get the functionality of default values by using partial blocks which were released in v4.0.0 - so your template would end up looking like this:

<script type="x-handlebars-template" id="menu-edit-form-tpl">
    <form method="{{#> method}}get{{/method}}" action="{{#> action}}index.php{{/action}}" class="menu-edit-form">
...                     
    </form>
</script>

Then it's just a case of passing in your method and action as partials by doing something like this:

var source = $('#menu-edit-form-tpl').html(),
    template = Handlebars.compile(source),
    html = template({}, {
        partials: {
            action: 'contact-form.php'
        }
    });

In the resulting html the method will default to get and the action will be contact-form.php. Here's a working demo:

var source = $('#menu-edit-form-tpl').html(),
    template = Handlebars.compile(source),
    html = template({}, {
        partials: {
            action: 'contact-form.php'
        }
    });


// Code below here only to show output.
document.write('<code>' + $("<div/>").text(html).html() + '</code>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="x-handlebars-template" id="menu-edit-form-tpl">
    <form method="{{#> method}}get{{/method}}" action="{{#> action}}index.php{{/action}}" class="menu-edit-form">
        ...
    </form>
</script>
Andy
  • 4,901
  • 5
  • 35
  • 57
3

You can register a helperMissing helper which will get called whenever a value is defined in your template, but not in your context (useful if you don't want missing values to fail silently):

Handlebars.registerHelper("helperMissing", function(context, options) {
    console.error("Template defines {{" + context.name + "}}, but not provided in context");
    return "{{" + context.name + "}}";
});
philipisapain
  • 886
  • 9
  • 13