Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

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

Merged
merged 1 commit into from

4 participants

@ForbesLindesay

Replaces #788 with my review and changes and rebase. This adds a basedir option at compile time that parallels the filename option to allow paths starting with / to be treated as relative to the basedir rather than the current file.

Will merge if no complaints by 2013-04-23T16:00:00Z

@Prestaul

Beautiful. This will help clean some our our templates up quite a bit. :+1:

@ForbesLindesay ForbesLindesay merged commit 2c8774b into master
@ForbesLindesay ForbesLindesay deleted the feature/basedir branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 23, 2013
  1. @chorvus @ForbesLindesay
This page is out of date. Refresh to see the latest.
View
58 lib/parser.js
@@ -379,23 +379,44 @@ Parser.prototype = {
},
/**
+ * 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);
@@ -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);
View
4 test/cases/auxiliary/extends-from-root.jade
@@ -0,0 +1,4 @@
+extends /auxiliary/layout
+
+block content
+ include /auxiliary/include-from-root
View
1  test/cases/auxiliary/include-from-root.jade
@@ -0,0 +1 @@
+h1 hello
View
8 test/cases/include-extends-from-root.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>My Application</title>
+ </head>
+ <body>
+ <h1>hello</h1>
+ </body>
+</html>
View
1  test/cases/include-extends-from-root.jade
@@ -0,0 +1 @@
+include /auxiliary/extends-from-root
View
2  test/run.js
@@ -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);
})
Something went wrong with that request. Please try again.