Tuesday, April 09, 2013

Angry Birds of JavaScript: Orange Bird - Templating

Introduction


A diabolical herd of pigs stole all of the front-end architecture from an innocent flock of birds and now they want it back!

A team of special agent hero birds will attack those despicable pigs until they recover what is rightfully theirs, front-end JavaScript architecture!

Will the birds be successful in the end? Will they defeat their bacon flavored foe? Let's find out together in another nail biting episode of Angry Birds of JavaScript!

Check out the series introduction post for a list of all the birds and their attack powers.

Previous Attacks


Orange Bird Attacks


In this post we will take a look at the Orange Bird. He first starts out small with a simple template, but then expands itself into a DOM blast that will surely send the message that the birds mean business. Slowly, one by one, the birds will take back what it theirs to keep!

What Was Stolen by the Pigs?


For the last several years we have seen a trend that more and more work is being done on the front-end of web development. We communicate to the back-end via Ajax or Web Sockets and then display the data somehow in the UI. The birds found themselves mostly using string concatenation to build up the rich user interfaces, which resulted in a lot of code that was boring and also prone for errors. Thankfully an Orange Bird came along and said, "Hey, isn't there something better than this? Can't we separate our view from our data somehow?", and that is how templates became to be in the bird world. The Orange Bird borrowed templating libraries from the humans such as Underscore.js and Handlebar.js to help fit this need among the foul.

However, during a recent invasion the pigs stole the birds' templating libraries! As a result, one of the Orange Birds has been tasked to reclaim what has been stolen. He will use his exploding power to help destroy the pigs in order to take back what is theirs.

Why Use a Templating Engine?


Before we get into what templating engines I recommend let's first look into why we might need one in the first place. The more I develop I try to find ways to separate the various parts of my application. I start to feel dirty when too much stuff is going on in the same place. Take a look at the following piece of code and tell me how you feel...


Yeah, I don't like all of the string concatenation either. I prefer not to have a bunch of presentation inside of my code if I can help it. On the plus side, it does work. You can see the output of the code in the following embedded jsFiddle.



So, what can we do instead? This is where some type of templating engine can help us simplify our code and separate our markup from our code.

Underscore.js


We will first look at the template method in the Underscore.js library. I tend to use Underscore in all of my projects these days so I already have the power of its templating engine loaded. If what I am doing is pretty simple, then I mostly default to use Underscore for templating. However, as you'll see there are some limitations which make the next library we will look at much more appealing.

Take 1


The following is the above code rewritten using Underscore's template. You'll notice that the code piece has been greatly simplified! Whoo hooo!


The bulk of the work is being done by the template to explode it into a bunch of markup! As you can see to the left our orange bird looks quite different now lolz ;)

We moved the layout into a script tag in our markup and gave it an identifier. The template has special markers <%= expression %> to denote where it should evaluate data passed to it. You can also use the <% statements %> symbols to put whatever JavaScript you want in there (think loops, branching, etc...)!


You can play around with the above code snippets in jsFiddle.

As Uncle Ben said, "With great power, comes great responsibility."

Being able to put whatever code you want in your template isn't the best idea in the world. By putting the date manipulation logic in the template it makes it really tough to Unit Test that piece of code. Just imagine if we started cluttering our template with more and more code blocks that like. If you go this route, then you aren't really solving the original problem at hand which was combining presentation and logic.

Take 2


The following is another take at using Underscore, but this time doing the data manipulation before. The downside is that I'm using the _.map() method and converting each date property to the relative version. There is some overhead in me having to loop over the data before handing it off to the templating engine.


We were able to remove the date logic in the following template since we did that work above in the JavaScript before calling the template to do its work. The result is better than what we started with, but it could be better.


You can play around with the above code snippets in jsFiddle.

Why use Underscore.js?


Pros


  • You can stick arbitrary JavaScript in the template
  • It is very small
  • If you are already using Backbone.js then you have it
  • If you are already using Underscore.js then you have it
  • You can Compile the Templates
  • Can Run on the Client and the Server
  • Can you think of others?

Cons


  • You can stick arbitrary JavaScript in the template
  • Doesn't have the concept of this in templates
  • Can you think of others?

Handlebars.js


Overall I tend to prefer the Handlebar.js over Underscore's template engine. Handlebars encourages you to separate your presenting from your logic, it is faster, and it provides a mechanism to precompile your templates that we will look at here in a bit.

First let's take another look at the problem we have been addressing throughout this post. The following code uses Handlebars to template the solution. The code is still pretty clean as was the previous version. You'll notice that I am defining a custom helper called fromNow that can be used in the template.


And now for the templating syntax below. The syntax feels much more terse to me compared to Underscore, which I like. Inside the template we are using the fromNow template helper to convert the time. This is nice so we don't have to map over our array beforehand like we did with Underscore or put the logic in the template itself.


You can play around with the above code snippets in jsFiddle.

Precompiling Your Templates


I briefly mentioned above that one of the things I liked was that you can precompile your templates. What does that even mean!?! Well, with both Underscore and Handlebars you need to compile your template before you use it (technically you can do it in one step with Underscore, but it still has to be done under the covers). Compiling a template is good to do if you plan on using it more than once or if you just want it done before you need it.

However, with Handlebars you can go one step further and compile the template on the server and include that on the front-end. This means that you can reduce that amount of work needed on the front-end AND there is a trimmed down version of the handlebars runtime that you can use that has only the parts necessary needed to execute a template (not compile it)!

How cool is that? If your answer was "It's just about as cool as Batman riding on a Rainbow Unicorn alongside dolphins!", then you were right! Congratulations ;)

So how does that work exactly? Well, first you install Handlebars on your server using Node...


Then you take your template contents (what is between the script tags) and save it to a file. In our case let's save it as tweets.tmpl. How run the handlebars precompiler against your template file.


Once all of that is done you have a precompiled version of your template that you can now include on your front-end application like the following...


Now that your template is available on the page you can access it by asking Handlebars for the precompiled version and you are all set to start using it!


Why use Handlebars.js?


Pros


  • Its a Logic-less Template Engine
  • You can Precompile Templates on the Server
  • Supports Helper methods
  • Can Run on the Client and the Server
  • Supports the concept of this in templates
  • It iss a superset of Mustache.js
  • Can you think of others?

Cons


  • Can you think of any?

What About Other Templating Engines?


That is a great question. Maybe your needs are different than mine or maybe you just don't like one of the engines that I've mentioned. If that is the case then you should check out a great tool created by Garann Means (@garannm) called the Template Chooser. The chooser will ask you a set of questions that will help determine which templating engine is right for your needs. The following is an example of what the chooser looks like...


Additional Resources



Attack!


The following is a simple Angry Birds clone using boxbox, a framework for the box2dweb JavaScript physics library, written by Bocoup's Greg Smith.

Press the space bar to launch the Orange Bird and you can also use the arrow keys.


Conclusion


Mixing markup in code can lead to some nasty looking code that is cumbersome, monotonous, and difficult to maintain. Being able to split these apart is a great benefit for developers to simplify their code and help keep each concern in its place. Thankfully libraries like Underscore and Handlebars help us out by providing a clean way to describe presentation apart from logic. THere is a lot of freedom depending on what library you use, but I'd encourage you to look around and find one that works for you. The answer to that may be not to use one and that is fine.

There are many other front-end architecture techniques that have been stolen by the pigs. Tune in next time as the next Angry Bird takes its revenge! Dun, dun, daaaaaaa!

No comments:

Post a Comment