Skip to content

Commit

Permalink
Merge pull request #32 from jGleitz/partials-glob
Browse files Browse the repository at this point in the history
glob expansion for partials search
  • Loading branch information
5thWall committed Aug 22, 2015
2 parents ae7f60f + 4f099c5 commit 6b706c3
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 32 deletions.
24 changes: 24 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,30 @@ module.exports = function(grunt) {
dest: 'tmp/hello_partial_function.html'}
]
},
partials_glob_df: { // glob expansion partial search (like partials_dfprefixes)
options: {
directory: 'test/fixtures/partials/',
glob: 'sub-$1/pre_$2.mustache',
clear_cache: true
},
files: [
{data: 'test/fixtures/objects/hello_world.json',
template: 'test/fixtures/templates/hello_partial_dir.mustache',
dest: 'tmp/hello_partial_globdf.html'}
]
},
partials_glob: {
options: {
directory: 'test/fixtures/partials/',
glob: '{sub-$1,.}/$2.!(ms)',
clear_cache: true
},
files: [
{data: 'test/fixtures/objects/hello_world.json',
template: 'test/fixtures/templates/hello_partial_glob.mustache',
dest: 'tmp/hello_partial_glob.html'}
]
},
batch_single_template_multiple_json_via_map: {
options: {
template: 'test/fixtures/templates/hello_world.html.mustache'
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,25 @@ which prepended onto the partial reference, regardless of whether it included
a directory or not. This option is still supported for backward compatibility
and maintains the same behavior.

#### options.glob
Type: `String`
Default value: `""`

A glob pattern to use to search for partials. If this option is set, `options.prefix_file`, `options.prefix_dir`,
`options.prefix` and `options.extension` will be ignored. The glob pattern will be expanded using
[`grunt.file.expand`](http://gruntjs.com/api/grunt.file#grunt.file.expand) and the first file found will be used.
If more than one file is found, a warning will be printed.

You can use this variables in the pattern:
* `$0` The whole partial name
* `$1` The partial name's directory part
* `$2` The partial name's basename part

Examples:
* `prefix_dir$1/prefix_file$2` does the same as using `options.prefix_file` and `options.prefix_dir`
* `$0.*` allows any extension
* `{images/$0.svg,partials/$0.mustache}` seaches for a partial either as `name.svg` in the `image` folder or as `name.mustache` in the `partials` folder.

#### options.clear_cache
Type: `Boolean`
Default value: `false`
Expand Down
97 changes: 65 additions & 32 deletions tasks/mustache_render.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module.exports = function gruntTask(grunt) {
prefix : "", // discouraged; use prefix_dir and/or prefix_file
prefix_dir : "",
prefix_file : "",
glob: "",
clear_cache : false,
escape: true
};
Expand Down Expand Up @@ -235,46 +236,78 @@ module.exports = function gruntTask(grunt) {
var prefixDir = this.options.prefix_dir;
var prefixFile = this.options.prefix_file;
var prefixOld = this.options.prefix;

if ((prefixDir || prefixFile) && prefixOld) {
throw new Error("old-style prefix option cannot be combined with the " +
"newer prefix_dir or prefix_file options");
}
var glob = this.options.glob;
var baseDir = this.options.directory;
var partialFile;

var dirname = path.dirname(name);
var hasDir = dirname && dirname !== '.';
var basename = path.basename(name);

if (prefixOld) {
if (hasDir) {
prefixDir = prefixOld;
grunt.log.error("Warning: partial reference " + name.yellow + " w/ " +
"prefix " + prefixOld.cyan + " will prepend prefix " +
"to the directory name, not the filename");
}
else { prefixFile = prefixOld; }
}

if (hasDir) {
if (prefixDir && ['.', '/'].indexOf(dirname[0]) !== -1) {
throw new Error("cannot use prefix when using a partial reference " +
"that points outside of the base directory");
}
} else if (prefixDir) {
grunt.log.error("Warning: prefix_dir " + prefixDir.cyan + " has no " +
"effect for partial reference " + name.yellow);
}
if (glob) {
if (prefixDir || prefixFile || prefixOld) {
grunt.log.error("Warning: All prefix options are ignored when " +
"using the glob option!");
}
glob = glob.replace(/\$0/g, name);
glob = glob.replace(/\$1/g, dirname);
glob = glob.replace(/\$2/g, basename);

var partials = grunt.file.expand({cwd: baseDir}, glob);
if (partials.length === 0) {
grunt.log.error("Warning: partial reference " + name.yellow +
" yields the glob pattern " + glob.cyan +
", which does not match anything in directory " +
baseDir.cyan);
} else {
if (partials.length > 1) {
grunt.log.error("Warning: glob pattern " + glob.cyan +
" for partial reference " + name.yellow +
" yields more than one file. Using the first." +
"Files found: \n" + partials.toString().yellow);
}
partialFile = path.join(baseDir, partials[0]);
}
} else {
if ((prefixDir || prefixFile) && prefixOld) {
throw new Error("old-style prefix option cannot be combined with " +
"the newer prefix_dir or prefix_file options");
}

var basename = path.basename(name);
var filePath = path.join(this.options.directory,
hasDir ? prefixDir + dirname : '.',
prefixFile + basename + this.options.extension);
if (prefixOld) {
if (hasDir) {
prefixDir = prefixOld;
grunt.log.error("Warning: partial reference " + name.yellow +
" w/ prefix " + prefixOld.cyan + " will prepend " +
"prefix to the directory name, not the filename");
}
else { prefixFile = prefixOld; }
}

if (grunt.file.exists(filePath)) {
return grunt.file.read(filePath);
if (hasDir) {
if (prefixDir && ['.', '/'].indexOf(dirname[0]) !== -1) {
throw new Error("cannot use prefix when using a partial " +
"reference that points outside of the base "+
"directory");
}
} else if (prefixDir) {
grunt.log.error("Warning: prefix_dir " + prefixDir.cyan + " has no " +
"effect for partial reference " + name.yellow);
}
var fileName = path.join(baseDir, hasDir ? prefixDir + dirname : '.',
prefixFile + basename + this.options.extension);
if (!grunt.file.exists(fileName)) {
grunt.log.error("Warning: partial reference " + name.yellow +
" yields " + fileName.cyan +
", which does not exist");
} else {
partialFile = fileName;
}
}

grunt.log.error("Warning: partial reference " + name.yellow + " yields " +
filePath.cyan + ", which does not exist");
if (partialFile) {
return grunt.file.read(partialFile);
}
return "";
};

Expand Down
12 changes: 12 additions & 0 deletions test/expected/hello_glob.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html>
<head>
<meta charset="UTF-8">
<title>A partial</title>
</head>
<body>
<h1>Hello mustache with glob patterns!</h1>
Hello glob pattern!
You can use any file extension :)

</body>
</html>
1 change: 1 addition & 0 deletions test/fixtures/partials/sub-b/another.fancy
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use any file extension :)
1 change: 1 addition & 0 deletions test/fixtures/partials/sub-b/hello.ext
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello glob pattern!
7 changes: 7 additions & 0 deletions test/fixtures/templates/hello_partial_glob.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{> head}}
<body>
<h1>Hello mustache with glob patterns!</h1>
{{> b/hello}}
You can {{> b/another}}
</body>
</html>
22 changes: 22 additions & 0 deletions test/mustache_render_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,28 @@ exports.mustache_render = {
test.done();
},

partials_glob_df: function(test) { // glob expansion partial search (like dfprefixes)
test.expect(1);

var actual = grunt.file.read('tmp/hello_partial_globdf.html');
var expected = grunt.file.read('test/expected/hello_dfprefixes.html');
test.equal(actual, expected, 'should find partials w/ glob ' +
'"sub-$1/pre_$2.mustache".');

test.done();
},

partials_glob: function(test) { // glob expansion partial search
test.expect(1);

var actual = grunt.file.read('tmp/hello_partial_glob.html');
var expected = grunt.file.read('test/expected/hello_glob.html');
test.equal(actual, expected, 'should find partials w/ glob ' +
'"?(+sub-$1)/$2.*".');

test.done();
},

batch_single_template_multiple_json_via_map: function(test) {
test.expect(3);

Expand Down

0 comments on commit 6b706c3

Please sign in to comment.