From f50690f67e6f333f7c213b7f646a30ddeba07348 Mon Sep 17 00:00:00 2001 From: Brad Dunbar Date: Wed, 4 Apr 2012 08:15:49 -0700 Subject: [PATCH] Tweak variable names. Update docs. * Restore template.source. * Use variable instead of varname. * Use text for template input. * Include settings in documentation. --- index.html | 19 +++++++++---------- test/utility.js | 6 +++--- underscore.js | 18 +++++++++--------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/index.html b/index.html index 1872377d9..ef0018e75 100644 --- a/index.html +++ b/index.html @@ -1335,7 +1335,7 @@ _.result(object, 'stuff'); => "nonsense"

- template_.template(templateString, [context]) + template_.template(templateString, [data], [settings])
Compiles JavaScript templates into functions that can be evaluated for rendering. Useful for rendering complicated bits of HTML from JSON @@ -1343,10 +1343,11 @@ _.result(object, 'stuff'); <%= … %>, as well as execute arbitrary JavaScript code, with <% … %>. If you wish to interpolate a value, and have it be HTML-escaped, use <%- … %> When you evaluate a template function, pass in a - context object that has properties corresponding to the template's free - variables. If you're writing a one-off, you can pass the context + data object that has properties corresponding to the template's free + variables. If you're writing a one-off, you can pass the data object as the second parameter to template in order to render - immediately instead of returning a template function. + immediately instead of returning a template function. The settings argument + should be a hash containing any _.templateSettings that should be overriden.

@@ -1397,25 +1398,23 @@ template({name : "Mustache"});
       

By default, template places the values from your data in the local scope via the with statement. However, you can specify a single variable name - with the varname setting. + with the variable setting.

-_.templateSettings.varname = 'data';
-var template = _.template("<%= data.hasWith %>");
-template({hasWith: 'no'});
+_.template("<%= data.hasWith %>", {hasWith: 'no'}, {variable: 'data'});
 => "no"

Precompiling your templates can be a big help when debugging errors you can't reproduce. This is because precompiled templates can provide line numbers and a stack trace, something that is not possible when compiling templates on the client. - template provides the compiled property on the compiled template + template provides the source property on the compiled template function for easy precompilation.

<script>
-  JST.project = <%= _.template(jstText).compiled %>;
+  JST.project = <%= _.template(jstText).source %>;
 </script>
diff --git a/test/utility.js b/test/utility.js index 03577800a..a367dc1cf 100644 --- a/test/utility.js +++ b/test/utility.js @@ -178,11 +178,11 @@ $(document).ready(function() { strictEqual(_.result(null, 'x'), null); }); - test('_.templateSettings.varname', function() { + test('_.templateSettings.variable', function() { var s = '<%=data.x%>'; var data = {x: 'x'}; - strictEqual(_.template(s, data, {varname: 'data'}), 'x') - _.templateSettings.varname = 'data'; + strictEqual(_.template(s, data, {variable: 'data'}), 'x') + _.templateSettings.variable = 'data'; strictEqual(_.template(s)(data), 'x') }); diff --git a/underscore.js b/underscore.js index 30ba01ed5..5cf516b80 100644 --- a/underscore.js +++ b/underscore.js @@ -951,13 +951,13 @@ // JavaScript micro-templating, similar to John Resig's implementation. // Underscore templating handles arbitrary delimiters, preserves whitespace, // and correctly escapes quotes within interpolated code. - _.template = function(source, data, settings) { + _.template = function(text, data, settings) { settings = _.extend(_.templateSettings, settings); // Compile the template source, taking care to escape characters that // cannot be included in a string literal and then unescape them in code // blocks. - var compiled = "__p.push('" + source + var source = "__p.push('" + text .replace(escaper, function(match) { return '\\' + escapes[match]; }) @@ -971,13 +971,13 @@ return "');\n" + unescape(code) + "\n;__p.push('"; }) + "');\n"; - // If no varname is specified, place data values in local scope. - if (!settings.varname) compiled = 'with(obj||{}){\n' + compiled + '}\n'; + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; - compiled = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};\n' + - compiled + "return __p.join('');\n"; + source = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};\n' + + source + "return __p.join('');\n"; - var render = new Function(settings.varname || 'obj', '_', compiled); + var render = new Function(settings.variable || 'obj', '_', source); if (data) return render(data, _); var template = function(data) { return render.call(this, data, _); @@ -985,8 +985,8 @@ // Provide the compiled function source as a convenience for build time // precompilation. - template.compiled = 'function(' + (settings.varname || 'obj') + '){\n' + - compiled + '\n}'; + template.source = 'function(' + (settings.variable || 'obj') + '){\n' + + source + '\n}'; return template; };