Search code examples
javascriptdust.jscanjs

JavaScript templating, why so great?


I've been looking into JavaScript templating libraries like dust.js and other more extensive libraries like canJS

Where I work we do nearly 99% of any application / site on the client side. Currently I just build strings of html, inject into the dom, listen for clicks / actions, do ajax, build more strings of html from the results and inject into the dom and so on.

If you take this simple example.

//stringbuilder
function StringBuilder(e){this.strings=new Array("");this.append(e)}StringBuilder.prototype.append=function(e){if(e){this.strings.push(e)}};StringBuilder.prototype.clear=function(){this.strings.length=1};StringBuilder.prototype.toString=function(){return this.strings.join("")}

var data = {
    fname: "Joe",
    lname: "Doe",
    occupation: "Developer",
    things: ["some", "list", "of", "things"]
}

var sb = new StringBuilder();

sb.append("<h1>" + data.fname + " " + data.lname + "</h1>");
sb.append("<p>Occupation: " + data.occupation + "</p>");
sb.append("<h3>A list of things</h3>");
sb.append("<ul>");
for (var i = 0; i < data.things.length; i++) {
    sb.append("<li>" + data.things[i] + "</li>");
}
sb.append("</ul>");

$("#output").html(sb.toString());

In what way could this be improved by templating? From what I've seen I would have to adapt to a particular template syntax which isn't any easier to read or maintain than the above. What about complex layouts, or scenarios where you have recursion (lists within lists without knowing how many levels it may go). I feel the templating syntax / engine my be a limiting factor in some cases.

I suppose it's nice to pull that html out of the JS completely, but lets say using script tags with the template syntax inside the HTML is off the table, I don't particularly want the templates as external files I need to perform extra requests to read.

Please educate me!


Solution

  • Well, just compare:

    sb.append("<h1>" + data.fname + " " + data.lname + "</h1>");
    sb.append("<p>Occupation: " + data.occupation + "</p>");
    sb.append("<h3>A list of things</h3>");
    sb.append("<ul>");
    for (var i = 0; i < data.things.length; i++) {
        sb.append("<li>" + data.things[i] + "</li>");
    }
    sb.append("</ul>");
    

    To

    <h1>@fname @lname</h1>
    <p>Occupation: @occupation</p>
    <h3>A list of things</h3>
    <ul>
        @foreach( thing in things ) {
            <li>@thing</li>
        }
    </ul>
    

    Which looks more maintainable to you?

    demo