# grunt-angular-templates [![Build Status](https://travis-ci.org/ericclemmons/grunt-angular-templates.svg)](https://travis-ci.org/ericclemmons/grunt-angular-templates) [![Dependencies](https://david-dm.org/ericclemmons/grunt-angular-templates.svg)](https://david-dm.org/ericclemmons/grunt-angular-templates) [![devDependencies](https://david-dm.org/ericclemmons/grunt-angular-templates/dev-status.svg)](https://david-dm.org/ericclemmons/grunt-angular-templates#info=devDependencies&view=table) > Speed up your AngularJS app by automatically minifying, combining, > and automatically caching your HTML templates with `$templateCache`. Here's an example of the output created by this task from multiple `.html` files: ```js angular.module('app').run(["$templateCache", function($templateCache) { $templateCache.put("home.html", // contents for home.html ... ); ... $templateCache.put("src/app/templates/button.html", // contents for button.html ); }]); ``` Then, when you use `ng-include` or `templateUrl` with `$routeProvider`, the template is already loaded without an extra AJAX request! ## Table of Contents - [Installation](#installation) - [Options](#options) - [Usage](#usage) - [Examples](#examples) - [Changelog](#changelog) - [License](#license) ## Installation *This plugin requires [Grunt][1] `~0.4.0`* *Usemin integration requires [grunt-usemin][5] `~2.0.0`* Install the plugin: $ npm install grunt-angular-templates --save-dev Enable the plugin within your `Gruntfile`: ```js grunt.loadNpmTasks('grunt-angular-templates'); ``` ## Options ### angular > Global namespace for Angular. If you use `angular.noConflict()`, then set this value to whatever you re-assign angular to. Otherwise, it defaults to `angular`. ### bootstrap > Callback to modify the bootstraper that registers the templates with `$templateCache`. By default, the bootstrap script wraps `function($templateCache) { ... }` with: ```js angular.module('app').run(['$templateCache', ... ]); ``` If you want to create your own wrapper so you register the templates as an AMD or CommonJS module, set the `bootstrap` option to something like: ```js bootstrap: function(module, script) { return 'module.exports[module] = ' + script + ';'; } ``` ### concat > Name of `concat` target to append the compiled template path to. This is especially handy if you combine your scripts using [grunt-contrib-concat][4] or [grunt-usemin][5]. ### htmlmin > Object containing [htmlmin options][2] that will *significantly* reduce the filesize of the compiled templates. Without this, the HTML (whitespace and all) will be faithfully compiled down into the final `.js` file. Minifying that file will only cut down on the *Javascript* code, not the *HTML* within the strings. I recommend using the following settings for production: ```js htmlmin: { collapseBooleanAttributes: true, collapseWhitespace: true, removeAttributeQuotes: true, removeComments: true, // Only if you don't use comment directives! removeEmptyAttributes: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true } ``` If you are using SVG, please make sure you set ```keepClosingSlash:true``` ### module > `String` of the `angular.module` to register templates with. If not specified, it will automatically be the name of the `ngtemplates` subtask (e.g. `app`, based on the examples below). ### prefix > `String` to prefix template URLs with. Defaults to `''` If you need to use absolute urls: ```js ngtemplates: { app: { options: { prefix: '/' } } } ``` If you serve static assets from another directory, you specify that as well. ### source > Callback to modify the template's source code. If you would like to prepend a comment, strip whitespace, or do post-processing on the HTML that `ngtemplates` doesn't otherwise do, use this function. ### append > Boolean to indicate the templates should be appended to dest instead of replacing it. Normally grunt-angular-templates creates a new file at `dest`. This option makes it append the compiled templates to the `dest` file rather than replace its contents. This is just a useful alternative to creating a temporary `dest` file and concatting it to your application. ### standalone > Boolean indicated if the templates are part of an existing module or a standalone. Defaults to `false`. - If the value is `false`, the module will look like `angular.module('app')`, meaning `app` module is retrieved. - If the value is `true`, the module will look like `angular.module('app', [])`, meaning `app` module is created. ### url > Callback to modify the template's `$templateCache` URL. Normally, this isn't needed as specifying your files with `cwd` ensures that URLs load via both AJAX and `$templateCache`. ### usemin > Path to `` usemin target This should be the output path of the compiled JS indicated in your HTML, such as `path/to/output.js` shown here. ## Usage ### Compiling HTML Templates After configuring your `ngtemplates` task, you can either run the task directly: $ grunt ngtemplates Or, bake it into an existing task: ```js grunt.registerTask('default', [ 'jshint', 'ngtemplates', 'concat' ]); ``` ### Including Compiled Templates Finally, you have to load the compiled templates' `.js` file into your application. #### Using HTML ```html ``` #### Using Grunt's `concat` task: This is my personal preference, since you don't have to worry about what the destination file is actually called. ```js concat: { app: { src: [ '**.js', '<%= ngtemplates.app.dest %>' ], dest: [ 'app.js' ] } } ``` #### Using [grunt-usemin][5] Using the following HTML as an example: ```html ``` **Do not use the `concat` option**, even though grunt-usemin generates a `concat.generated` object behind the scenes. Instead, use the `usemin` option to indicate the anticipated output filepath from grunt-usemin. ```js ngtemplates: { app: { src: '**.html', dest: 'template.js', options: { usemin: 'dist/vendors.js' // <~~ This came from the block } } } ``` **Note**: Earlier versions of grunt-usemin (*correctly, in my opinion*) would have generated a `concat['dist/vendors.js']` object for each build section in the HTML. Now, because there's a single `concat.generated` object with **all** JS/CSS files within it, I'm back-tracking the proper `concat` target for you. ## Examples ### Register HTML Templates in `app` Module ```js ngtemplates: { app: { src: '**.html', dest: 'templates.js' } } ``` ### Register Relative Template URLs Normally, your app, templates, & server are in separate folders, which means that the template URL is **different** from the file path. ```js ngtemplates: { app: { cwd: 'src/app', src: 'templates/**.html', dest: 'build/app.templates.js' } } ``` This will store the template URL as `templates/home.html` instead of `src/app/templates/home.html`, which would cause a 404. ### Minify Template HTML Simply pass the [same options][2] as the `htmlmin` task: ```js ngtemplates: { app: { src: '**.html', dest: 'templates.js', options: { htmlmin: { collapseWhitespace: true, collapseBooleanAttributes: true } } } } ``` Or, if you already have an existing `htmlmin` task, you can reference it: ```js ngtemplates: { app: { src: '**.html', dest: 'templates.js', options: { htmlmin: '<%= htmlmin.app %>' } } } ``` ### Customize Template URL Suppose you only use `ngtemplates` when on production, but locally you serve templates via Node, sans the `.html` extension. You can specify a `url` callback to further customize the registered URL: ```js ngtemplates: { app: { src: '**.html', dest: 'templates.js', options: { url: function(url) { return url.replace('.html', ''); } } } } ``` ### Customize Output Some people like [AMD & RequireJS][3] and would like wrap the output in AMD or something else (don't ask me why!): ```js ngtemplates: { app: { src: '**.html', dest: 'templates.js', options: { bootstrap: function(module, script) { return 'define(' + module + ', [], function() { return { init: ' + script + ' }; });'; } } } } ``` You will be able to custom everything surrounding `$templateCache.put(...)`. ## Changelog - v0.5.9 - Fixes over-matching on `cwd` when `expand:true` - v0.5.8 - Fixes `cwd` being part of the $templateCache string when `expand:true` ([#134](https://github.com/ericclemmons/grunt-angular-templates/pull/134)), Added verbose logging for minify ([#136](https://github.com/ericclemmons/grunt-angular-templates/pull/136)) - v0.5.7 – Improve error messages ([#100](https://github.com/ericclemmons/grunt-angular-templates/pull/100)) - v0.5.6 – Updated `html-minifier` to correct whitespace issues. ([96](https://github.com/ericclemmons/grunt-angular-templates/pull/96)) - v0.5.5 – Add `append` option to concat, not overwrite the `dest`. ([#89](https://github.com/ericclemmons/grunt-angular-templates/pull/89)) - v0.5.4 – Specifying an invalid `usemin` option still creates file ([#84](https://github.com/ericclemmons/grunt-angular-templates/pull/84)) - v0.5.3 – Fix bug with Underscore templates ([#79](https://github.com/ericclemmons/grunt-angular-templates/pull/79)) - v0.5.2 – Fix `usemin` matching issue on Windows ([#80](https://github.com/ericclemmons/grunt-angular-templates/pull/80)) - v0.5.1 – Add `usemin` option form v0.4.10 - v0.5.0 – Works with `grunt-usemin` ([#44](https://github.com/ericclemmons/grunt-angular-templates/issues/44)) - v0.4.10 – Add `usemin` option - v0.4.9 – Improve `prefix` and support for URLs ([#57](https://github.com/ericclemmons/grunt-angular-templates/pull/57)) - v0.4.8 – Compiled assets are JSHint-able ([#58](https://github.com/ericclemmons/grunt-angular-templates/pull/58)) - v0.4.7 – Fix bug for when htmlmin is not an Object ([#56](https://github.com/ericclemmons/grunt-angular-templates/issues/56)) - v0.4.6 – Add `prefix` option for easier URL prefixes ([#53](https://github.com/ericclemmons/grunt-angular-templates/pull/53)) - v0.4.5 – Attempt to better normalize templates based on current OS ([#52](https://github.com/ericclemmons/grunt-angular-templates/pull/52)) - v0.4.4 – Fixed regression caused by `htmlmin` ([#54](https://github.com/ericclemmons/grunt-angular-templates/pull/54)) - v0.4.3 - `options.concat` targets on Windows convert `/` to `\\`. [#48](https://github.com/ericclemmons/grunt-angular-templates/issues/48) - v0.4.2 - Fix for using `grunt-env` to change environments. Thanks to @FredrikAppelros ([#20](https://github.com/ericclemmons/grunt-express-server/pull/20)) - v0.4.1 – Fix bug with empty files. - v0.4.0 – Complete rewrite. - v0.3.12 – Whoops, forgot to make `htmlmin` a regular dependency. Thanks @rubenv ([#37](https://github.com/ericclemmons/grunt-angular-templates/pull/37)) - v0.3.11 – Add `htmlmin` option that supports both an `{ ... }` and `<%= htmlmin.options %>` for existing tasks. - v0.3.10 – Fix *unknown concat target* bug on windows, thanks to @trask ([#31](https://github.com/ericclemmons/grunt-angular-templates/pull/31)) - v0.3.9 – Allow the creation of a new module via `module.define`, thanks to @sidwood ([#28](https://github.com/ericclemmons/grunt-angular-templates/pull/28)) - v0.3.8 – Fix error that occurs when adding 0-length files, thanks to @robertklep ([#27](https://github.com/ericclemmons/grunt-angular-templates/pull/27)) - v0.3.7 – Add `noConflict` option to work with [angular.noConflict](https://github.com/angular/angular.js/pull/1535), thanks to @mbrevoort ([#26](https://github.com/ericclemmons/grunt-angular-templates/pull/26)) - v0.3.6 – Fix issue with dading to `concat` task when it's an array, thanks to @codefather ([#23](https://github.com/ericclemmons/grunt-angular-templates/pull/23)) - v0.3.5 – Preserver line endings in templates, thanks to @groner ([#21](https://github.com/ericclemmons/grunt-angular-templates/pull/21)) - v0.3.4 – Attempt to fix a bug with `Path`, thanks to @cgross ([#19](https://github.com/ericclemmons/grunt-angular-templates/issues/19)) - v0.3.3 – Add `concat` option for automatically adding compiled template file to existing `concat` (or `usemin`-created) task, thanks to @cgross ([#17](https://github.com/ericclemmons/grunt-angular-templates/pull/17)) - v0.3.2 – Add `module` option for setting which module the templates will be added to, thanks to @sidwood ([#20](https://github.com/ericclemmons/grunt-angular-templates/pull/20)) - v0.3.1 – Add `prepend` option for modifying final `$templateCache` IDs, thanks to @mbarchein. ([#16](https://github.com/ericclemmons/grunt-angular-templates/pull/16)) - v0.3.0 – **BC break** - Templates are added to an existing module (e.g. `myapp`) rather than being their own `myapp.templates` module to be manually included, thanks to @geddesign. ([#10](https://github.com/ericclemmons/grunt-angular-templates/issues/10)) - v0.2.2 – Escape backslashes, thanks to @dallonf. ([#9](https://github.com/ericclemmons/grunt-angular-templates/pull/9)) - v0.2.1 – Remove `./bin/grunt-angular-templates`. No need for it! - v0.2.0 – Update to Grunt 0.4, thanks to @jgrund. ([#5](https://github.com/ericclemmons/grunt-angular-templates/issues/5)) - v0.1.3 – Convert `\\` to `/` in template IDs (for on win32 systems) ([#3](https://github.com/ericclemmons/grunt-angular-templates/issues/3)) - v0.1.2 – Added NPM keywords - v0.1.1 – [Fails to combine multiple templates](https://github.com/ericclemmons/grunt-angular-templates/issues/1). Added directions to README on how to integrate with AngularJS app. Integrated with TravisCI - v0.1.0 – Released to [NPM](https://npmjs.org/package/grunt-angular-templates) ## License Copyright (c) 2013 Eric Clemmons Licensed under the MIT license. [1]: http://gruntjs.com/ [2]: https://github.com/gruntjs/grunt-contrib-htmlmin [3]: http://requirejs.org/docs/whyamd.html [4]: https://github.com/gruntjs/grunt-contrib-concat [5]: https://github.com/yeoman/grunt-usemin [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/ericclemmons/grunt-angular-templates/trend.png)](https://bitdeli.com/free "Bitdeli Badge")