tags:

views:

77

answers:

4
+1  A: 

I have become a big fan of mustache.js recently for doing exactly this kind of thing.

http://github.com/janl/mustache.js/

Edit:

if I tweak calvinf's JSON format a little then this is an example using mustache.js:

<html>
  <head>
   <script type="text/javascript" src=" http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://github.com/janl/mustache.js/raw/master/mustache.js"&gt;&lt;/script&gt;
    <script type="text/javascript">
    var topics = {
    topics: [
    {
    title : "Topic 1",
    items : [
      {title: "1a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "1b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
    },
    {
    title : "Topic 2",
    items : [
      {title: "2a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "2b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
    }
    ]};


 var template = "<ul>{{#topics}}<li>{{title}}<ul>{{#items}}<li id=\"foo_item{{title}}\"><a href=\"{{link}}\">{{text}}</a></li>{{/items}}</ul>{{/topics}}</ul>";

      $(document).ready(function() {
  $("#topics").html(Mustache.to_html(template, topics));
      });

    </script>
    <title></title>
  </head>
  <body>
   <div id="topics"></div>
  </body>
</html>

If you want a speed benchmark for JavaScript templating libraries I found this link useful:

http://www.viget.com/extend/benchmarking-javascript-templating-libraries/

Mark McLaren
mustache.js is a good templating system to check out. I'd also take a look at jquery-tmpl as it'll likely be included in jQuery 1.5 based on comments jeresig has made. http://github.com/jquery/jquery-tmpl
calvinf
Resig's templating is super-dangerous, as it fails to HTML-encode by default (or even optionally). Anything you build on it is doomed to a thousand HTML-injection XSS security holes. Stay well away. (Mustache does not make this grievous error.)
bobince
@bobince -- while I completely agree that not have the **option** of HTML-encoding input in a client-side Javascript is no good at all, isn't it a better practice to handle the HTML-encoding on the server side?
Sean Vieira
@Sean: Only if you're producing the HTML itself on the server side, which presumably you're not if you're templating with mustache. Passing HTML-encoded text back in a JSON object for placement in a template is inappropriate; what if you wanted to use the same text in another context too, like writing to an attribute via DOM, or putting in an `alert()` box? The process of HTML-encoding should always be done at the point of inserting text into HTML.
bobince
+2  A: 

First recommendation is taking a look at the JSON site. It has some examples of JSON code in JavaScript.

If you're structuring the whole thing out of JSON, I'd do it like this.

var topics = {
  topic1: {
    title : "Topic 1",
    items : [
      {title: "1a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "1b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
  },
  topic2: {
    title : "Topic 2",
    items : [
      {title: "2a", link: "http://www.example.com/", text: "Link Text or HTML"},
      {title: "2b", link: "http://www.example.com/", text: "Link Text or HTML"}
    ]
  }
};

If you only need a subset of the information you could do it differently, but this should give you something to start with.

To update the DOM with these values, you can loop through the appropriate array from the JSON object and then populate the values. Use the jQuery .html( htmlString ) function.

I hope this helps you get started.

calvinf
+1  A: 

I would recommend the excellent underscore.js's template function for this sort of thing.

Sean Vieira
A: 

You can use DOM-like methods to set attributes and text content instead to avoid the HTML-escaping issues you'll have with plain html()-setting and the more naïve of the templating systems. For example using jQuery 1.4 and with JSON input along the lines of calvinf's example:

var ul0= $('<ul>');
$.each(topics, function() {
    var li0= $('<li>', {text: this.title});
    var ul1= $('<ul>');
    $.each(this.items, function() {
        ul1.append($('<li>', {id: 'foo_'+this.title})
            .append($('<a>', {href: this.link, text: this.text})
                .append($('<strong>', {text: this.data0}))
                .append($('<span>', {text: this.data1}))
                .append($('<em>', {text: this.data2}))
            )
        );
    });
    li0.append(ul1);
    ul0.append(li0);
});
bobince