Skip to content

Commit

Permalink
Merge pull request #112 from lazd/nsdeclare
Browse files Browse the repository at this point in the history
Use nsdeclare for namespace declarations
  • Loading branch information
vladikoff committed Aug 3, 2014
2 parents 49328c5 + eee220b commit 37c469d
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 49 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ Task targets, files and options may be specified according to the grunt [Configu

#### separator
Type: `String`

Default: `linefeed + linefeed`

Concatenated files will be joined on this string.

#### namespace
Type: `String` or `false` or `function`

Default: `'JST'`

The namespace in which the precompiled templates will be assigned. *Use dot notation (e.g. App.Templates) for nested namespaces or false for no namespace wrapping.* When false with `amd` option set `true`, templates will be returned directly from the AMD wrapper.
Expand Down Expand Up @@ -65,18 +67,21 @@ options: {

#### partialsUseNamespace
Type: `Boolean`

Default: `false`

When set to `true`, partials will be registered in the `namespace` in addition to templates.

#### wrapped
Type: `Boolean`

Default: `true`

Determine if preprocessed template functions will be wrapped in Handlebars.template function.

#### node
Type: `Boolean`

Default: `false`

Enable the compiled file to be required on node.js by preppending and appending proper declarations. You can use the file safely on the front-end.
Expand All @@ -85,6 +90,7 @@ For this option to work you need to define the `namespace` option.

#### amd
Type: `Boolean` or `String` or `Array`

Default: `false`

Wraps the output file with an AMD define function and returns the compiled template namespace unless namespace has been explicitly set to false in which case the template function will be returned directly.
Expand All @@ -102,6 +108,7 @@ define(['handlebars'], function(Handlebars) {

#### commonjs
Type: `Boolean`

Default: `false`

Wraps the output file in a CommonJS module function, exporting the compiled templates. It will also add templates to the template namespace, unless `namespace` is explicitly set to `false`.
Expand Down Expand Up @@ -185,6 +192,7 @@ Note: If processPartialName is not provided as an option the default assumes tha

#### partialRegex
Type: `Regexp`

Default: `/^_/`

This option accepts a regex that defines the prefix character that is used to identify Handlebars partial files.
Expand All @@ -198,6 +206,7 @@ options: {

#### partialsPathRegex
Type: `Regexp`

Default: `/./`

This option accepts a regex that defines the path to a directory of Handlebars partials files. The example below shows how to mark every file in a specific directory as a partial.
Expand All @@ -211,6 +220,7 @@ options: {

#### compilerOptions
Type `Object`

Default: `{}`

This option allows you to specify a hash of options which will be passed directly to the Handlebars compiler.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
"test": "grunt test"
},
"dependencies": {
"chalk": "~0.4.0",
"handlebars": "~1.3.0",
"chalk": "~0.4.0"
"nsdeclare": "0.1.0"
},
"devDependencies": {
"grunt-contrib-jshint": "~0.6.0",
Expand Down
52 changes: 29 additions & 23 deletions tasks/handlebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

'use strict';
var chalk = require('chalk');
var nsdeclare = require('nsdeclare');

module.exports = function(grunt) {
var _ = grunt.util._;
var getNamespaceDeclaration = require('./lib/handlebars').getNamespaceDeclaration;

// content conversion for templates
var defaultProcessContent = function(content) { return content; };
Expand All @@ -23,8 +23,8 @@ module.exports = function(grunt) {
var defaultProcessName = function(name) { return name; };

// filename conversion for partials
var defaultProcessPartialName = function(filePath) {
var pieces = _.last(filePath.split('/')).split('.');
var defaultProcessPartialName = function(filepath) {
var pieces = _.last(filepath.split('/')).split('.');
var name = _(pieces).without(_.last(pieces)).join('.'); // strips file extension
if (name.charAt(0) === '_') {
name = name.substr(1, name.length); // strips leading _ character
Expand All @@ -47,7 +47,7 @@ module.exports = function(grunt) {
var partialsPathRegex = options.partialsPathRegex || /./;

// assign regex for partial detection
var isPartial = options.partialRegex || /^_/;
var isPartialRegex = options.partialRegex || /^_/;

// assign transformation functions
var processContent = options.processContent || defaultProcessContent;
Expand All @@ -56,25 +56,33 @@ module.exports = function(grunt) {
var processAST = options.processAST || defaultProcessAST;
var useNamespace = options.namespace !== false;

var namespaceInfo = _.memoize(function(filepath) {
if (!useNamespace) {return undefined;}
if (_.isFunction(options.namespace)) {
return getNamespaceDeclaration(options.namespace(filepath));
} else {
return getNamespaceDeclaration(options.namespace);
}
});

// assign compiler options
var compilerOptions = options.compilerOptions || {},
filesCount = 0;

this.files.forEach(function(f) {
var partials = [];
var templates = [];
var nsDeclarations = {};

// Namespace info for current template
var nsInfo;

// Map of already declared namespace parts
var nsDeclarations = {};

// nsdeclare options when fetching namespace info
var nsDeclareOptions = { response: 'details', declared: nsDeclarations };

// Just get the namespace info for a given template
var getNamespaceInfo = _.memoize(function(filepath) {
if (!useNamespace) {return undefined;}
if (_.isFunction(options.namespace)) {
return nsdeclare(options.namespace(filepath), nsDeclareOptions);
} else {
return nsdeclare(options.namespace, nsDeclareOptions);
}
});

// iterate files, processing partials and templates separately
f.src.filter(function(filepath) {
// Warn on and remove invalid source files (if nonull was set).
Expand All @@ -87,11 +95,6 @@ module.exports = function(grunt) {
})
.forEach(function(filepath) {
var src = processContent(grunt.file.read(filepath), filepath);
nsInfo = namespaceInfo(filepath);
if (nsInfo) {
// save a map of declarations so we can put them at the top of the file later
nsDeclarations[nsInfo.namespace] = nsInfo.declaration;
}

var Handlebars = require('handlebars');
var ast, compiled, filename;
Expand All @@ -110,19 +113,25 @@ module.exports = function(grunt) {
}

// register partial or add template to namespace
if (partialsPathRegex.test(filepath) && isPartial.test(_.last(filepath.split('/')))) {
if (partialsPathRegex.test(filepath) && isPartialRegex.test(_.last(filepath.split('/')))) {
filename = processPartialName(filepath);
if (options.partialsUseNamespace === true) {
nsInfo = getNamespaceInfo(filepath);

partials.push(nsInfo.declaration);
partials.push('Handlebars.registerPartial('+JSON.stringify(filename)+', '+nsInfo.namespace+'['+JSON.stringify(filename)+'] = '+compiled+');');
} else {
partials.push('Handlebars.registerPartial('+JSON.stringify(filename)+', '+compiled+');');
}
} else {
nsInfo = getNamespaceInfo(filepath);

if(options.amd && !useNamespace) {
compiled = 'return ' + compiled;
}
filename = processName(filepath);
if (useNamespace) {
templates.push(nsInfo.declaration);
templates.push(nsInfo.namespace+'['+JSON.stringify(filename)+'] = '+compiled+';');
} else if (options.commonjs === true) {
templates.push('templates['+JSON.stringify(filename)+'] = '+compiled+';');
Expand All @@ -137,9 +146,6 @@ module.exports = function(grunt) {
grunt.log.warn('Destination not written because compiled files were empty.');
} else {
if (useNamespace) {
var declarations = _.values(nsDeclarations).join(options.separator);
output.unshift(declarations);

if (options.node) {
output.unshift('Handlebars = glob.Handlebars || require(\'handlebars\');');
output.unshift('var glob = (\'undefined\' === typeof window) ? global : window,');
Expand Down
18 changes: 0 additions & 18 deletions tasks/lib/handlebars.js

This file was deleted.

4 changes: 2 additions & 2 deletions test/expected/handlebarsnowrap.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
this["JST"] = this["JST"] || {};

Handlebars.registerPartial("partial", function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
Expand All @@ -9,6 +7,8 @@ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
return "<span>Canada</span>";
});

this["JST"] = this["JST"] || {};

this["JST"]["test/fixtures/one.hbs"] = function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Handlebars.helpers); partials = this.merge(partials, Handlebars.partials); data = data || {};
Expand Down
6 changes: 3 additions & 3 deletions test/expected/namespace_as_function.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
this["JST"] = this["JST"] || {};
this["JST"]["countries"] = this["JST"]["countries"] || {};
this["JST"] = this["JST"] || {};
this["JST"]["treeNav"] = this["JST"]["treeNav"] || {};
this["JST"]["treeNav"]["leaves"] = this["JST"]["treeNav"]["leaves"] || {};

this["JST"]["countries"]["basic"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
Expand All @@ -13,6 +10,9 @@ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
return "Basic template that does nothing.";
});

this["JST"]["treeNav"] = this["JST"]["treeNav"] || {};
this["JST"]["treeNav"]["leaves"] = this["JST"]["treeNav"]["leaves"] || {};

this["JST"]["treeNav"]["leaves"]["basic"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
Expand Down
4 changes: 2 additions & 2 deletions test/expected/partials_path_regex.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
this["JST"] = this["JST"] || {};

Handlebars.registerPartial("partial", Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
Expand All @@ -9,6 +7,8 @@ helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
return "<span>Canada</span>";
}));

this["JST"] = this["JST"] || {};

this["JST"]["test/fixtures/one.hbs"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Handlebars.helpers); partials = this.merge(partials, Handlebars.partials); data = data || {};
Expand Down

0 comments on commit 37c469d

Please sign in to comment.