2

I had to replace the default underscore teplating delimiters/Interpolate regex for compatibility with asp.net webforms.From the website i opted for mustache like syntax

_.templateSettings = {
  interpolate : /\{\{(.+?)\}\}/g
};

tried this

_.template("{{if(loggedIn)Welcome {{name}}}}",{name:"James",completed:true});

but seems this is not the way( since a error occurred) to check boolean expression using a templating system. But from the docs seems it is possible

as well as execute arbitrary JavaScript code, with <% … %>

  • So how do i execute arbitrary js code with the above mentioned interpolation
mu is too short
  • 426,620
  • 70
  • 833
  • 800
Deeptechtons
  • 10,945
  • 27
  • 96
  • 178

3 Answers3

15

Your problem is that you're defining a Mustache-style replacement for <%= ... %> but trying to use it where you'd normally use <% ... %>. From the fine manual:

Define an interpolate regex to match expressions that should be interpolated verbatim, an escape regex to match expressions that should be inserted after being HTML escaped, and an evaluate regex to match expressions that should be evaluated without insertion into the resulting string.

So there are three regexes in play:

  1. interpolate is for <%= ... %>.
  2. escape is for <%- ... %>.
  3. evaluate is for <% ... %>.

You're telling Underscore to use {{ ... }} in place of <%= ... %> and then you're getting an error because if(loggedIn) can't be interpolated. You just need to fix your _.templateSettings to reflect what you're trying to do:

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

and then your template would look like this:

{{ if(loggedIn) { }}Welcome {{= name }} {{ } }}

Demo: http://jsfiddle.net/ambiguous/RwgVg/8/

You'll need to include the { and } in the template because _.template adds semicolons when compiling the template, that results in things like:

if(loggedIn) {; ...

(Thanks to JaredMcAteer for pointing this out).

You might want to add an escape regex as well, that would probably be /\{\{-(.+?)\}\}/g.

Community
  • 1
  • 1
mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • 5
    This is probably the best explanation of Underscore's templateSettings that I've been able to find. Their website's explanation leaves much to be desired... – AlbertEngelB Aug 23 '12 at 01:53
  • Just a note your fiddle displays `Welcome James` regardless if `loggedIn` is `true` or `false` adding braces before and after `{{ if(loggedIn) { }}Welcome {{= name }}{{}}}` fixes it. Not very readable though. – JaredMcAteer Sep 18 '12 at 21:28
  • @JaredMcAteer: Seems you're right, `_.template` is slipping a `;` into the compiled version so it says `if(loggedIn);...` (you can `console.log(_.template($('#tmpl').html()).source)` to see it). I'll fix this up. And yes, all those braces to get to be a bit much. – mu is too short Sep 18 '12 at 21:38
2

I believe this works for the transition to the mustache style syntax:

/**
     * @configuration transform Underscore.js template syntax
     * @description change the Ruby on Rails style syntax to the Mustache syntax
     * @default <%= var %>
     * @modified 
     *  evaluate        {{ JavaScript code}}    execute arbitrary js code, such as loops
     *  interpolate     {{= variable }}         prints value of variables
     *  escape          {{- variable }}         this syntax will html escape variables
     */ 
    _.templateSettings = {
        evaluate:    /\{\{(.+?)\}\}/g,          
        interpolate: /\{\{=(.+?)\}\}/g,
        escape: /\{\{-(.+?)\}\}/g
    };

This would be mustache style syntax, but keeps the original options of using the "=" and the "-". Not using either evaluates JS, such as for loops. One could swap them around so that the {{var}} was the interpolate and the evaluate could be something else, to keep your templates cleaner if you prefer, since interpolate is most frequently used.

0

As far as you hasn't overwritten the Underscore.templateSettings.evaluate setting you should still can use: <% ... %> for evaluate code.

I have seen attempts to also define the Underscore.templateSettings.evaluate setting to match with Mustache syntax but Mustache fights very strong against template evaluations so is gonna be difficult.

fguillen
  • 36,125
  • 23
  • 149
  • 210
  • hmm so using a dedicated templating library is best i got to do :) – Deeptechtons May 15 '12 at 09:19
  • If you really want Mustache, then without a doubt you need use a dedicated templating library. But remember the origin of this thread was your need of "execute arbitrary js code" in your templates and Mustache is not gonna like this :).. although Mustache is very friendly with simple _boolean_ blocks. – fguillen May 15 '12 at 09:24
  • Yeah, i am not going to hijack the post. I will look for solution until this gets answered!! Surprisingly this too does not work. hmm seems i am doing something terribly wrong here `_.template("<% if(completed)Welcome <%= name%>%>",{name:"James",completed:true});` – Deeptechtons May 15 '12 at 09:30
  • I have found how it works , you have to do below `_.template("<% if(completed){ %>Welcome <%= name%><% } %>",{name:"James",completed:false});` – Deeptechtons May 15 '12 at 09:38