Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabled 'include' and 'extends' to use paths relative to basedir #989

Merged
merged 1 commit into from Apr 23, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
58 changes: 32 additions & 26 deletions lib/parser.js
Expand Up @@ -378,24 +378,45 @@ Parser.prototype = {
return node;
},

/**
* Resolves a path relative to the template for use in
* includes and extends
*
* @param {String} path
* @param {String} purpose Used in error messages.
* @return {String}
* @api private
*/

resolvePath: function (path, purpose) {
var p = require('path');
var dirname = p.dirname;
var basename = p.basename;
var join = p.join;

if (path[0] !== '/' && !this.filename)
throw new Error('the "filename" option is required to use "' + purpose + '" with "relative" paths');

if (path[0] === '/' && !this.options.basedir)
throw new Error('the "basedir" option is required to use "' + purpose + '" with "absolute" paths');

path = join(path[0] === '/' ? this.options.basedir : dirname(this.filename), path);

if (basename(path).indexOf('.') === -1) path += '.jade';

return path;
},

/**
* 'extends' name
*/

parseExtends: function(){
var path = require('path');
var fs = require('fs');
var dirname = path.dirname;
var basename = path.basename;
var join = path.join;

if (!this.filename)
throw new Error('the "filename" option is required to extend templates');
var path = this.resolvePath(this.expect('extends').val.trim(), 'extends');
if ('.jade' != path.substr(-5)) path += '.jade';

var path = this.expect('extends').val.trim();
var dir = dirname(this.filename);

var path = join(dir, path + '.jade');
var str = fs.readFileSync(path, 'utf8');
var parser = new Parser(str, path, this.options);

Expand Down Expand Up @@ -444,33 +465,18 @@ Parser.prototype = {
*/

parseInclude: function(){
var path = require('path');
var fs = require('fs');
var dirname = path.dirname;
var basename = path.basename;
var join = path.join;

var path = this.expect('include').val.trim();
var dir = dirname(this.filename);

if (!this.filename)
throw new Error('the "filename" option is required to use includes');

// no extension
if (!~basename(path).indexOf('.')) {
path += '.jade';
}
var path = this.resolvePath(this.expect('include').val.trim(), 'include');

// non-jade
if ('.jade' != path.substr(-5)) {
var path = join(dir, path);
var str = fs.readFileSync(path, 'utf8').replace(/\r/g, '');
var ext = extname(path).slice(1);
if (filters.exists(ext)) str = filters(ext, str, { filename: path });
return new nodes.Literal(str);
}

var path = join(dir, path);
var str = fs.readFileSync(path, 'utf8');
var parser = new Parser(str, path, this.options);
parser.blocks = utils.merge({}, this.blocks);
Expand Down
4 changes: 4 additions & 0 deletions test/cases/auxiliary/extends-from-root.jade
@@ -0,0 +1,4 @@
extends /auxiliary/layout

block content
include /auxiliary/include-from-root
1 change: 1 addition & 0 deletions test/cases/auxiliary/include-from-root.jade
@@ -0,0 +1 @@
h1 hello
8 changes: 8 additions & 0 deletions test/cases/include-extends-from-root.html
@@ -0,0 +1,8 @@
<html>
<head>
<title>My Application</title>
</head>
<body>
<h1>hello</h1>
</body>
</html>
1 change: 1 addition & 0 deletions test/cases/include-extends-from-root.jade
@@ -0,0 +1 @@
include /auxiliary/extends-from-root
2 changes: 1 addition & 1 deletion test/run.js
Expand Up @@ -20,7 +20,7 @@ cases.forEach(function(test){
var path = 'test/cases/' + test + '.jade';
var str = fs.readFileSync(path, 'utf8');
var html = fs.readFileSync('test/cases/' + test + '.html', 'utf8').trim().replace(/\r/g, '');
var fn = jade.compile(str, { filename: path, pretty: true });
var fn = jade.compile(str, { filename: path, pretty: true, basedir: 'test/cases' });
var actual = fn({ title: 'Jade' });
actual.trim().should.equal(html);
})
Expand Down