A template is a chunk of HTML that you need to inject onto the page. Often templates are created “server side” – in that they come to the JavaScript fully formed and just need to be put into the DOM. But sometimes that isn’t feasible or would require and extra round trip to the server which might be slow. In that case having the template right in JavaScript is ideal. You can certainly just do a bit of string concatenation adding together bits of HTML and data until you have the template you need. But that likely isn’t ideal as it doesn’t separate the concerns of data and template. Real JavaScript templating can help here.
In this screencast we’ll cover the basic “why” of JavaScript templating and then specifically cover a simple example of how it’s done in Underscore.js. Then we’ll cover some other alternatives.
Demo
var compiled = _.template(
"<div class='movie'>" +
"<h2><%= movie_title %></h2>" +
"<p><%= movie_desc %></p>" +
"</div>"
);
var i, toAppendString = "";
for (i = 0; i < data.movies.length; i++) {
toAppendString += compiled(data.movies[i]);
}
$("body").append(toAppendString);
See the Pen %= penName %> by Chris Coyier (@chriscoyier) on CodePen
Links
- Basic Demo on CodePen
- Underscore.js Templating
- NetTuts: Best Practices When Working With JavaScript Templates
- MDN: JavaScript templates
- John Resig: JavaScript Micro-Templating
- James Padolsey: Straight-up interplation
Nice one Chris!
Do you have any suggestion on how to separate the templates out of the main javascript file?
For example, using require js, I see that we can separate templates to html files and then loading that using require js text plugin, but not everyone (including me) is inclined to using require js or other module loading libraries.
I end up always adding the templates in script tags with ID in html, but if we have lots of templates, it can get bloated very fast.
Is there an easy way to load template in html format from Javascript? Maybe like this?
@Hendra, I use requirejs, so you end up with something like:
It’s a little bit to get your head around at first, as your code ends up being very modular (not a bad thing!).
Sorry, missed that you already mentioned requirejs.
Hi, great screencast!
Just started using Backbone.js recently – pretty cool. In Backbone all your underscore templates are defined in the html files. Keeps things really neat and tidy in my mind, good separation of concerns – although being a more full on javascript framework, there is a bit more overhead than simply using underscore.
Thanks for the tut, defo a big fan of using JavaScript templating in the right place.
Pretty cool screencast, thx! I did not know that you can use codepen to fake a service :)
So pleased to see a fresh video, I’ve been checking back most days. Not watched yet but just wanted to say I pleased you are back on the videos.
Free javascript book: Learning Javascript Design Patterns
Chris,
I really am learning JS from scratch (and everything else for that matter), but I want to make sure I understand one detail: you use += as your operator in the line:
toAppendString += compiled(data.movies[i]);
Is that because you’re adding each new iteration of the ‘for’ loop to the end of the previous iteration before appending the whole chunk of new populated markup to the DOM?
Thanks!
Yep! the
+=
operator means “add onto the value I already have”. Essentially shortcut forx = x + y
.The reasoning there is “touching” the DOM should generally be considered expensive and to be avoided until necessary. Touching meaning finding something or manipulating it. Rather than doing that over and over inside a loop, we instead prepare what is needed inside the loop and touch the DOM only once.
Hi Chris!
This was a real helpful tutorial.
I was thinking for some time now, how to display my last pushed repos on my user gh-page dynamically. our screencast and this CodePen (the only version is broken, but the downloadable version works) helped me.
Even with the Underscore it much easier!
The site it self need some more styling, but the tech is fine and working. For the curious here is the code
Thank you very much!
Wow… awesome tips chris… Thank you.
Thanks!