Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

dust: support relative partial paths #67

Open
wants to merge 3 commits into from

4 participants

@jmoyers
  • Shared relative path partial test added
  • Absolute path > relative path > options.view > default to './views'
  • Should very rarely cost an extra failed readFile
  • Its likely to work on the first pass, its usually a flat views/ folder
jmoyers added some commits
@jmoyers jmoyers dust: default relative path, fall back on views/ 7d64558
@jmoyers jmoyers Shared test for relative path partials
* Look for options.filename so we don't waste a call to fs
* Behavior is absolute path > relative path > default views
88d1604
@jmoyers jmoyers Actually support absolute path 88537af
@jmoyers

Ref #66

@tj tj commented on the diff
lib/consolidate.js
((19 lines not shown))
+ }
+
+ var path = partial,
+ absolutePath = '/' === path[0];
+
+ // If we have a parent filename, try relative path
+ if (options.filename && !absolutePath) {
+ path = dirname(options.filename) + '/' + path;
+ } else if (!absolutePath) {
+ path = views + '/' + partial;
+ }
+
+ read(path, options, function (err, str) {
+ if (err) {
+ // Fall back on views/partial
+ return read(views + '/' + partial, options, callback);
@tj Owner
tj added a note

IMO we shouldn't have this part, if it's relative and filename is present then we use that, absolute, or otherwise your conditional above will default it to this anyway

@jmoyers
jmoyers added a note

Yeah, thats fine. The case it doesn't handle (options.filename exists and is in a subdirectory, but the template referenced in the partial is in the defaults views directory) probably won't happen often or is more properly handled through a ../ relative path. I can see this happening for a header and footer referenced in many templates.

@tj Owner
tj added a note

but if it's not absolute, and no filename is given you're already defaulting to views/partial, unless im missing something

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@durango

What's going on with this PR?

@erikmueller

Is this PR still alive? I'm a great fan of relative paths for partials ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 7, 2012
  1. @jmoyers
  2. @jmoyers

    Shared test for relative path partials

    jmoyers authored
    * Look for options.filename so we don't waste a call to fs
    * Behavior is absolute path > relative path > default views
  3. @jmoyers
This page is out of date. Refresh to see the latest.
View
32 lib/consolidate.js
@@ -18,7 +18,9 @@
*/
var fs = require('fs'),
- extname = require('path').extname;
+ path = require('path'),
+ extname = path.extname,
+ dirname = path.dirname;
var readCache = {};
@@ -136,17 +138,35 @@ exports.dust.render = function(str, options, fn){
}
var ext = 'dust'
- , views = '.';
+ , views = './views';
if (options) {
if (options.ext) ext = options.ext;
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;
- read(path, options, callback);
+ engine.onLoad = function(partial, callback){
+ if ('' == extname(partial)) {
+ partial += '.' + ext;
+ }
+
+ var path = partial,
+ absolutePath = '/' === path[0];
+
+ // If we have a parent filename, try relative path
+ if (options.filename && !absolutePath) {
+ path = dirname(options.filename) + '/' + path;
+ } else if (!absolutePath) {
+ path = views + '/' + partial;
+ }
+
+ read(path, options, function (err, str) {
+ if (err) {
+ // Fall back on views/partial
+ return read(views + '/' + partial, options, callback);
@tj Owner
tj added a note

IMO we shouldn't have this part, if it's relative and filename is present then we use that, absolute, or otherwise your conditional above will default it to this anyway

@jmoyers
jmoyers added a note

Yeah, thats fine. The case it doesn't handle (options.filename exists and is in a subdirectory, but the template referenced in the partial is in the defaults views directory) probably won't happen often or is more properly handled through a ../ relative path. I can see this happening for a header and footer referenced in many templates.

@tj Owner
tj added a note

but if it's not absolute, and no filename is given you're already defaulting to views/partial, unless im missing something

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+ callback(null, str);
+ });
};
try {
View
1  test/fixtures/dust/relative/child_partial.dust
@@ -0,0 +1 @@
+<p>{user.name} from partial child view, relative path!</p>
View
2  test/fixtures/dust/relative/parent_view.dust
@@ -0,0 +1,2 @@
+{>child_partial/}
+<p>{user.name} is in the parent view.</p>
View
31 test/shared/partials.js
@@ -2,10 +2,12 @@
var cons = require('../../')
, fs = require('fs')
, readFile = fs.readFile
- , readFileSync = fs.readFileSync;
+ , readFileSync = fs.readFileSync
+ , resolve = require('path').resolve;
exports.test = function(name) {
- var user = { name: 'Tobi' };
+ var user = { name: 'Tobi' }
+ , fixturePath = 'test/fixtures/' + name + '/';
describe(name, function(){
afterEach(function(){
@@ -14,16 +16,39 @@ exports.test = function(name) {
});
it('should support rendering a partial', function(done){
- var str = fs.readFileSync('test/fixtures/' + name + '/user_partial.' + name).toString();
+ var str = fs.readFileSync(fixturePath + '/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();
});
});
+
+ it('should support a partial relative to parent view', function(done){
+ var str = fs.readFileSync(fixturePath + '/relative/parent_view.' + name)
+ .toString();
+
+ var locals = {
+ user: user,
+ views: "./test/fixtures/" + name,
+ filename: resolve(fixturePath + '/relative/parent_view.' + name)
+ };
+
+ cons[name].render(str, locals, function(err, html){
+ if (err) return done(err);
+ html.should.equal([
+ '<p>Tobi from partial child view, relative path!</p>',
+ '<p>Tobi is in the parent view.</p>'
+ ].join(''));
+ done();
+ });
+ });
});
};
Something went wrong with that request. Please try again.