Skip to content

Commit

Permalink
add partials support
Browse files Browse the repository at this point in the history
  • Loading branch information
simov authored and tj committed Dec 22, 2012
1 parent 3df2bba commit 7d28ae1
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 23 deletions.
56 changes: 46 additions & 10 deletions lib/consolidate.js
Expand Up @@ -91,21 +91,53 @@ function read(path, options, fn) {
});
}

/**
* Read `path` with `options` with
* callback `(err, str)`. When `options.cache`
* is true the partial string will be cached.
*
* @param {String} options
* @param {Function} fn
* @api private
*/

function readPartials(path, options, fn) {
if (!options.partials) return fn();
var partials = options.partials;
var keys = Object.keys(partials);

function next(index) {
if (index == keys.length) return fn(null);
var key = keys[index];
var file = join(dirname(path), partials[key] + extname(path));
read(file, options, function (err, str) {
if (err) return fn(err);

This comment has been minimized.

Copy link
@ptz0n

ptz0n Jan 19, 2015

This modifies the options object (locals) passed to the app.render function in express. Doing multiple renders with the same locals object will cause multiple (and undesired) partial reads.

Using different keys for partial paths and loaded (read) partial strings is one approach. Another one is to set a flag key on the options object when all partials are read, so that we never try to read partial paths that's actually partial strings.

options.partials[key] = str;
next(++index);
});
}

next(0);
}

/**
* fromStringRenderer
*/

function fromStringRenderer(name) {
return function(path, options, fn){
options.filename = path;
if (cache(options)) {
exports[name].render('', options, fn);
} else {
read(path, options, function(err, str){
if (err) return fn(err);
exports[name].render(str, options, fn);
});
}
readPartials(path, options, function (err) {
if (err) return fn(err);
if (cache(options)) {
exports[name].render('', options, fn);
} else {
read(path, options, function(err, str){
if (err) return fn(err);
exports[name].render(str, options, fn);
});
}
});
};
}

Expand Down Expand Up @@ -155,6 +187,7 @@ exports.dust.render = function(str, options, fn){
if (options.views) views = options.views;
if (options.settings && options.settings.views) views = options.settings.views;
}

engine.onLoad = function(path, callback){
if ('' == extname(path)) path += '.' + ext;
if ('/' !== path[0]) path = views + '/' + path;
Expand Down Expand Up @@ -367,7 +400,7 @@ exports.hogan.render = function(str, options, fn){
var engine = requires.hogan || (requires.hogan = require('hogan.js'));
try {
var tmpl = cache(options) || cache(options, engine.compile(str, options));
fn(null, tmpl.render(options));
fn(null, tmpl.render(options, options.partials));
} catch (err) {
fn(err);
}
Expand All @@ -386,6 +419,9 @@ exports.handlebars = fromStringRenderer('handlebars');
exports.handlebars.render = function(str, options, fn) {
var engine = requires.handlebars || (requires.handlebars = require('handlebars'));
try {
for (var partial in options.partials) {
engine.registerPartial(partial, options.partials[partial]);
}
var tmpl = cache(options) || cache(options, engine.compile(str, options));
fn(null, tmpl(options));
} catch (err) {
Expand Down Expand Up @@ -482,7 +518,7 @@ exports.mustache = fromStringRenderer('mustache');
exports.mustache.render = function(str, options, fn) {
var engine = requires.mustache || (requires.mustache = require('mustache'));
try {
fn(null, engine.to_html(str, options));
fn(null, engine.to_html(str, options, options.partials));
} catch (err) {
fn(err);
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -24,7 +24,7 @@
"hogan.js": "2.0.0",
"dust": "0.3.0",
"dustjs-linkedin": "0.4.0",
"handlebars": "1.0.5beta",
"handlebars": "1.0.7",
"underscore": "1.3.3",
"qejs": "0.0.1",
"walrus": "0.9.0",
Expand Down
5 changes: 4 additions & 1 deletion test/consolidate.js
Expand Up @@ -10,14 +10,17 @@ require('./shared').test('eco');
require('./shared').test('whiskers');
require('./shared').test('haml-coffee');
require('./shared').test('hogan');
require('./shared/partials').test('hogan');
require('./shared').test('dust');
require('./shared/partials').test('dust');
require('./shared').test('handlebars');
require('./shared/partials').test('handlebars');
require('./shared').test('underscore');
require('./shared').test('qejs');
require('./shared').test('walrus');
require('./shared').test('mustache');
require('./shared/partials').test('mustache');
require('./shared').test('just');
require('./shared').test('ect');
require('./shared').test('mote');
require('./shared').test('toffee');
require('./shared').test('toffee');
1 change: 1 addition & 0 deletions test/fixtures/handlebars/partials.handlebars
@@ -0,0 +1 @@
{{>partial}}
1 change: 1 addition & 0 deletions test/fixtures/hogan/partials.hogan
@@ -0,0 +1 @@
{{>partial}}
1 change: 1 addition & 0 deletions test/fixtures/mustache/partials.mustache
@@ -0,0 +1 @@
{{>partial}}
35 changes: 24 additions & 11 deletions test/shared/partials.js
Expand Up @@ -13,17 +13,30 @@ exports.test = function(name) {
fs.readFileSync = readFileSync;
});

it('should support rendering a partial', function(done){
var str = fs.readFileSync('test/fixtures/' + name + '/user_partial.' + name).toString();
var locals = {
user: user,
views: "./test/fixtures/" + name
};
cons[name].render(str, locals, function(err, html){
if (err) return done(err);
html.should.equal('<p>Tobi from partial!</p><p>Tobi</p>');
done();
if (name == 'hogan' || name == 'mustache' || name == 'handlebars') {
it('should support partials', function(done){
var path = 'test/fixtures/' + name + '/partials.' + name;
var locals = { user: user, partials: { partial: 'user' } };
cons[name](path, locals, function(err, html){
if (err) return done(err);
html.should.equal('<p>Tobi</p>');
done();
});
});
});
}
else {
it('should support rendering a partial', function(done){
var str = fs.readFileSync('test/fixtures/' + name + '/user_partial.' + name).toString();
var locals = {
user: user,
views: "./test/fixtures/" + name
};
cons[name].render(str, locals, function(err, html){
if (err) return done(err);
html.should.equal('<p>Tobi from partial!</p><p>Tobi</p>');
done();
});
});
}
});
};

0 comments on commit 7d28ae1

Please sign in to comment.