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

Functionality and tests for relative path partial names through the cli #563

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
40 changes: 36 additions & 4 deletions bin/mustache
Expand Up @@ -78,7 +78,13 @@ function readPartials (cb) {
var partialPath = partialsPaths.pop();
var partial = fs.createReadStream(partialPath);
streamToStr(partial, function onDone (str) {
partials[getPartialName(partialPath)] = str;

var keysArray = getPartialNames(partialPath);

keysArray.forEach(function addPartialNames (key) {
partials[key] = str;
});

readPartials(cb);
});
}
Expand Down Expand Up @@ -131,6 +137,32 @@ function hasVersionArg () {
});
}

function getPartialName (filename) {
return path.basename(filename, '.mustache');
}
function getPartialNames (filename) {
// get path relative to the template file
// in order to use e.g. {{> ../common/footer }}

// before, {{> footer }} used the -p file whose streamToStr happened to
// finish first, as seen above in readPartials

// this can be extended to the mustache API by using the relative path as
// the key in the partials object
// e.g. mustache.render(template, view, { '../common/footer': '...' })
var relativePath = path
.relative(templateArg, filename)
// without this, you would have to use {{> ..\\common\\footer }} for windows
// and {{> ../common/footer }} for *nix
.replace(/\\{1,2}/g, '/')
// since path.relative shows paths relative to the file, and not the
// directory (i.e. what everyone is used to), change the reference to the
// current directory from '../' to './'
.replace(/^\.\.\//, './')
// obviously if we want parents of the current directory, we want '../../'
// as opposed to './../../', so this replace fixes that
.replace(/^\.\/\.\.\//, '../')
.replace('.mustache', '');

return [
path.basename(filename, '.mustache'),
relativePath
];
}
1 change: 1 addition & 0 deletions test/_files/alt/partial_with_relative_path.mustache
@@ -0,0 +1 @@
ALT
1 change: 1 addition & 0 deletions test/_files/cli_with_relative_partials.json
@@ -0,0 +1 @@
{}
3 changes: 3 additions & 0 deletions test/_files/cli_with_relative_partials.mustache
@@ -0,0 +1,3 @@
{{> ./partial_with_relative_path }}

{{> ./alt/partial_with_relative_path }}
2 changes: 2 additions & 0 deletions test/_files/cli_with_relative_partials.txt
@@ -0,0 +1,2 @@
MAIN
ALT
1 change: 1 addition & 0 deletions test/_files/partial_with_relative_path.mustache
@@ -0,0 +1 @@
MAIN
25 changes: 23 additions & 2 deletions test/cli-test.js
Expand Up @@ -6,6 +6,7 @@ var child_process = require('child_process');
var _files = path.join(__dirname, '_files');
var cliTxt = path.resolve(_files, 'cli.txt');
var cliPartialsTxt = path.resolve(_files, 'cli_with_partials.txt');
var cliRelativePartialsTxt = path.resolve(_files, 'cli_with_relative_partials.txt');
var moduleVersion = require('../package').version;

function changeForOS(command) {
Expand Down Expand Up @@ -140,5 +141,25 @@ describe('Mustache CLI', function () {
done();
});
});
})
});
});

describe('with relative partials', function () {
before(function(done) {
fs.readFile(cliRelativePartialsTxt, function onFsEnd(err, data) {
if (err) return done(err);

expectedOutput = data.toString();
done();
});
});

it('selects the file described with the relative path', function (done) {
exec(changeForOS('bin/mustache -p test/_files/alt/partial_with_relative_path.mustache -p test/_files/partial_with_relative_path.mustache test/_files/cli_with_relative_partials.json test/_files/cli_with_relative_partials.mustache'), function (err, stdout, stderr) {
assert.equal(err, null);
assert.equal(stderr, '');
assert.equal(stdout, expectedOutput);
done();
});
});
});
});