Made _.template delimeters customizable

This commit is contained in:
noah
2010-01-15 23:25:52 -05:00
parent 4f1a72da51
commit 94195e661d
3 changed files with 41 additions and 4 deletions

View File

@@ -994,6 +994,11 @@ _.uniqueId('contact_');
variables. If you're writing a one-off, you can pass the <b>context</b>
object as the second parameter to <b>template</b> in order to render
immediately instead of returning a template function.
<br />
If the <i>&lt;% &hellip; %&gt;</i> 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.
</p>
<pre>
var compiled = _.template("hello: &lt;%= name %&gt;");
@@ -1003,6 +1008,15 @@ compiled({name : 'moe'});
var list = "&lt;% _.each(people, function(name) { %&gt; &lt;li&gt;&lt;%= name %&gt;&lt;/li&gt; &lt;% }); %&gt;";
_.template(list, {people : ['moe', 'curly', 'larry']});
=&gt; "&lt;li&gt;moe&lt;/li&gt;&lt;li&gt;curly&lt;/li&gt;&lt;li&gt;larry&lt;/li&gt;"
var custom = "{{ _.each(people, function(name) { }} &lt;li&gt;{{= name }}&lt;/li&gt; {{ }); }}";
_.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']});
=&gt; "&lt;li&gt;moe&lt;/li&gt;&lt;li&gt;curly&lt;/li&gt;&lt;li&gt;larry&lt;/li&gt;"
</pre>
<h2>Chaining</h2>

View File

@@ -39,8 +39,23 @@ $(document).ready(function() {
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');
var custom = _.template({
template: "<ul>{{ for (key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>",
start: "{{", end: "}}",
interpolate: /\{\{=(.+?)\}\}/g
});
result = custom({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');
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");
});
});

View File

@@ -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;
};