Skip to content

Instantly share code, notes, and snippets.

@vonnenaut
Last active July 6, 2021 04:16
Show Gist options
  • Select an option

  • Save vonnenaut/b7bec667dc43aced3aa475cd390da804 to your computer and use it in GitHub Desktop.

Select an option

Save vonnenaut/b7bec667dc43aced3aa475cd390da804 to your computer and use it in GitHub Desktop.
Handlebars.js

Handlebars.js

https://handlebarsjs.com/guide/

https://handlebarsjs.com/api-reference/

Handlebars is a templating engine for web pages. You create an HTML-ish template which the templating engine converts on-the-fly into HTML content on the server, including dynamic content

  • use {{{ and }}} to avoid escaping a value, {{expression}} to escape

input:

var source = document.getElementById("entry-template").innerHTML;
var template = Handlebars.compile(source);
var context = { title: "My New Post", body: "This is my first post!" };
var html = template(context);

output:

<div class="entry">
  <h1>My New Post</h1>
  <div class="body">
    This is my first post!
  </div>
</div>
  • alternative templating engines include EJS and Pug (Jade)
  • usesHTML and Handlebars expressions
  • similar to Embedded Ruby in function, though EJS is more similar to Embedded Ruby in appearance
  • can be installed or loaded from a CDN like JQuery or Bootstrap
<p>{{firstname}} {{lastname}}</p>

Setup

CDN

  • use for small-scale and testing
<!-- Include Handlebars from a CDN -->
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script>
  // compile the template
  var template = Handlebars.compile("Handlebars <b>{{doesWhat}}</b>");
  // execute the compiled template and print the output to the console
  console.log(template({ doesWhat: "rocks!" }));
</script>

Installation (npm or yarn)

https://handlebarsjs.com/installation/

  • just use npm or yarn - don't mix usage
  • this is the recommended way, along with Webpack build engine (or Browserify or Parcel)
  • see https://handlebarsjs.com/installation/ for integrations plugins for Webpack, Browserify, Parcel and Babel

install handlebars

npm install handlebars
# or
yarn add handlebars

Usage

and use require

const Handlebars = require("handlebars");
const template = Handlebars.compile("Name: {{name}}");
console.log(template({ name: "Nils" }));
<script id="entry-template" type="text/x-handlebars-template">
  <div class="entry">
    <h1>{{title}}</h1>
    <div class="body">
      {{body}}
    </div>
  </div>
</script>

Compile template in JS using Handlebars.compile

var source = document.getElementById("entry-template").innerHTML;
var template = Handlebars.compile(source);

Get HTML result of evaluating a template by executing template w/a context

var context = { title: "My New Post", body: "This is my first post!" };
var html = template(context);

Precompiling Templates

https://handlebarsjs.com/installation/precompilation.html#getting-started

  • it's much more efficient to compile templates beforehand and include precompiled versions in your website
  • optimizations can also be applied

install Handlebars via npm npm install -g handlebars

create template file, example.handlebars Handlebars <b>{{doesWhat}}</b> precompiled!

run precompiler handlebars example.handlebars -f example.precompiled.js

include Handlebars runtime and precompiled JS

<div id="output"></div>
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.runtime.js"></script>
<script src="example.precompiled.js"></script>
<script>
  var template = Handlebars.templates.example;
  document.getElementById('output').innerHTML = template({doesWhat: 'rocks!'})
</script>

this optimization allows you to specify a list of the known helpers to the compiler handlebars <input> -f <output> -k each -k if -k unless

Precompiling Inside Node.js

https://handlebarsjs.com/installation/precompilation.html#precompiling-templates-inside-nodejs

  • can be precompiled in Node.js without invoking handlebars from cli using Handlebars.precompile
  • string result can then be transmitted to clients, who can parse it w/ Handlebars.template
let template = "Handlebars <b>{{doesWhat}}</b> precompiled!";
let Handlebars = require("handlebars");
let compiled = Handlebars.precompile(template);
console.log(compiled);
{"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
    var helper, alias1=container.propertyIsEnumerable;

  return "Handlebars <b>"
    + container.escapeExpression(((helper = (helper = helpers.doesWhat ||
    (depth0 != null ? depth0.doesWhat : depth0)) != null ? helper : container.hooks.helperMissing),
    (typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),
    {"name":"doesWhat","hash":{},"data":data}) : helper)))
    + "</b> precompiled!";
},"useData":true}

client side:

Handlebars.partials["test1"] = Handlebars.template({
  /** insert compiled output here **/
});

reference templates dynamically in your JS

var result = Handlebars.partials["test1"]({ name: "yourname" });
//do whatever you want with the result

Simple Expressions

template

<p>{{firstname}} {{lastname}}</p>

input object

{
  firstname: "Yehuda",
  lastname: "Katz",
}

output

<p>Yehuda Katz</p>

Comments

{{! This comment will not show up in the output}}
<!-- This comment will show up as HTML-comment -->
{{!-- This comment may contain mustaches like }} --}}

Helpers

https://handlebarsjs.com/guide/builtin-helpers.html

  • built-in helper with gives access to an object's properties
// template
{{#with person}}
{{firstname}} {{lastname}}
{{/with}}

...

// input
{
  person: {
    firstname: "Yehuda",
    lastname: "Katz",
  },
}
  • each helper iterates an array, allowing access to properties of each object
<ul class="people_list">
  {{#each people}}
    <li>{{this}}</li>
  {{/each}}
</ul>

...

{
  people: [
    "Yehuda Katz",
    "Alan Johnson",
    "Charles Jolley",
  ],
}

Custom Helpers

  • can be registered w/ Handlebars.registerHelper method
    • use SafeString() to return generated HTML from a custom helper; you will want to manually escape parameters
Handlebars.registerHelper("bold", function(text) {
  var result = "<b>" + Handlebars.escapeExpression(text) + "</b>";
  return new Handlebars.SafeString(result);
});
  • this will escape passed-in parameters and mark the response as safe
Handlebars.registerHelper('loud', function (aString) {
    return aString.toUpperCase()
})

Block Helpers

https://handlebarsjs.com/guide/block-helpers.html

  • allow you to define helpers that will invoke a section of template w/a different context than the current
  • ID'd by a # preceeding helper name and require matching closing /
<div class="entry">
  <h1>{{title}}</h1>
  <div class="body">
    {{#noop}}{{body}}{{/noop}}
  </div>
</div>

Partials

allow for code reuse by creating shared templates

Handlebars.registerPartial(
    "person", 
    "{{person.name}} is {{person.age}} years old.\n"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment