diff --git a/index.html b/index.html
index 6f100537e..70490a641 100644
--- a/index.html
+++ b/index.html
@@ -994,6 +994,11 @@ _.uniqueId('contact_');
variables. If you're writing a one-off, you can pass the context
object as the second parameter to template in order to render
immediately instead of returning a template function.
+
+ If the <% … %> syntax is not convenient because
+ your templating languages assigns special meaning to it, the delimeters
+ can be customized by passing an object as the first argument. See the
+ code sample below for options.
var compiled = _.template("hello: <%= name %>");
@@ -1003,6 +1008,15 @@ compiled({name : 'moe'});
var list = "<% _.each(people, function(name) { %> <li><%= name %></li> <% }); %>";
_.template(list, {people : ['moe', 'curly', 'larry']});
=> "<li>moe</li><li>curly</li><li>larry</li>"
+
+var custom = "{{ _.each(people, function(name) { }} <li>{{= name }}</li> {{ }); }}";
+_.template({
+ template: custom,
+ start: '{{', // the code start delimeter
+ end: '}}', // the code end delimeter
+ interpolate: /\{\{=(.+?)\}\}/g // a regex with 1 capture group for the var name
+}, {people : ['moe', 'curly', 'larry']});
+=> "<li>moe</li><li>curly</li><li>larry</li>"
Chaining
diff --git a/test/utility.js b/test/utility.js
index 7b1357dcf..93263c9c6 100644
--- a/test/utility.js
+++ b/test/utility.js
@@ -39,8 +39,23 @@ $(document).ready(function() {
result = fancyTemplate({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
equals(result, "", 'can run arbitrary javascript in templates');
+ var custom = _.template({
+ template: "{{ for (key in people) { }}- {{= people[key] }}
{{ } }}
",
+ start: "{{", end: "}}",
+ interpolate: /\{\{=(.+?)\}\}/g
+ });
+ result = custom({people : {moe : "Moe", larry : "Larry", curly : "Curly"}});
+ equals(result, "", 'can run arbitrary javascript in templates');
+
var quoteTemplate = _.template("It's its, not it's");
equals(quoteTemplate({}), "It's its, not it's");
+
+ var customQuote = _.template({
+ template: "It's its, not it's",
+ start: "{{", end: "}}",
+ interpolate: /\{\{=(.+?)\}\}/g
+ });
+ equals(customQuote({}), "It's its, not it's");
});
});
diff --git a/underscore.js b/underscore.js
index 4385967c6..c0f901651 100644
--- a/underscore.js
+++ b/underscore.js
@@ -563,16 +563,24 @@
// "Secrets of the JavaScript Ninja", page 83.
// Single-quote fix from Rick Strahl's version.
_.template = function(str, data) {
+ var start = '<%', end = '%>',
+ interpolate = /<%=(.+?)%>/g;
+ if(str && !_.isString(str)) {
+ start = str.start || start;
+ end = str.end || end;
+ interpolate = str.interpolate || interpolate;
+ str = str.template;
+ }
var fn = new Function('obj',
'var p=[],print=function(){p.push.apply(p,arguments);};' +
'with(obj){p.push(\'' +
str.replace(/[\r\t\n]/g, " ")
- .replace(/'(?=[^%]*%>)/g,"\t")
+ .replace(new RegExp("'(?=[^"+end[0]+"]*"+end+")","g"),"\t")
.split("'").join("\\'")
.split("\t").join("'")
- .replace(/<%=(.+?)%>/g, "',$1,'")
- .split("<%").join("');")
- .split("%>").join("p.push('")
+ .replace(interpolate, "',$1,'")
+ .split(start).join("');")
+ .split(end).join("p.push('")
+ "');}return p.join('');");
return data ? fn(data) : fn;
};