Fixing Issue #35. newlines in evaluated code.

This commit is contained in:
Jeremy Ashkenas
2010-09-27 17:35:43 -04:00
parent 902f1192e0
commit fbd682d9ec
3 changed files with 22 additions and 26 deletions

View File

@@ -1065,17 +1065,15 @@ _.template(list, {people : ['moe', 'curly', 'larry']});
<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 <b>start</b> and <b>end</b> tokens, and an <b>interpolate</b> regex Define and an <b>interpolate</b> regex, and an (optional) <b>evaluate</b> regex
to match expressions that should be evaluated and inserted. For example, to match expressions that should be inserted and evaluated, respectively.
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:
</p> </p>
<pre> <pre>
_.templateSettings = { _.templateSettings = {
start : '{{',
end : '}}',
interpolate : /\{\{(.+?)\}\}/g interpolate : /\{\{(.+?)\}\}/g
}; };

View File

@@ -55,7 +55,9 @@ $(document).ready(function() {
var result = basicTemplate({thing : 'This'}); var result = basicTemplate({thing : 'This'});
equals(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); equals(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
var fancyTemplate = _.template("<ul><% for (key in people) { %><li><%= people[key] %></li><% } %></ul>"); var fancyTemplate = _.template("<ul><% \
for (key in people) { \
%><li><%= people[key] %></li><% } %></ul>");
result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}}); result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
equals(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates'); equals(result, "<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>", 'can run arbitrary javascript in templates');
@@ -84,8 +86,7 @@ $(document).ready(function() {
equals(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); equals(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
_.templateSettings = { _.templateSettings = {
start : '{{', evaluate : /\{\{(.+?)\}\}/g,
end : '}}',
interpolate : /\{\{=(.+?)\}\}/g interpolate : /\{\{=(.+?)\}\}/g
}; };
@@ -100,8 +101,7 @@ $(document).ready(function() {
equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
_.templateSettings = { _.templateSettings = {
start : '<?', evaluate : /<\?(.+?)\?>/g,
end : '?>',
interpolate : /<\?=(.+?)\?>/g interpolate : /<\?=(.+?)\?>/g
}; };
@@ -116,8 +116,6 @@ $(document).ready(function() {
equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'."); equals(quoteInStatementAndBody({foo: "bar"}), "Statement quotes and 'quotes'.");
_.templateSettings = { _.templateSettings = {
start : '{{',
end : '}}',
interpolate : /\{\{(.+?)\}\}/g interpolate : /\{\{(.+?)\}\}/g
}; };

View File

@@ -617,8 +617,7 @@
// By default, Underscore uses ERB-style template delimiters, change the // By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters. // following template settings to use alternative delimiters.
_.templateSettings = { _.templateSettings = {
start : '<%', evaluate : /<%(.+?)%>/g,
end : '%>',
interpolate : /<%=(.+?)%>/g interpolate : /<%=(.+?)%>/g
}; };
@@ -628,21 +627,22 @@
// With alterations for arbitrary delimiters, and to preserve whitespace. // With alterations for arbitrary delimiters, and to preserve whitespace.
_.template = function(str, data) { _.template = function(str, data) {
var c = _.templateSettings; var c = _.templateSettings;
var endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g"); var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
var fn = new Function('obj',
'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
'with(obj||{}){__p.push(\'' + 'with(obj||{}){__p.push(\'' +
str.replace(/\r/g, '\\r') str.split("'").join("\\'")
.replace(c.interpolate, function(match, code) {
return "'," + code.replace(/\\'/g, "'") + ",'";
})
.replace(c.evaluate || null, function(match, code) {
return "');" + code.replace(/\\'/g, "'")
.replace(/[\r\n\t]/g, ' ') + "__p.push('";
})
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n') .replace(/\n/g, '\\n')
.replace(/\t/g, '\\t') .replace(/\t/g, '\\t')
.replace(endMatch,"✄") + "');}return __p.join('');";
.split("'").join("\\'") var func = new Function('obj', tmpl);
.split("✄").join("'") return data ? func(data) : func;
.replace(c.interpolate, "',$1,'")
.split(c.start).join("');")
.split(c.end).join("__p.push('")
+ "');}return __p.join('');");
return data ? fn(data) : fn;
}; };
// ------------------------------- Aliases ---------------------------------- // ------------------------------- Aliases ----------------------------------