#127: Basics of JavaScript Templating

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

Comments

  1. User Avatar
    Hendra
    Permalink to comment#

    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?

    var compiled = _.template('some.html')
    
    • User Avatar
      Daniel Nitsche
      Permalink to comment#

      @Hendra, I use requirejs, so you end up with something like:

      define(['text!templates/some.html'], function(SomeTemplate) {
          var compiled = _.template(SomeTemplate);
      });
      

      It’s a little bit to get your head around at first, as your code ends up being very modular (not a bad thing!).

    • User Avatar
      Daniel Nitsche
      Permalink to comment#

      Sorry, missed that you already mentioned requirejs.

  2. User Avatar
    Steve
    Permalink to comment#

    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.

  3. User Avatar
    Francisco Alvarez
    Permalink to comment#

    Pretty cool screencast, thx! I did not know that you can use codepen to fake a service :)

  4. User Avatar
    Richard Dale
    Permalink to comment#

    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.

  5. User Avatar
    David Barkoczi
    Permalink to comment#
  6. User Avatar
    Tim Rourke
    Permalink to comment#

    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!

    • User Avatar
      Chris Coyier
      Permalink to comment#

      Yep! the += operator means “add onto the value I already have”. Essentially shortcut for x = 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.

  7. User Avatar
    Pete
    Permalink to comment#

    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!

  8. User Avatar
    Ramesh Chowdarapally
    Permalink to comment#

    Wow… awesome tips chris… Thank you.

  9. User Avatar
    ken
    Permalink to comment#

    Thanks!

Submit a Comment

Posting Code

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.

icon-closeicon-emailicon-linkicon-logo-staricon-menuicon-searchicon-staricon-tag