Skip to content

Commit

Permalink
Implement multiple view directories for include
Browse files Browse the repository at this point in the history
  • Loading branch information
mde committed Jul 16, 2017
1 parent 8557289 commit 6a24714
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 8 deletions.
34 changes: 28 additions & 6 deletions lib/ejs.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,32 @@ exports.resolveInclude = function(name, filename, isDir) {
* @param {Options} options compilation options
* @return {String}
*/
function getIncludePath(path, options){
function getIncludePath(path, options) {
var includePath;
var filePath;
var views = options.views;

// Abs path
if (path.charAt(0) == '/') {
includePath = exports.resolveInclude(path.replace(/^\/*/,''), options.root || '/', true);
}
// Relative paths
else {
if (!options.filename) {
throw new Error('`include` use relative path requires the \'filename\' option.');
// Look relative to a passed filename's directory first
if (options.filename) {
includePath = exports.resolveInclude(path, options.filename);
}
// Then look in any views directories
else if (Array.isArray(views) && views.some(function (v) {
filePath = exports.resolveInclude(path, v, true);
return fs.existsSync(filePath);
})) {
includePath = filePath;
}
else {
throw new Error('`include` using relative path requires either ' +
'a valid \'filename\' or \'views\' option.');
}
includePath = exports.resolveInclude(path, options.filename);
}
return includePath;
}
Expand Down Expand Up @@ -390,8 +406,13 @@ exports.renderFile = function () {
// in the data, copy them to options
if (arguments.length === 3) {
// Express 4
if (data.settings && data.settings['view options']) {
utils.shallowCopyFromList(opts, data.settings['view options'], _OPTS_EXPRESS);
if (data.settings) {
if (data.settings['view options']) {
utils.shallowCopyFromList(opts, data.settings['view options'], _OPTS_EXPRESS);
}
if (data.settings.views) {
opts.views = data.settings.views;
}
}
// Express 3 and lower
else {
Expand Down Expand Up @@ -442,6 +463,7 @@ function Template(text, opts) {
options.rmWhitespace = opts.rmWhitespace;
options.root = opts.root;
options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
options.views = opts.views;

if (options.strict) {
options._with = false;
Expand Down
59 changes: 57 additions & 2 deletions test/ejs.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,61 @@ suite('ejs.render(str, data, opts)', function () {
var out = ejs.render('<%= this.foo %>', {}, {context: ctxt});
assert.equal(out, ctxt.foo);
});

test('support express multiple views folders, falls back to second if first is not available', function (done) {
var data = {
viewsText: 'test',
settings: {
views: [
path.join(__dirname, 'fixtures/nonexistent-folder'),
path.join(__dirname, 'fixtures')
]
}
};
ejs.renderFile(path.join(__dirname, 'fixtures/views.ejs'), data, {}, function(error, data){
assert.ifError(error);
assert.equal('<div><p>global test</p>\n</div>\n', data);
done();
});

});

test('support express multiple views folders, also in old format', function (done) {
var data = {
viewsText: 'test',
settings: {
views: [
path.join(__dirname, 'fixtures/views'),
path.join(__dirname, 'fixtures')
]
}
};
ejs.renderFile(path.join(__dirname, 'fixtures/views-old.ejs'), data, {}, function(error, data){
assert.ifError(error);
assert.equal('<div><p>custom test</p>\n</div>\n', data);
done();
});

});

test('support express multiple views folders, uses fallback also in old format', function (done) {
var data = {
viewsText: 'test',
settings: {
views: [
path.join(__dirname, 'fixtures/nonexistent-folder'),
path.join(__dirname, 'fixtures')
]
}
};
ejs.renderFile(path.join(__dirname, 'fixtures/views-old.ejs'), data, {}, function(error, data){
assert.ifError(error);
assert.equal('<div><p>global test</p>\n</div>\n', data);
done();
});

});

});

suite('ejs.renderFile(path, [data], [options], fn)', function () {
Expand Down Expand Up @@ -762,7 +817,7 @@ suite('include()', function () {
ejs.render(fixture('include-simple.ejs'));
}
catch (err) {
assert.ok(err.message.indexOf('requires the \'filename\' option') > -1);
assert.ok(err.message.indexOf('a valid \'filename\'') > -1);
return;
}
throw new Error('expected inclusion error');
Expand Down Expand Up @@ -890,7 +945,7 @@ suite('preprocessor include', function () {
ejs.render(fixture('include_preprocessor.ejs'), {pets: users}, {delimiter: '@'});
}
catch (err) {
assert.ok(err.message.indexOf('requires the \'filename\' option') > -1);
assert.ok(err.message.indexOf('a valid \'filename\'') > -1);
return;
}
throw new Error('expected inclusion error');
Expand Down

0 comments on commit 6a24714

Please sign in to comment.