ERB for JavaScript

Today I found this at reddit and was stunned by the way it was implemented. I now created a similar implementation, it’s just a little smaller, supports escaping and doesn’t use an evil delimiter hack and it also supports all of the ERB goodness including the leading-percent sign block support.

Example:

var template = new JSTemplate('\
  <%# This is a nice little comment %>\
  <p>Total number of users: <%= this.users.length %></p>\
  <ul>\
  <% each(this.users, function(user, idx) { %>\
    <li>#<%= idx + 1 %> <%= escape(user) %></li>\
  <% }) %>\
  </ul>\
  <p>Last updated on: <%= this.lastUpdate %>\
');
document.getElementById('output').innerHTML = template.render({
  users:        ['H4><0r', 'peter', 'anton'],
  lastUpdate:   new Date()
});

Available helper functions are each and escape, now guess what they do.

Sourcecode is here: jstemplates

Update: It can process ERB % statements now too.

4 Responses to “ERB for JavaScript”

  1. Very cool bit of code. I was fooling with it, trying to load the template text using an XMLHttpRequest, with the target document just a plain text document containing the markup, but I was having issues with preparing the template string to instantiate JSTemplate. To make it work for me I had to prepare the responseText as follows:

    		var req=new XMLHttpRequest();
    		req.open("GET", "sample.jst",false);
    		req.send(null);
    		var txt=req.responseText;
    		txt=txt.replace(/[\n\r]/g,""); //!!!!IMPORTANT
    		var template=new JSTemplate(txt);
    		document.getElementById('output').innerHTML=
    			template.render({
    			    users:        ['H4>
    
    Comment by David Edelstein — Tuesday, July 10th, 2007 @ 3:36 am
  2. In theory the newline replacement shouldn’t be necessary. I wonder which browser you’re using, probably the parser has to cope with the carriage return character too.

    Comment by Armin Ronacher — Thursday, July 12th, 2007 @ 12:05 am
  3. Hrm, your comment system cut off half my comment, I think that it didn’t like that those > < in H4><or (so im going to use html-entities)….Anyways, It was word for word from your example code and you caught my drift anyways.

    I’m using firefox, but maybe I should see how IE does it, but I doubt that it would work as expected either.

    More interestingly though, your script does some pretty neat stuff that you didn’t include in your example. check this example template out and you’ll see that it works too!

    <% this.fcn=function(){%><p>P function called</p><%} ;%>\
        <%# This is a nice little comment %>\
        <p>Total number of users: <%= this.users.length %></p>\
        <ul>\
        <% each(this.users, function(user, idx) { %>\
          <li>#<%= idx + 1 %> <%= escape(user) %></li>\n\
        <% }) %>\
        </ul>\
        <%this.fcn();%>\
        <p>Last updated on: <%= this.lastUpdate %>\
    ');

    I also made an iif function to include along with each and escape (can leave out the else function and this still works):

      function iif(cond, t_stmt, f_stmt) {
        if(cond){
    	return t_stmt();
        }else if(f_stmt){
    	return f_stmt();
        }
      }

    example:

     <% iif(true,function(){%><br>is true<%}, function(){%><br>is false<%}) %>\

    you can even use the iif function using a template function as a parameter and it works too!

    very nice.

    - Dave

    Comment by David Edelstein — Thursday, July 12th, 2007 @ 4:12 pm
  4. Hiya, wanted this working in IE6 and found a couple things that made it work:
    -the split function doesn’t behave properly with regexp captures (used http://blog.stevenlevithan.com/archives/cross-browser-split to fix)
    -indexing strings in IE doesn’t work, so replaced all string indexes (part[0], etc.) w/ part.charAt(0)
    -eval function in IE doesn’t work, fix is at http://arrix.blogspot.com/2007/04/eval-bug-in-ie.html

    Comment by Charles Cooke — Monday, July 23rd, 2007 @ 12:58 am

Leave a Reply

cogitations driven by wordpress