Tuesday, March 17, 2015

handlebars 101

I really like the concept of handlebars (in terms of the library vs framework debate, and decoupling the "V" and "C" out of "MVC", unlike other heavier tools) but loops weren't as obvious. In older versions of Handlebars you had to write helpers, but like this stackoverflow describes now it's as easy as
{{#each myArray}}
    Index: {{@index}} Value = {{this}}
{{/each}}
and
{{#each myObject}}
    Key: {{@key}} Value = {{this}}
{{/each}}
and of course you can replace "myArray" or "myObject"with "." if you are passing in a simple array or object.

Also, if you want a comma-delimited list, that can look something like
{{#each myArray}}
    {{this}}{{#unless @last}}, {{/unless}}
{{/each}}
FOLLOWUP: if I call a post "handlebars 101" I owe it to my future self to have a reminder of the basic handlebars syntax in that post...
Keep in mind you can do "triple stash" if you don't want html escaped: {{{unescaped_html}}}

After including the handlebars js file, you make a template in a script tag like so:
<script id="hello-world-template" type="text/x-handlebars-template">
    <div>Hello, {{name}}</div>
</script>

You compile that template (probably keeping the resulting object around for reuse)

var helloWorldTemplate = Handlebars.compile($("#hello-world-template").html());

Then later you run that function, probably passing in a map of key/value pairs for substitution, and using (in jQuery) .html() or .append() to glom on the template result.

$("#someHolderObject").html(helloWorldTemplate({"name":"Kirk"}));

UPDATE: I had forgotten that I hadn't done this without JQuery -- and, sigh, who would want to be so uncool as to use jQuery?

const parent = document.getElementById("parent");
const helloWorldTemplate = Handlebars.compile(document.getElementById('hello-world-template').innerHTML);
parent.innerHTML += helloWorldTemplate({"name":"Kirk"}); 


Admttedly "+=" for appending HTML feels kind of sketchy. Years of jQuery followed by React made me forget how fiddly going from strings to DOM elements can be, even with a templating library like Handlebars. If you'd feel more moral formally making elements:

const parser = new DOMParser();
const convertedHtml = parser.parseFromString(helloWorldTemplate({"name":"Kirk"}), 'text/xml');
parent.appendChild(convertedHtml.documentElement);

Hmmm.

No comments:

Post a Comment