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> 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 object as the second parameter to <b>template</b> in order to render
immediately instead of returning a template function. 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> </p>
<pre> <pre>
var compiled = _.template("hello: &lt;%= name %&gt;"); 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;"; 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']}); _.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;" =&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> </pre>
<h2>Chaining</h2> <h2>Chaining</h2>

View File

@@ -39,8 +39,23 @@ $(document).ready(function() {
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');
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"); var quoteTemplate = _.template("It's its, not it's");
equals(quoteTemplate({}), "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. // "Secrets of the JavaScript Ninja", page 83.
// Single-quote fix from Rick Strahl's version. // Single-quote fix from Rick Strahl's version.
_.template = function(str, data) { _.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 fn = new Function('obj',
'var p=[],print=function(){p.push.apply(p,arguments);};' + 'var p=[],print=function(){p.push.apply(p,arguments);};' +
'with(obj){p.push(\'' + 'with(obj){p.push(\'' +
str.replace(/[\r\t\n]/g, " ") str.replace(/[\r\t\n]/g, " ")
.replace(/'(?=[^%]*%>)/g,"\t") .replace(new RegExp("'(?=[^"+end[0]+"]*"+end+")","g"),"\t")
.split("'").join("\\'") .split("'").join("\\'")
.split("\t").join("'") .split("\t").join("'")
.replace(/<%=(.+?)%>/g, "',$1,'") .replace(interpolate, "',$1,'")
.split("<%").join("');") .split(start).join("');")
.split("%>").join("p.push('") .split(end).join("p.push('")
+ "');}return p.join('');"); + "');}return p.join('');");
return data ? fn(data) : fn; return data ? fn(data) : fn;
}; };