Fixes #411. Partially adding _.templateSettings could break template strings containing the words 'null' or 'undefined'.

This commit is contained in:
Jeremy Ashkenas
2012-01-04 16:00:36 -05:00
parent 7157d0187f
commit 69ed6177ab
3 changed files with 16 additions and 7 deletions

View File

@@ -1235,10 +1235,11 @@ compiled({epithet: "stooge"});
<p> <p>
If ERB-style delimiters aren't your cup of tea, you can change Underscore's If ERB-style delimiters aren't your cup of tea, you can change Underscore's
template settings to use different symbols to set off interpolated code. template settings to use different symbols to set off interpolated code.
Define an <b>interpolate</b> regex, and an (optional) <b>evaluate</b> regex Define an <b>interpolate</b> regex to match expressions that should be
to match expressions that should be inserted and evaluated, respectively. interpolated verbatim, an <b>escape</b> regex to match expressions that should
If no <b>evaluate</b> regex is provided, your templates will only be be inserted after being HTML escaped, and an <b>evaluate</b> regex to match
capable of interpolating values. expressions that should be evaluated without insertion into the resulting
string. You may define or omit any combination of the three.
For example, to perform For example, to perform
<a href="http://github.com/janl/mustache.js#readme">Mustache.js</a> <a href="http://github.com/janl/mustache.js#readme">Mustache.js</a>
style templating: style templating:

View File

@@ -144,6 +144,9 @@ $(document).ready(function() {
var mustache = _.template("Hello {{planet}}!"); var mustache = _.template("Hello {{planet}}!");
equals(mustache({planet : "World"}), "Hello World!", "can mimic mustache.js"); equals(mustache({planet : "World"}), "Hello World!", "can mimic mustache.js");
var templateWithNull = _.template("a null undefined {{planet}}");
equals(templateWithNull({planet : "world"}), "a null undefined world", "can handle missing escape and evaluate settings");
}); });
}); });

View File

@@ -892,6 +892,11 @@
escape : /<%-([\s\S]+?)%>/g escape : /<%-([\s\S]+?)%>/g
}; };
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /.^/;
// JavaScript micro-templating, similar to John Resig's implementation. // JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace, // Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code. // and correctly escapes quotes within interpolated code.
@@ -901,13 +906,13 @@
'with(obj||{}){__p.push(\'' + 'with(obj||{}){__p.push(\'' +
str.replace(/\\/g, '\\\\') str.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'") .replace(/'/g, "\\'")
.replace(c.escape, function(match, code) { .replace(c.escape || noMatch, function(match, code) {
return "',_.escape(" + code.replace(/\\'/g, "'") + "),'"; return "',_.escape(" + code.replace(/\\'/g, "'") + "),'";
}) })
.replace(c.interpolate, function(match, code) { .replace(c.interpolate || noMatch, function(match, code) {
return "'," + code.replace(/\\'/g, "'") + ",'"; return "'," + code.replace(/\\'/g, "'") + ",'";
}) })
.replace(c.evaluate || null, function(match, code) { .replace(c.evaluate || noMatch, function(match, code) {
return "');" + code.replace(/\\'/g, "'") return "');" + code.replace(/\\'/g, "'")
.replace(/[\r\n\t]/g, ' ') .replace(/[\r\n\t]/g, ' ')
.replace(/\\\\/g, '\\') + ";__p.push('"; .replace(/\\\\/g, '\\') + ";__p.push('";