JavaScript Templating: Adding HTML the Right Way

If you’ve been using JavaScript for any semi-substantial amount of time, you’ve probably had to add some HTML to your page dynamically. If you haven’t then you’re missing out on some of the greatest power of JavaScript. There’s a problem though: It’s a pain in the buttocks to write HTML code inside a JavaScript string – especially when it’s a large amount of HTML and/or some of the tags have attributes – and adding in values from variables. It’s just a giant mess of quotes and plus signs.

You can see what I mean below:

1
2
3
var html = "<div class=\"someClass\">" + text
+ "</div><p class=\"" + p_class + "\">"
+ p_text + "</p>";

Templating Structure

Thankfully there is a simpler solution known as templating. First I’ll show you a quick and dirty way to make a tiny little templating solution of your own so if you just need it for a simple job, you won’t need to bother sending a server request for a big templating plugin that offers 50 features you won’t find a use for. After that I’ll introduce you to some of those “big templating plugin[s],” so that you can have some more options and power if you prefer.

Quick and Dirty JavaScript Templating Solution

This example uses some concepts from a post on NetTuts, but applies them to the Twitter widget I created in my post titled How and Why JZ Publish / Subscribe Should Be Used. We’ll start by creating the HTML template.

1
2
3
4
5
6
7
8
<script type="template" id="tweet-template">
<div class="tweet">
<a href="http://twitter.com/{{from_user}}" target="_blank">
<img src="{{profile_image_url}}" class="tweet-image" />
</a>
{{text}}
</div>
</script>

Let’s take a closer look at this, shall we? The template is wrapped in a script tag for 2 reasons: (1) it helps show us that the HTML within it is used by a script and (2) it will not render the inside HTML on the screen. So, technically the template is all the code within the script tag and does not technically include the script tag. Next, we see that there is an id on the script tag. This is how it is identified because you could be using several templates on one page. Also the type is set to “template” and not the usual “text/javascript.” This distinguishes it from actual JavaScript code.

Now we get to the meat and potatoes (YUM!) of the template. The template consists entirely of normal HTML with a few strings wrapped in double curly brackets ({{ }}). Those bracketed words are what get replaced by some JavaScript values. The word inside the brackets refers to a property name for a JavaScript object. Below you’ll see the JavaScript data that we retrieved from Twitter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[
{
"from_user":"JoeZimJS",
"profile_image_url":"http://a0.twimg.com/profile_images/1508527935/logo_square_normal.png",
"text":"\"Direct assault on Internet users.\" That's what ACLU calls a snooping bill moving thru House: http://t.co/0qu7S9DV via @demandprogress",
...
},
{
"from_user":"JoeZimJS",
"profile_image_url":"http://a0.twimg.com/profile_images/1508527935/logo_square_normal.png",
"text":"@inserthtml Go right ahead. I'm sure others have thought of it as well.",
...
},
{
"from_user":"JoeZimJS",
"profile_image_url":"http://a0.twimg.com/profile_images/1508527935/logo_square_normal.png"
"text":"New Post on http://t.co/o1qth8c3 coming up tomorrow morning: JavaScript Templating. You won't want to miss this amazing article.",
...},
...
]

Notice how there is a from_user property within each result. That property will replace every instance of {{from_user}} inside the template. Same thing applies for every other property within the results. So, how are we ripping out all of those bracketed words and throwing in those properties instead? Well how about we use the code I wrote below!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
useTemplate = function(template, data) {
var i = 0,
len = data.length,
html = '';

// Replace the {{XXX}} with the corresponding property
function replaceWithData(data_bit) {
var html_snippet, prop, regex;

for (prop in data_bit) {
regex = new RegExp('{{' + prop + '}}', 'ig');
html_snippet = (html_snippet || template).replace(regex, data_bit[key]);
}

return html_snippet;
}

// Go through each element in the array and add the properties to the template
for (; i < len; i++) {
html += replaceWithData(data[i]);
}

// Give back the HTML to be added to the DOM
return html;
};

This might be a bit harder to understand, so I’ll go through it slowly. The function takes 2 parameters. The first one is a string containing the template code, which you can retrieve by using innerHTML on the script tag that contains the template. The second parameter is the data, such as the Twitter results in the previous code sample.

Next up, we create a function that iterates through each of the properties, finds the curly bracket expression(s) in the template that matches the property, and replaces it with the value from the property. It then returns the template with the property values in it. After we’ve created that function, we have a for loop go through the array of Twitter results and call the function with each individual result, creating HTML code for each of them and concatenating them together into one big chunk of HTML. Then that HTML is returned so you can drop it in anywhere you want to.

That’s about all there is to it. If you want to see an example of this function getting used, go ahead and look below. It’s pretty simple, even when not using jQuery or any other library to help you get through the DOM.

JavaScript Templating Libraries

The small templating solution I showed above may not be what you want, either because it lacks some features that you need or because you can’t bring yourself to copy and paste it into your code. In any case, there are plenty of great options out there just waiting for you. If you don’t use jQuery or you’d rather just use a standalone library, I recommend using Handlebars.js. However, if you do use jQuery and like the idea of using templating as a extension of jQuery’s DOM manipulation, then the jQuery Templates plugin – which is an official jQuery plugin, though it is no longer being developed – is the tool for you. Either way, you’ll be getting a truly great library that has been tested by thousands of people and can handle any template-related problem you can conjure up.

{{The_End}}

Well, that brings us to the end of this tutorial. I’m entirely ok with you using the libraries rather than the code I wrote up there. I had considered turning that code into a jQuery plugin, but the current libraries are already so awesome that the only reason for doing it would be having a plugin with a tiny footprint for when you didn’t need the power of those other libraries, which I don’t think is a good enough reason. Anyway, I enjoyed writing this and I hope you enjoyed reading it. Make sure to be a good sport and write a comment and/or share the post below because it’s your involvement that keeps this blog alive. Happy Coding!

Author: Joe Zimmerman

Author: Joe Zimmerman Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.