Git

Git Handlebars Example

1. Introduction

In this post, we feature a comprehensive Example on Git Handlebars. Git is a free and open source (FOSS) version control system that was originally created by Linus Torvalds to use for developing the Linux kernel. The Linux kernel being a large piece of software — with developers working on it from all over the world — had a large and positive impact on the way Git is designed. Unlike older version control systems — like RCS and SVN — Git is decentralized. Instead of a single server being the “master”, every developer has a full copy of the code repository history locally. As a result, the initial “cloning” of the repository is slower, but subsequent (and much more frequent) operations like commit-ing and diff-ing are much faster and (can be) entirely local (i.e., not requiring a network connection).

Handlebars.js is a Javascript library for building simple, clean logic-less templates based on the Mustache Templating Language. The focus is on keeping the code (logic) and the view separate.

2. Getting a Handle on Things

Let’s start by creating a super-simple Handlebars-powered page. We can get started very simply by creating a basic HTML page and including the Handlebars library in the head section of the page:

Adding the Handlebars library

<script type="text/javascript"
    src="https://examples.javacodegeeks.com/wp-content/litespeed/localres/aHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS8=ajax/libs/handlebars.js/4.0.11/handlebars.min.js">
</script>

Now in the body of the page we can add the (very basic) Handlebars template, starting with a version of the Hello World! example (what else?):

Defining our Handlebars template

    <script id="hello-world-template" type="text/x-handlebars-template">
      <p>Hello {{adj}} world!</p>
    </script>

As you may have already noticed, a lot of the text inside the script tag is plain HTML. It’s the {{adj}} part that is interesting: it’s where the Handlebars magic happens. It is what is called an expression: Handlebars will replace that expression with its value when it is run.

It is important to note two things here:

  1. The template must be placed within script tags, otherwise the browser might modify it.
  2. The type of the script tag must be text/x-handlebars-template so that the browser doesn’t try to parse the template as Javascript (which it isn’t).

Having created the template, we now need to:

  1. Compile the template.
  2. Create a context to use for the evaluation.
  3. Evaluate the template given its context and then insert the output into the HTML page.

Here is the listing of the complete page:

index.html

<html>
  <head>
    <title>Getting Started with Handlebars</title>
    <script type="text/javascript" src="https://examples.javacodegeeks.com/wp-content/litespeed/localres/aHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS8=ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script>
  </head>
  <body>
    
    <script id="hello-world-template" type="text/x-handlebars-template">
      <p>Hello {{adj}} world!</p>
    </script>
    
    <div id="content"></div>

    <script type="text/javascript">
      var source = document.getElementById("hello-world-template").innerHTML;
      var template = Handlebars.compile(source);
      var context = {adj: "awesome"};
      document.getElementById("content").innerHTML = template(context);
    </script>
  </body>
</html>

Let’s look at the code in lines 15-18:

  • Line 15: read the contents of the template
  • Line 16: compile the template
  • Line 17: define our context
  • Line 18: execute the template with the context to get the compiled HTML & insert it into the page

If you load this page in your browser you will see the message Hello awesome world! You have now successfully created your first Handlebars template. Congratulations!

3. Did You Git it?

Now that we have created something worthwhile, why not put it under version control (we’re going to want to change it, aren’t we)? To get started, let’s initialize a Git repository in the directory where you have just created the index.html file.

$ cd $HOME/Code/git-handlebars
$ git init
Initialized empty Git repository in $HOME/Code/git-handlebars/.git/

Having initialized a Git repository, let’s take a look at what’s the current status:

$ git status
On branch master

No commits yet

Untracked files:
  (use "git add ..." to include in what will be committed)

        index.html

nothing added to commit but untracked files present (use "git add" to track)

What’s that? Git is telling is that we haven’t committed anything yet and it is also helpfully giving us the command to do so (git add)!! Also, Git has shown us which file(s) is(are) “untracked” (not currently under Git’s version control). Let’s take are of that:

$ git add index.html

Ok, so Git was very quiet this time. Let’s check on the status again:

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   index.html

We can see that Git now knows that index.html is a new file. To have Git start tracking changes to this file, let’s commit it:

$ git commit -m "My first Handlebars template"
git commit -m "My first Handlebars template"
[master (root-commit) f0787dd] My first Handlebars template
 1 file changed, 21 insertions(+)
 create mode 100755 index.html

$ git status
On branch master
nothing to commit, working tree clean

We have now added our first file to the Git repository and then we ran git status to confirm that we had a “clean” working tree.

4. Handle it With Helpers

In Handlebars you can’t directly write Javascript inside a template. Does that mean Handlbars is limited to doing just variable substitutions? Not at all! Handlebars lets you use helpers, Javascript fuctions that you can call from inside your templates that help you create complex and reusable code. Calling a helper is as simple as using its name: {{helpername}}. You can also pass in variables by listing them after the helper’s name: {{helpername arg1 arg2}}. Let us update our little experiment with this new-found knowledge. The updated template looks like:

Updated template

<script id="hello-world-template" type="text/x-handlebars-template">
  <h2>Hello {{adj}} world!</h2>

  <p>Now let's add some {{bold 'bold text'}} to this page.</p>
</script>

We define our helper in a separate code.js file:

code.js

Handlebars.registerHelper('bold', function(str) {
    str = str || '';
    return '<strong>' + str + '</strong>';
});

Having made our changes, let’s take a look at what Git has to say:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   index.html

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        code.js

no changes added to commit (use "git add" and/or "git commit -a")

As expected, Git shows us that we have modified our index.html file and added a new code.js file. Let’s take a look at what’s changed in the index.html file:

$ git diff index.html
diff --git a/index.html b/index.html
index 8060315..f0b128f 100755
--- a/index.html
+++ b/index.html
@@ -2,11 +2,14 @@
   <head>
     <title>Getting Started with Handlebars</title>
     <script type="text/javascript" src="https://examples.javacodegeeks.com/wp-content/litespeed/localres/aHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS8=ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script>
+    <script type="text/javascript" src="code.js"></script>
   </head>
   <body>

     <script id="hello-world-template" type="text/x-handlebars-template">
-      <p>Hello {{adj}} world!</p>
+      <h2>Hello {{adj}} world!</h2>
+
+      <p>Now let's add some {{bold 'bold text'}} to this page.</p>
     </script>

     <div id="content"></div>

That’s great! Everything is as expected. Now let’s commit the changes we have just made:

$ git add index.html code.js

$ git commit -m "Adding a helper to our Handlebars code"
[master e9dd43a] Adding a helper to our Handlebars code
 2 files changed, 8 insertions(+), 1 deletion(-)
 create mode 100755 code.js

$ git status
On branch master
nothing to commit, working tree clean

5. The Great Escape

Having committed our code, let’s open it in a browser and take a look at it. This is what it looks like:

Git Handlebars - angle brackets of HTML have been escaped
Oops! The angle brackets of HTML have been escaped!

Oh no, Handlebars escaped the angle brackets of our template!

The solution to this particular issue is simple in Handlebars: use triple curly braces (aka triple-stash; {{{...}}}) instead of double curly braces to tell Handlebars to not escape the generated values:

Use triple-stash to avoid HTML escaping

<script id="hello-world-template" type="text/x-handlebars-template">
  <h2>Hello {{adj}} world!</h2>

  <p>Now let's add some {{{bold 'bold text'}}} to this page.</p>
</script>

Having made the above change, we now have to check it into Git. We can be smart about this and use git amend to change the previous commit rather than having to create a new one:

$ git commit --amend --no-edit index.html

$ git status
On branch master
nothing to commit, working tree clean

$ git log
commit 04e0f19ae6fbdf0113bd8a2aa3ba94d34a3d2d6c (HEAD -> master)
Author: somebody
Date:   somedate

    Adding a helper to our Handlebars code

commit ef6c3bc053d2ac5ab3dc244a614255e8ed4246ed
Author: somebody
Date:   somedate

    My first Handlebars template

Here’s what we just did:

  • The git commit --amend command amends the previous commit rather than creating a new one. This allows us to correct our mistake quietly and cleanly. NB: running amend like this is not safe on public commits (explanation taken from [1]).
  • The --no-edit option tells Git that we don’t want to edit the comment of the previous Git commit.
  • We checked the status to ensure we had a clean working directory.
  • We used git log to verify that there are still only 2 commits in the repository’s history, not the three that would have been present had we not used amend.

Our page now looks like we actually wanted it to look:

Git Handlebars - output we envisaged in our minds
Now we see the output we envisaged in our minds

6. Express Yourself in Blocks

Block expressions in Handlebars allow us to specify helpers that invoke our template with a different context than the current one. Block expressions are started with {{#blockHelperName}} and end with {{/blockHelperName}}. We start by updating our template to use a helper to generate a list of addresses:

Updated template includes helper to generate list of addresses

<script id="hello-world-template" type="text/x-handlebars-template">
  <h2>Hello {{adj}} world!</h2>

  <p>Now let's add some {{{bold 'bold text'}}} to this page.</p>

  <p>List of addresses:</p>
  {{#listAddr addrs}}{{addr1}},<br> {{addr2}},<br> {{addr3}}{{/listAddr}}
</script>

Let’s add some address information to our context:

Update context to add some addresses

      var context = {adj: "awesome", addrs : [
	{addr1: "345", addr2: "Peach Tree Lane", addr3: "Somewhereville"},
	{addr1: "142", addr2: "Orange Street", addr3: "Smallville"},
	{addr1: "249", addr2: "Banana Avenue", addr3: "Orange County, CA"}
      ]};

Then we register our helper function:

Helper to handle block expressions

Handlebars.registerHelper('listAddr', function(items, options) {
    var out = "<ol>";
    for (i = 0; i < items.length; i++) {
	out += "<li>" + options.fn(items[i]) + "</li>";
    }
    return out + "</ol>";
});

The helper receives addrs as its first parameter and an options hash as the second parameter. This options hash contains a special property fn which can be invoked with a context just like an ordinary Handlebars helper.

Now our page looks like this:

Git Handlebars - Listing addresses using block expressions
Listing addresses using block expressions

As before, we want to commit our changes to the Git repository:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   code.js
        modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")

$ git add -u

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   code.js
        modified:   index.html

As a convenience, we used git add -u to add all (tracked) updated files to the staging area (instead of git commit index.html code.js). Once ready in the staging area, we commit our code to the repository.

7. Parting Thoughts

We have learnt a lot about the basics of the Handlebars templating system while also learning how to create a repository in Git, how to add files to it, how to commit and diff them. We also learnt how to correct a commit! Of course, there’s a lot more to learn on both topics, but I hope this gives you a good start on your journey.

8. Download the Source Code

We just saw an example of building a template in Handlebars using Git for version control.

Download
You can download the full source code of this example here: GitWithHandlebars.zip

Harshdeep Jawanda

Armed with a Bachelor of Engineering (Comp. Engg.) degree from University of Pune, India, and a Master of Science (Comp. Sci.) degree from the University of New Mexico, USA, Harshdeep uses his vast experience to develop highly scalable, fault-tolerant distributed systems and come up with innovative solutions to all sorts of problems. As Founder & CTO of Plowns he is using those skills to ensure the all-round growth of children outside the classroom.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button