Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

backbone/underscore template in mustache format causing error on # pound/hash symbol?

I'm using backbone's underscore templating engine with the mustache formatting patterns.

I have already been successfully using it elsewhere in the project but now for the first time I'm using the looping list patterns from mustache to populate the template which is throwing an error which I'm a bit baffled by. The error in chrome is:

"Uncaught SyntaxError: Unexpected token ILLEGAL"

and points to underscore's template function in the backtrace, which is pretty useless but in firebug i get a more helpful error like this:

enter image description here

Suggesting that the hash symbol '#' is the issue, which would make sense as I know that mustache is working ok as there are many other parts of the project using it well, also this is the first time I'm using the hash sybol in my templates.It looks like a problem either with the looping feature or with the interpolation/template settings for underscore.

Here's the relevant piece of my template:

<div class="thumblist thumblistleft" id="currentprojectslist">
    <div class="thumb-list-header">
         <h2>current projects</h2>
    </div>
    <div class="thumb-list-area">
        <ol>
        {{#worklist}}       <!----- LOOK HERE --->
            {{#current}}
              <li><a>{{title}}</a></li>
            {{/current}}
        {{/worklist}}
        </ol>
    </div>
</div>

and here's a sample of the JSON (which all validates fine)

{blah blah blah lot in here before,"worklist":[{"thumb":"img/project-s.jpg","id":"340","title":"Test Project One","desc":"big load of content here","current":true}], and so on....}

I was initially following this example here for reference: http://mustache.github.com/#demo

NOW HERES WHERE I THINK THE PROBLEM MIGHT BE:

underscore.js suggests using this before rendering a mustache template:

_.templateSettings = {
     evaluate : /\{\[([\s\S]+?)\]\}/g,
     interpolate : /\{\{([\s\S]+?)\}\}/g
};

also:

interpolate : /\{\{(.+?)\}\}/g

Also just the interpolate statement, ive tried both. However my regex knowledge is really poor and I have a feeling it might not accomodate the hash? At any rate.... I'm totally stumped. Can someone help me out here?

is it even possible to loop like this? looking at underscore source i'm not sure: http://documentcloud.github.com/underscore/docs/underscore.html#section-120

Thanks very much

like image 740
Alex Avatar asked Jan 25 '12 11:01

Alex


2 Answers

Came up against this problem today. The issue seems to be the order that Underscore does the templating: escape, interpolate, then evaluate. So you need to explicitly ignore any matches for {{# in your interpolation regex:

_.templateSettings = {
  evaluate:    /\{\{#([\s\S]+?)\}\}/g,            // {{# console.log("blah") }}
  interpolate: /\{\{[^#\{]([\s\S]+?)[^\}]\}\}/g,  // {{ title }}
  escape:      /\{\{\{([\s\S]+?)\}\}\}/g,         // {{{ title }}}
}

It doesn't actually work the same way as Mustache: there aren't proper blocks in Underscore's templating, so there is no need for a closing block {{/}}. You just need to match your statements up like you would with standard Underscore templates.

like image 84
Max Wheeler Avatar answered Nov 15 '22 08:11

Max Wheeler


I'm posting for the sakes of anyone else facing this issue. After a lot of googling to no avail, i went through the underscore.js source with a fine toothed comb and basically you have to either use underscore's template syntax, writein ugly function processors into your JSON or include mustache.js into your source and call:

Mustache.render(mytemplate,mymodel)

and foresake underscore's

_.template(..) function

Annoying but whatever, I hope that helps someone

like image 27
Alex Avatar answered Nov 15 '22 06:11

Alex