2
\$\begingroup\$

I am terrible with writing JavaScript code that outputs HTML. So, here's how a string literal looks like in a project that I'm working on:

tweet = '<div class="h-ui-box">'

+ '<table>'

+ '<tr>'

+ '<td id="first">'
+ '<img src="' + item.profile_image_url + '" alt="' + item.from_user + '" width="56">'
+ '</td>'

+ '<td>'
+ '<section>'
+ '<header>'
+ '<h1><a href="http://twitter.com/'
+ (function(from_user) { 
    return from_user + '">' + from_user + '</a></h1>';
})(item.from_user)
+ '</header>'
+ '<article>' + item.text.twitterify() + '</article>'
+ '</section>'
+ '</td>'

+ '</tr>'

+ '</table>'

+ '<footer><a href="http://twitter.com/' + item.from_user + '/status/' + item.id.toString() + '" target="_blank">' + item.created_at + '</a></footer>'
+ '</div>';

How would I go about to improve this?

\$\endgroup\$

4 Answers 4

4
\$\begingroup\$

Make yourself a "template" that you immediately convert into html (using innerHtml or whatever your framework has handy), then use the dom to fix up the few variable bits. You may use ids to locate the tags that need substitution, if you can guarantee they are unique. Otherwise use XPath.

\$\endgroup\$
3
\$\begingroup\$

Writing that much markup dynamically will prove a headache eventually. Put the markup directly into your page, including reasonable default content. It'll be easier for you to read/edit/validate, while ensuring that you're giving something to search engines, screenreaders, and anyone who's got JS turned off. From there, follow Tobu's counsel.

\$\endgroup\$
3
\$\begingroup\$

I've had lots of success with jquery templates in the past.

For example:

var markup='<tr><td>${id}</td><td><a href="/index/tender/id/${id}">${title}</a></td><td {{if days_left <1}} class="label warning" {{/if}} >${days_left}</td></tr>';    

$.template( "templateTenders", markup ); //compile the markup as a jquery.template

//....get json data - via an ajax call    
$.tmpl("templateTenders", data).appendTo( "#tenderlist" );  //data is a JSON data object (assoc array) that comes in via ajax.

[edit]

I've since moved onto using mustasche.js which is wonderful.

[edit 2013]

I've since moved onto using handlebar.js(https://stackoverflow.com/questions/4392634/mustache-js-vs-jquery-tmpl/9481181#9481181) which is even more wonderful and a lot faster than mustache.js

\$\endgroup\$
1
  • \$\begingroup\$ Please note that, as I've mentioned in my answer to this question, the jQuery Templates plugin is no longer being developed or maintained, and has been superseded by JSRender and JSViews, which are admittedly still pre-beta, but it looks like they will be the way forward. \$\endgroup\$ Commented Dec 7, 2011 at 21:26
1
\$\begingroup\$

This is an area I've done a bit of work in lately.

Initially my requirements were pretty minimal, and so I started using a really basic function that acted on a String (the template) and accepted an Object (containing the data to be presented) as a parameter, like this:

if (!String.prototype.supplant) {
    String.prototype.supplant = function (o) {
        return this.replace(/{([^{}]*)}/g,
            function (a, b) {
                var r = o[b];
                return typeof r === 'string' || typeof r === 'number' ? r : a;
            }
        );
    };
}

(Thanks to Douglas Crockford)

You'd use it like this:

param = {domain: 'valvion.com', media: 'http://media.valvion.com/'};
url = "{media}logo.gif".supplant(param);

So your template is a string of markup, with placeholders named for the properties in the object. This approach is a little tidier than inlining everything, but still doesn't mitigate the slightly dirty feeling of having markup in JS strings.

My requirements then became more complex, requiring some conditional logic within the templates. I then discovered jQuery templating (since jQuery is our library of choice) but it unfortunately died in beta, but has fortunately been superseded by JSRender.

JSRender is jQuery-independent, really fast, flexible, and uses templates that are declared as elements in the markup of the page rather than in JS strings.

It has some nifty conditional logic and other handy features.

I'd suggest this would be the way to go. Do bear in mind, however, that JSRender is currently pre-beta. I've just started using it for a particular project, and it's working really well for me.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.