From 0ea95746a8d64b434389832d5daf3bb37ff83a59 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Mon, 10 Sep 2012 14:50:17 -0700 Subject: [PATCH] Allow auto-loading of partials Fixes #247 --- CHANGES | 2 ++ mustache.js | 18 +++++++++++++----- test/parse_test.js | 4 ++-- test/render_test.js | 15 +++++++++------ test/writer_test.js | 21 +++++++++++++++++++++ 5 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 test/writer_test.js diff --git a/CHANGES b/CHANGES index 06c055a..687af82 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ = HEAD * Rename Renderer => Writer. + * Allow partials to be loaded dynamically using a callback (thanks @TiddoLangerak + for the suggestion). * Fixed a bug with higher-order sections that prevented them from being passed the raw text of the section from the original template. * More concise token format. Tokens also include start/end indices in the diff --git a/mustache.js b/mustache.js index dbbc1fe..c9498e4 100644 --- a/mustache.js +++ b/mustache.js @@ -212,8 +212,12 @@ var Mustache; var self = this; cache[key] = function (view, partials) { if (partials) { - for (var name in partials) { - self.compilePartial(name, partials[name]); + if (typeof partials === "function") { + self._loadPartial = partials; + } else { + for (var name in partials) { + self.compilePartial(name, partials[name]); + } } } @@ -269,7 +273,12 @@ var Mustache; }; Writer.prototype._partial = function (name, context) { + if (!(name in this._partialCache) && this._loadPartial) { + this.compilePartial(name, this._loadPartial(name)); + } + var fn = this._partialCache[name]; + return fn ? fn(context) : ""; }; @@ -306,9 +315,8 @@ var Mustache; } /** - * Low-level function that compiles the given `tokens` into a - * function that accepts two arguments: a Context and a - * Writer. + * Low-level function that compiles the given `tokens` into a function + * that accepts two arguments: a Context and a Writer. */ function compileTokens(tokens) { var subRenders = {}; diff --git a/test/parse_test.js b/test/parse_test.js index 6a56826..6aa0609 100644 --- a/test/parse_test.js +++ b/test/parse_test.js @@ -1,6 +1,6 @@ var assert = require('assert'); var vows = require('vows'); -var parse = require('./../mustache').parse; +var Mustache = require('./../mustache'); // A map of templates to their expected token output. Tokens are in the format: // [type, value, startIndex, endIndex]. @@ -59,7 +59,7 @@ var spec = {}; for (var template in expectations) { (function (template, tokens) { spec['knows how to parse ' + JSON.stringify(template)] = function () { - assert.deepEqual(parse(template), tokens); + assert.deepEqual(Mustache.parse(template), tokens); }; })(template, expectations[template]); } diff --git a/test/render_test.js b/test/render_test.js index 859cb71..57f41a1 100644 --- a/test/render_test.js +++ b/test/render_test.js @@ -2,15 +2,12 @@ var fs = require("fs"); var path = require("path"); var assert = require("assert"); var vows = require("vows"); +var Mustache = require("./../mustache"); -var Mustache = require(path.join(__dirname, "..", "mustache")); var _files = path.join(__dirname, "_files"); function getContents(testName, ext) { - var file = path.join(_files, testName + "." + ext); - try { - return fs.readFileSync(file, "utf8"); - } catch (e) {} + return fs.readFileSync(path.join(_files, testName + "." + ext), "utf8"); } // You can put the name of a specific test to run in the TEST environment @@ -42,7 +39,13 @@ testNames.forEach(function (testName) { var template = getContents(testName, "mustache"); var expect = getContents(testName, "txt"); - var partial = getContents(testName, "partial"); + + var partial; + try { + partial = getContents(testName, "partial"); + } catch (e) { + // No big deal. + } spec["knows how to render " + testName] = function () { Mustache.clearCache(); diff --git a/test/writer_test.js b/test/writer_test.js new file mode 100644 index 0000000..8fcd6e1 --- /dev/null +++ b/test/writer_test.js @@ -0,0 +1,21 @@ +var assert = require("assert"); +var vows = require("vows"); +var Writer = require("./../mustache").Writer; + +vows.describe("Mustache.Writer").addBatch({ + "A Writer": { + topic: function () { + var writer = new Writer(); + return writer; + }, + "loads partials correctly": function (writer) { + var partial = "The content of the partial."; + var result = writer.render("{{>partial}}", {}, function (name) { + assert.equal(name, "partial"); + return partial; + }); + + assert.equal(result, partial); + } + } +}).export(module);