Sunday, November 8, 2015

Handlebars Essentials 3 - Template Precompilation

Assuming the project has templates in a dedicated folder, this step will optimize the way pages are rendered with Handlebars.

Why precompilation? Because Handlebars is designed to convert (compile) templates from their source form (with double-curly-braces) to a Javascript. And this step is expensive on a thin client. So, there is a quick and relatively easy extra step during development to compile all templates into a single .js file. That file is to be referenced by a <script> tag from the host page.


1. Make sure that Node.js is installed and up-to-date.

2. Use the following to install Handlebars module for Node.js.
$ sudo npm install -g handlebars


3. Place all templates into a subfolder, say “templates”. Then, from the root of the project do this:
$ handlebars templates/* -f templates/templates.js

This creates a single .js file with the code for all precompiled templates. To minimize the output and strip out spaces, use this instead:
$ handlebars templates/* -m -f templates/templates.js


4. Add a reference to the newly created templates.js.
<script src="templates/templates.js"></script>
<script src="js/initModel.js"></script>


5. App.js - replace the function to load templates with the following code. Note that partial templates still need to be loaded from the source as before, it appears this is the only way to register partials in Handlebars at present. And this is the only change required.
  function loadTemplatesAndRender() {
    indexTemplate = Handlebars.templates["index.hbs"];
    itemsTemplate = Handlebars.templates["items.hbs"];
    itemTemplate = Handlebars.templates["item.hbs"];

    // Note, the item template is a partial,
    // therefore also needs to be loaded as a source.
    var t3 = $.get("templates/item.hbs", function (data) {
      Handlebars.registerPartial("item", data);
    }, "html");
    // Wait for templates to finish loading.
    $.when(t3).done(function() {
      // Also wait for $(document).ready().
      $(function() {
        //alert("ALL DONE");
        renderPage();
        renderItems();
      })
    })
  }


UPDATE: There is a simpler way to "register" partials. Use the following somewhere after templates are loaded:
Handlebars.partials = Handlebars.templates;

For this to work the partial's reference needs to point to a template by file name, like so:
{{#each items}}
  {{> item.hbs language=@root.language}}
{{else}}
  {{language.noItemsFound}}
{{/each}}


No comments:

Post a Comment