Skip to content

Commit fe77394

Browse files
add registerFullPath to prevent clobbering, release 0.7.5
1 parent 9702bbc commit fe77394

File tree

7 files changed

+107
-6
lines changed

7 files changed

+107
-6
lines changed

Gruntfile.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ module.exports = function(grunt) {
9191
'test/globals/info.json',
9292
'test/globals/textspec.json'
9393
]
94+
},
95+
registerFullPath: {
96+
template: '<h1>{{salutation}}{{punctuation}} {{location}}</h1>{{> test/fixtures/deep/shared/pathTest}}',
97+
templateData: {
98+
"salutation": "Hallo",
99+
"punctuation": ",",
100+
"location": "Welt"
101+
},
102+
output: 'tmp/fullPath.html',
103+
partials: 'test/fixtures/deep/shared/**/*.handlebars',
104+
registerFullPath: true
94105
}
95106
},
96107

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,60 @@ Heres a few of the ways you can use it
9393
}
9494
```
9595

96+
The available configuration options are as follows
97+
98+
Unless otherwise noted, all configurable values can be represented as
99+
* a string representing the path to a specific file
100+
* a string representing the path to a [globbed representation](http://gruntjs.com/api/grunt.file#globbing-patterns) of the files, matched up against the values resolved from the `template` configuration
101+
* an array of literal paths, globbed paths, or a combination of the two
102+
103+
__`template`__ - The template fed to handlebars. In addition to the normal configurable values, it can also be an inline string representation of a template (e.g. raw html and handlebars).
104+
105+
__`preHTML`__ - Static text to be inserted before the compiled template
106+
__`postHTML`__ - Static text to be inserted after the compiled template
107+
108+
__`templateData` ~~ The data being fed to compiled template, in addition to the normal configurable values, this can be
109+
* an inline string representation of a data (I don't know why you would do that though, when you can do...)
110+
* an inline JSON representation of a data
111+
112+
__`output`__ - the file(s) that handlebars saves the files to. This can be
113+
__`globals`__ - globals that can be included, useful for when you have template specific data, but want some data available to all templates
114+
__`helpers`__ - handlebars helpers
115+
__`partials`__ - handlebars partials
116+
117+
__`registerFullPath`__ - normally, helpers and partials are registered under their basename, rather than their path (e.g. partial at `partials/deep/awesomePartial.handlebars` is registered as `{{> awesomePartial}}`). When set to `true`, helpers and partials are registered under their full paths (e.g. {{> partials/deep/awesomePartial}}), to prevent clobbering after resolving globbed values.
118+
119+
120+
#### A note on globing
121+
122+
When you specify templates using globs, the values from `template` are used to create the values for output, for example, if your file structure looks like this
123+
124+
```
125+
|-foo
126+
|-bar.handlebars
127+
|-baz.handlebars
128+
|-bar.json
129+
|-baz.json
130+
```
131+
132+
and your configuration looks like this
133+
134+
```JSON
135+
{
136+
"template": "./foo/*.handlebars",
137+
"templateData": "./foo/*.json",
138+
"output": "./foo/*.html"
139+
}
140+
```
141+
142+
the output would be `./foo/bar.html` and `./foo/baz.html`
143+
144+
96145
### Why
97146
I had to work with several hundred repeated data structures that never changed. Keeping them all in html was silly, but pushing out a template engine for the end user to compile the same information multiple times was even sillier. This allows you to have your templated cake and eat it too.
98147

99148
## Release History
149+
* 0.7.5 - Redford - add `registerFullPath` option to prevent partial/helper registration clobbering, update README
100150
* 0.7.4 - M. Jean - don't send objects to handlebars.compile, code cleanup
101151
* 0.7.3 - Cousin Ben - switch from require to readFile to allow for html in partials
102152
* 0.7.2 - Bernice - @stimmins improved handling of templateData and globals

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "grunt-compile-handlebars",
33
"description": "Compile handlebar templates, outputting static HTML",
4-
"version": "0.7.4",
4+
"version": "0.7.5",
55
"homepage": "https://github.com/patrickkettner/grunt-compile-handlebars",
66
"author": {
77
"name": "Patrick Kettner",

tasks/compile-handlebars.js

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,24 +130,52 @@ module.exports = function(grunt) {
130130
return json;
131131
};
132132

133+
var shouldRegisterFullPaths = function(itShould, type) {
134+
135+
if (itShould && typeof itShould === 'string') {
136+
itShould = itShould.toLowerCase().indexOf(type) === 0;
137+
}
138+
139+
return itShould;
140+
};
141+
133142
grunt.registerMultiTask('compile-handlebars', 'Compile Handlebars templates ', function() {
134143
var fs = require('fs');
135144
var config = this.data;
136-
handlebars = config.handlebars || handlebars;
137145
var templates = getConfig(config.template);
138146
var templateData = config.templateData;
139147
var helpers = getConfig(config.helpers);
140148
var partials = getConfig(config.partials);
141149
var done = this.async();
142150

151+
handlebars = config.handlebars || handlebars;
152+
143153
helpers.forEach(function (helper) {
144-
var basename = getBasename(helper, config.helpers);
145-
handlebars.registerHelper(basename, require(fs.realpathSync(helper)));
154+
var name = shouldRegisterFullPaths(config.registerFullPath, 'helpers') ?
155+
// full path, minus extention
156+
helper.replace(/\.[^/.]+$/, "") :
157+
// just the file's name
158+
getBasename(helper, config.helpers);
159+
160+
if (handlebars.helpers[name]) {
161+
grunt.log.error(name + ' is already registered, clobbering with the new value. Consider setting `registerFullPath` to true');
162+
}
163+
164+
handlebars.registerHelper(name, require(fs.realpathSync(helper)));
146165
});
147166

148167
partials.forEach(function (partial) {
149-
var basename = getBasename(partial, config.partials);
150-
handlebars.registerPartial(basename, fs.readFileSync(fs.realpathSync(partial), "utf8"));
168+
var name = shouldRegisterFullPaths(config.registerFullPath, 'partials') ?
169+
// full path, minus extention
170+
partial.replace(/\.[^/.]+$/, "") :
171+
// just the file's name
172+
getBasename(partial, config.partials);
173+
174+
if (handlebars.partials[name]) {
175+
grunt.log.error(name + ' is already registered, clobbering with the new value. Consider setting `registerFullPath` to true');
176+
}
177+
178+
handlebars.registerPartial(name, fs.readFileSync(fs.realpathSync(partial), "utf8"));
151179
});
152180

153181
templates.forEach(function(template, index) {

test/compile_handlebars_test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ exports.clean = {
107107

108108
test.equal(actual, expected, 'Use specific templateName.json per templateName.handlebars (as in globbedTemplateAndOutput) plus multiple global json on top');
109109

110+
test.done();
111+
},
112+
registerFullPath: function (test) {
113+
test.expect(1);
114+
115+
var actual = grunt.file.read('tmp/fullPath.html');
116+
var expected = grunt.file.read('test/expected/fullPath.html');
117+
118+
test.equal(actual, expected, 'Partials and helpers referenced at their full paths should work when registerFullParth is true');
119+
110120
test.done();
111121
}
112122
};

test/expected/fullPath.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1>Hallo, Welt</h1><div> full paths!!!</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div> full paths!!!</div>

0 commit comments

Comments
 (0)