diff --git a/Gruntfile.js b/Gruntfile.js index 7fe8548..1ebfb4f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -91,6 +91,17 @@ module.exports = function(grunt) { 'test/globals/info.json', 'test/globals/textspec.json' ] + }, + registerFullPath: { + template: '

{{salutation}}{{punctuation}} {{location}}

{{> test/fixtures/deep/shared/pathTest}}', + templateData: { + "salutation": "Hallo", + "punctuation": ",", + "location": "Welt" + }, + output: 'tmp/fullPath.html', + partials: 'test/fixtures/deep/shared/**/*.handlebars', + registerFullPath: true } }, diff --git a/README.md b/README.md index 0cccfe5..47809ce 100644 --- a/README.md +++ b/README.md @@ -93,10 +93,60 @@ Heres a few of the ways you can use it } ``` +The available configuration options are as follows + +Unless otherwise noted, all configurable values can be represented as +* a string representing the path to a specific file +* 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 +* an array of literal paths, globbed paths, or a combination of the two + +__`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). + +__`preHTML`__ - Static text to be inserted before the compiled template +__`postHTML`__ - Static text to be inserted after the compiled template + +__`templateData` ~~ The data being fed to compiled template, in addition to the normal configurable values, this can be +* an inline string representation of a data (I don't know why you would do that though, when you can do...) +* an inline JSON representation of a data + +__`output`__ - the file(s) that handlebars saves the files to. This can be +__`globals`__ - globals that can be included, useful for when you have template specific data, but want some data available to all templates +__`helpers`__ - handlebars helpers +__`partials`__ - handlebars partials + +__`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. + + +#### A note on globing + +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 + +``` +|-foo + |-bar.handlebars + |-baz.handlebars + |-bar.json + |-baz.json +``` + +and your configuration looks like this + +```JSON +{ + "template": "./foo/*.handlebars", + "templateData": "./foo/*.json", + "output": "./foo/*.html" +} +``` + +the output would be `./foo/bar.html` and `./foo/baz.html` + + ### Why 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. ## Release History + * 0.7.5 - Redford - add `registerFullPath` option to prevent partial/helper registration clobbering, update README * 0.7.4 - M. Jean - don't send objects to handlebars.compile, code cleanup * 0.7.3 - Cousin Ben - switch from require to readFile to allow for html in partials * 0.7.2 - Bernice - @stimmins improved handling of templateData and globals diff --git a/package.json b/package.json index 88092f9..6117fe1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "grunt-compile-handlebars", "description": "Compile handlebar templates, outputting static HTML", - "version": "0.7.4", + "version": "0.7.5", "homepage": "https://github.com/patrickkettner/grunt-compile-handlebars", "author": { "name": "Patrick Kettner", diff --git a/tasks/compile-handlebars.js b/tasks/compile-handlebars.js index c5be88d..e79ff5f 100644 --- a/tasks/compile-handlebars.js +++ b/tasks/compile-handlebars.js @@ -130,24 +130,52 @@ module.exports = function(grunt) { return json; }; + var shouldRegisterFullPaths = function(itShould, type) { + + if (itShould && typeof itShould === 'string') { + itShould = itShould.toLowerCase().indexOf(type) === 0; + } + + return itShould; + }; + grunt.registerMultiTask('compile-handlebars', 'Compile Handlebars templates ', function() { var fs = require('fs'); var config = this.data; - handlebars = config.handlebars || handlebars; var templates = getConfig(config.template); var templateData = config.templateData; var helpers = getConfig(config.helpers); var partials = getConfig(config.partials); var done = this.async(); + handlebars = config.handlebars || handlebars; + helpers.forEach(function (helper) { - var basename = getBasename(helper, config.helpers); - handlebars.registerHelper(basename, require(fs.realpathSync(helper))); + var name = shouldRegisterFullPaths(config.registerFullPath, 'helpers') ? + // full path, minus extention + helper.replace(/\.[^/.]+$/, "") : + // just the file's name + getBasename(helper, config.helpers); + + if (handlebars.helpers[name]) { + grunt.log.error(name + ' is already registered, clobbering with the new value. Consider setting `registerFullPath` to true'); + } + + handlebars.registerHelper(name, require(fs.realpathSync(helper))); }); partials.forEach(function (partial) { - var basename = getBasename(partial, config.partials); - handlebars.registerPartial(basename, fs.readFileSync(fs.realpathSync(partial), "utf8")); + var name = shouldRegisterFullPaths(config.registerFullPath, 'partials') ? + // full path, minus extention + partial.replace(/\.[^/.]+$/, "") : + // just the file's name + getBasename(partial, config.partials); + + if (handlebars.partials[name]) { + grunt.log.error(name + ' is already registered, clobbering with the new value. Consider setting `registerFullPath` to true'); + } + + handlebars.registerPartial(name, fs.readFileSync(fs.realpathSync(partial), "utf8")); }); templates.forEach(function(template, index) { diff --git a/test/compile_handlebars_test.js b/test/compile_handlebars_test.js index 4171fae..6755d5a 100644 --- a/test/compile_handlebars_test.js +++ b/test/compile_handlebars_test.js @@ -107,6 +107,16 @@ exports.clean = { test.equal(actual, expected, 'Use specific templateName.json per templateName.handlebars (as in globbedTemplateAndOutput) plus multiple global json on top'); + test.done(); + }, + registerFullPath: function (test) { + test.expect(1); + + var actual = grunt.file.read('tmp/fullPath.html'); + var expected = grunt.file.read('test/expected/fullPath.html'); + + test.equal(actual, expected, 'Partials and helpers referenced at their full paths should work when registerFullParth is true'); + test.done(); } }; diff --git a/test/expected/fullPath.html b/test/expected/fullPath.html new file mode 100644 index 0000000..e0c6d51 --- /dev/null +++ b/test/expected/fullPath.html @@ -0,0 +1 @@ +

Hallo, Welt

full paths!!!
diff --git a/test/fixtures/deep/shared/pathTest.handlebars b/test/fixtures/deep/shared/pathTest.handlebars new file mode 100644 index 0000000..cd610e3 --- /dev/null +++ b/test/fixtures/deep/shared/pathTest.handlebars @@ -0,0 +1 @@ +
full paths!!!