Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Allow generated JS to define new angular module #28

Merged
merged 1 commit into from

5 participants

@sidwood

This commit allows the module option to be an object literal as well as a string. When defined as an object literal we can specify that a new angular module should be defined.

ngtemplates:    {
  myapp:        {
    options:    {
      module: {
        name: 'templates',
        define: true
      }
    },
    src:        'src/views/**.html',
    dest:       'dist/templates.js'
  }
}

This generates the following.

angular.module('templates', []).run(['$templateCache', function($templateCache) {
  ...
}]);

Commit includes full test coverage and README updates. Let me know if you have any concerns or change requests.

@sidwood

I've noticed that the compiler's parameter list is getting too long now with all the additions. It's currently at 6 parameters with this PR.

If you'd like I'd be happy to submit a refactoring. I'm thinking we could pass in an options object to the compiler. I was tempted to do that in this PR but I thought I should check with you first.

@ericclemmons
Owner
@sidwood

Maybe I'm missing something but it seems better to keep grunt build tasks and app module architecture separate. What if someone has different build requirements for the dev cycle vs. production build? For example, when testing directives with external templates it's nice to have the templates compiled in one location and then compiled in a different location when building for distribution.

Originally I thought of just adding defineModule: true to the options object but I noticed the denormalised prefixing and decided on a nested config object. If that's not your cup-o-tea I'd be happy to change it. Let me know.

It's the weekend here in London so I'm off to the pub :o)

@sidwood

Another use case for multiple build targets using the same module name are i18n/i10n templates. Its feasible that someone would like to build a template cache for each locale. So the build process would A) generate the html templates using translation data and grunt template syntax, then B) use grunt-angular-templates to generate a 'templates' module for each locale. The end result would be multiple build artefacts, each an angular module with the name 'templates'. Does that make sense?

@ericclemmons
Owner
@sidwood

Nice one! Let me know how you want to proceed with the compiler refactor. If you're happy for me to handle it I can get to it later this week.

@kozmic

+1

@ericclemmons ericclemmons merged commit ce54c0c into ericclemmons:master

1 check passed

Details default The Travis CI build passed
@ericclemmons
Owner

Just tagged & released v0.3.9, thanks to you @sidwood!

I'm really sorry for the delay. Hectic few weeks for me. I just inherited ~15 new developers!

@yaru22

Hi @ericclemmons, what happened to this define option? I need to create a new module but I don't know how to do it in v0.5.1.

@ericclemmons

Howdy @yaru22. https://github.com/ericclemmons/grunt-angular-templates#standalone If there was a section in the Examples, would you have caught that? (Dunno how to structure grunt plugin readmes in the most useful way...)

@yaru22

Hi @ericclemmons. standalone option is exactly what I was looking for. I created #71 to add a brief explanation of that option. Maybe it can get better but it's a good start =)

@lautarobock

I'm using 0.5.3 but it doesnt work. put [object Object] as a module name

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 7, 2013
  1. @sidwood
This page is out of date. Refresh to see the latest.
View
39 Gruntfile.js
@@ -70,13 +70,44 @@ module.exports = function(grunt) {
src: ['test/fixtures/simple.html'],
dest: 'tmp/simple_prepend.js'
},
- target: {
+ moduleString: {
options: {
base: 'test/fixtures',
- module: 'ImAModuleNotATarget'
+ module: 'ImNotATarget'
},
src: ['test/fixtures/simple.html'],
- dest: 'tmp/options_module.js'
+ dest: 'tmp/module_option_string.js'
+ },
+ moduleObject: {
+ options: {
+ base: 'test/fixtures',
+ module: {
+ name: 'ImNotATarget',
+ define: true
+ }
+ },
+ src: ['test/fixtures/simple.html'],
+ dest: 'tmp/module_option_object.js'
+ },
+ moduleObjectName: {
+ options: {
+ base: 'test/fixtures',
+ module: {
+ name: 'ImNotATarget'
+ }
+ },
+ src: ['test/fixtures/simple.html'],
+ dest: 'tmp/module_option_object_name.js'
+ },
+ moduleObjectDefine: {
+ options: {
+ base: 'test/fixtures',
+ module: {
+ define: true
+ }
+ },
+ src: ['test/fixtures/simple.html'],
+ dest: 'tmp/module_option_object_define.js'
},
concatSimple: {
options: {
@@ -98,7 +129,7 @@ module.exports = function(grunt) {
noConflict: 'notGlobalAngular'
},
src: 'test/fixtures/simple.html',
- dest: 'tmp/options_noConflict_fixture.js'
+ dest: 'tmp/noConflict_option_fixture.js'
},
}
});
View
29 README.md
@@ -37,7 +37,7 @@ grunt.initConfig({
base: 'src/views', // $templateCache ID will be relative to this folder
prepend: '/static/assets/', // (Optional) Prepend path to $templateCache ID
module: 'App' // (Optional) The module the templates will be added to
- // Defaults to target name (e.g. `build`)
+ // Defaults to target name (e.g. `myapp`)
concat: 'dist/js/app.js' // (Optional) Append to existing `concat` target
noConflict: 'otherAngular' // (Optional) Name of angular.noConflict() app uses
},
@@ -133,6 +133,33 @@ ngtemplates: {
This will append the output file `dist/js/templates.js` to
`usemin`'s dynamic `concat` task: `dist/js/app.js`.
+### Defining an Angular Module
+
+It's possible to define a new angular module in the generated JS file.
+
+```js
+ngtemplates: {
+ myapp: {
+ options: {
+ module: {
+ name: 'templates',
+ define: true
+ }
+ },
+ src: 'src/views/**.html',
+ dest: 'dist/templates.js'
+ }
+}
+```
+
+This will generate the following at `dist/templates.js`:
+
+```js
+angular.module('templates', []).run(['$templateCache', function($templateCache) {
+ ...
+}]);
+```
+
## Changelog
### v0.3.8
View
17 tasks/angular-templates.js
@@ -16,14 +16,27 @@ module.exports = function(grunt) {
var compiler = require('./lib/compiler').init(grunt);
grunt.registerMultiTask('ngtemplates', 'Compile AngularJS templates', function() {
- var id = this.options().module || this.target;
+ var id = this.target;
var noConflict = this.options().noConflict || 'angular';
var files = grunt.file.expand(this.files[0].src);
var dest = path.normalize(this.files[0].dest);
var done = this.async();
var options = this.options();
+ var define = false;
- compiler.compile(id, noConflict, options, files, function(err, compiled) {
+ if (options.module) {
+ if (typeof options.module === 'string') {
+ id = options.module;
+ } else if (options.module.hasOwnProperty('name') && typeof options.module.name === 'string') {
+ id = options.module.name;
+ }
+
+ if (options.module.hasOwnProperty('define') && options.module.define === true ) {
+ define = true;
+ }
+ }
+
+ compiler.compile(id, noConflict, define, options, files, function(err, compiled) {
if (err) {
done(false);
} else {
View
10 tasks/lib/compiler.js
@@ -23,8 +23,14 @@ module.exports.init = function(grunt) {
}, callback);
};
- var compile = function(id, noConflict, options, files, callback) {
- var template = '<%= noConflict %>.module("<%= id %>").run(["$templateCache", function($templateCache) {\n<%= content %>\n}]);\n';
+ var compile = function(id, noConflict, define, options, files, callback) {
+ var template = '<%= noConflict %>.module("<%= id %>"';
+
+ if (define) {
+ template += ', []';
+ }
+
+ template += ').run(["$templateCache", function($templateCache) {\n<%= content %>\n}]);\n';
concat(options, files, function(err, concated) {
var compiled = process(template, id, concated.join(''), noConflict);
View
42 test/angular-templates_test.js
@@ -35,21 +35,51 @@ exports.ngtemplates = {
test.done();
},
- module: function(test) {
+ moduleString: function(test) {
test.expect(1);
- var actual = grunt.file.read('tmp/options_module.js');
- var expected = grunt.file.read('test/expected/options_module.js');
+ var actual = grunt.file.read('tmp/module_option_string.js');
+ var expected = grunt.file.read('test/expected/module_option_string.js');
- test.equal(expected, actual, 'should set the angular module to the provided options value');
+ test.equal(expected, actual, 'set angular module name to the one provided');
+ test.done();
+ },
+
+ moduleObject: function(test) {
+ test.expect(1);
+
+ var actual = grunt.file.read('tmp/module_option_object.js');
+ var expected = grunt.file.read('test/expected/module_option_object.js');
+
+ test.equal(expected, actual, ' define new angular module with provided name');
+ test.done();
+ },
+
+ moduleObjectName: function(test) {
+ test.expect(1);
+
+ var actual = grunt.file.read('tmp/module_option_object_name.js');
+ var expected = grunt.file.read('test/expected/module_option_string.js');
+
+ test.equal(expected, actual, ' set angular module name to the one provided');
+ test.done();
+ },
+
+ moduleObjectDefine: function(test) {
+ test.expect(1);
+
+ var actual = grunt.file.read('tmp/module_option_object_define.js');
+ var expected = grunt.file.read('test/expected/module_option_object_define.js');
+
+ test.equal(expected, actual, ' define new angular module with grunt target name');
test.done();
},
noConflict: function(test) {
test.expect(1);
- var actual = grunt.file.read('tmp/options_noConflict_fixture.js');
- var expected = grunt.file.read('test/expected/options_noConflict.js');
+ var actual = grunt.file.read('tmp/noConflict_option_fixture.js');
+ var expected = grunt.file.read('test/expected/noConflict_option.js');
test.equal(expected, actual, 'should reference angular by the noConflict options value');
test.done();
View
2  test/expected/options_module.js → test/expected/module_option_object.js
@@ -1,4 +1,4 @@
-angular.module("ImAModuleNotATarget").run(["$templateCache", function($templateCache) {
+angular.module("ImNotATarget", []).run(["$templateCache", function($templateCache) {
$templateCache.put("simple.html",
"Howdy there! \\ Your name is \"{{ name }}\".\n"
View
7 test/expected/module_option_object_define.js
@@ -0,0 +1,7 @@
+angular.module("moduleObjectDefine", []).run(["$templateCache", function($templateCache) {
+
+ $templateCache.put("simple.html",
+ "Howdy there! \\ Your name is \"{{ name }}\".\n"
+ );
+
+}]);
View
7 test/expected/module_option_string.js
@@ -0,0 +1,7 @@
+angular.module("ImNotATarget").run(["$templateCache", function($templateCache) {
+
+ $templateCache.put("simple.html",
+ "Howdy there! \\ Your name is \"{{ name }}\".\n"
+ );
+
+}]);
View
0  test/expected/options_noConflict.js → test/expected/noConflict_option.js
File renamed without changes
Something went wrong with that request. Please try again.