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:
- The template must be placed within
script
tags, otherwise the browser might modify it. - The
type
of thescript
tag must betext/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:
- Compile the template.
- Create a context to use for the evaluation.
- 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:
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: runningamend
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 usedamend
.
Our page now looks like we actually wanted it to look:
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:
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.
You can download the full source code of this example here: GitWithHandlebars.zip