Compare commits

..

59 Commits

Author SHA1 Message Date
javi
7a1bf369ce allow to set template compiler 2014-01-17 13:05:52 +01:00
Kyle Robinson Young
a5c76f56e4 Explicitly set files to publish to npm. Ref gruntjs/gruntjs.com#65 2013-12-15 10:17:44 -08:00
Kyle Robinson Young
ffb72d7dd9 Remove verbose writeFlags as of Grunt v0.4.2 its automatic. Ref gruntjs/grunt#749. 2013-11-30 09:12:35 -08:00
Mason Stewart
37326b9a58 Clarification about interpolation setting in the README. Fixes #29
Closes gh-34.
2013-10-23 00:34:59 -04:00
Kyle Robinson Young
38ee6e22d4 Remove Gruntfile.js as main in package.json 2013-09-14 12:12:09 -07:00
Kyle Robinson Young
2a793822f4 Bump v0.5.1 2013-07-14 19:25:40 -07:00
Kyle Robinson Young
1b64cccea0 Fix typo 2013-07-14 19:25:18 -07:00
Kyle Robinson Young
8839411c2c Upgrade jshint 2013-07-14 19:21:01 -07:00
Kyle Robinson Young
ef494300fa Update copyright to 2013 2013-07-14 19:19:52 -07:00
Kyle Robinson Young
4ec59db55c Add gitattributes to fix crlf issues 2013-07-14 19:18:09 -07:00
Kyle Robinson Young
f7bd8b7c52 Merge pull request #30 from jimrubenstein/master
Add the filepath for the JST that failed to compile
2013-07-14 19:14:14 -07:00
Jim Rubenstein
7b290ffe80 Output which file failed to compile 2013-07-14 21:38:36 -04:00
Tyler Kellen
dc66a34f38 quote version number for travis 2013-03-15 01:27:09 -05:00
Tyler Kellen
dfe5b8f22a add node 0.10 to travis 2013-03-14 17:21:29 -05:00
Tyler Kellen
0588336f6c update docs 2013-03-06 12:54:06 -05:00
Tyler Kellen
4eaee630c9 version bump 2013-03-06 12:51:36 -05:00
Tyler Kellen
666ff0053e Merge pull request #25 from Alshten/master
Return the function when namespace explicitely set to 'false'
2013-03-06 09:48:08 -08:00
Adrien Antoine
30685afc19 Replaced amdWrapper by amd 2013-03-06 17:09:18 +00:00
Adrien Antoine
efee77f83c Fixed the tests for the AMD-no-Namespace improvement 2013-03-06 13:56:40 +00:00
Adrien Antoine
4a4e1734bf Improved AMD support when namespace = false 2013-03-06 11:44:15 +00:00
Tyler Kellen
2277764a38 bump contrib-jshint 2013-02-26 11:43:50 -05:00
Tyler Kellen
1bd9475ad2 regen readme to fix typo 2013-02-20 12:42:59 -05:00
Tyler Kellen
d8af514686 add peerDependencies 2013-02-18 08:56:56 -05:00
Tyler Kellen
32b10d3fc8 fix test 2013-02-18 08:56:46 -05:00
Tyler Kellen
87924a766f 0.4 release 2013-02-15 18:58:22 -05:00
Tyler Kellen
ffe9197837 Merge pull request #19 from colinhicks/fix-tests
Fix tests failing since lodash version bump
2013-02-15 15:56:12 -08:00
Colin Hicks
3dcfe1348f Add assertion and config for new test 2013-02-15 13:45:54 -05:00
Colin Hicks
3802fa500e Add test for unscoped template variable case; compiles a block 2013-02-15 12:12:22 -05:00
Colin Hicks
9f4671ed41 Tweak expected output w/r/t lodash changes; add templateSetting.variable to test configs 2013-02-15 12:09:15 -05:00
Tyler Kellen
44f5566772 typo 2013-02-12 10:37:15 -05:00
Tyler Kellen
2f3f08fa64 Merge pull request #16 from jugglinmike/add-caveat
Add caveat for users with advanced workflows
2013-02-12 07:35:29 -08:00
Mike Pennisi
8fab2400f5 Add caveat for users with advanced workflows
The detail described here was first discussed in GitHub issue #11, where
@tkellen requested it be included in the project readme file.
2013-02-11 19:18:12 -05:00
Tyler Kellen
1f3715eaca update getting started guide link 2013-02-05 11:54:29 -05:00
Tyler Kellen
d16c9f14e7 version bump 2013-01-29 16:01:44 -05:00
Tyler Kellen
a2a57bbb75 Merge pull request #15 from jamie-stackhouse/master
Fixes #14
2013-01-29 12:59:35 -08:00
Jamie Stackhouse
73215fc73d Fix regular expression when dealing with lodash touched source. 2013-01-29 16:27:25 -04:00
Tyler Kellen
38d9cab887 fix version in generated readme 2013-01-26 22:57:05 -05:00
Tyler Kellen
b3b0783855 prep for rc7 2013-01-23 11:48:54 -05:00
Kyle Robinson Young
ab2565473e Add separator option, warn on nonexistent src files and empty output. 2013-01-10 13:08:29 -08:00
Kyle Robinson Young
f6d67bca77 Switching to this.files property per gruntjs/grunt#606. 2013-01-09 14:48:55 -08:00
Tyler Kellen
56edaf6b95 Merge pull request #11 from srigi/c39f2c9c3781e56e01e8a8f42ec899125ca1f28e
Replace Underscore.js with Lo-Dash
2013-01-02 07:36:58 -08:00
Igor Hlina
c39f2c9c37 Replace Underscore.js with Lo-Dash 2012-12-31 21:06:55 +01:00
Tyler Kellen
6aa2b5e8d1 Merge pull request #10 from taka84u9/processContent-option
Added a processContent option
2012-12-29 15:51:36 -08:00
Yuku Takahashi
e933f45e21 Added a processContent option 2012-12-29 22:18:21 +09:00
Tyler Kellen
5b469cae5f update deps 2012-12-13 10:48:39 -06:00
Tyler Kellen
ee162af004 docs and deps 2012-12-12 16:40:27 -06:00
Tyler Kellen
fb9337ad16 install grunt-cli globally with travis for testing 2012-12-12 16:40:13 -06:00
Tyler Kellen
77b6ec4d5d fix nodeunit target name 2012-11-28 08:41:28 -06:00
Tyler Kellen
4430c8bf96 documentation 2012-11-28 08:41:10 -06:00
Tyler Kellen
34b878aa51 Merge pull request #7 from tebriel/devel
Added an amdWrapper option and a prettify option
2012-11-27 07:24:21 -08:00
Chris Moultrie
1912ddbd37 Added an amdWrapper option and a prettify option 2012-11-26 13:02:20 -05:00
Tyler Kellen
5db6cf24ec fix test suite in gruntfile 2012-11-19 16:25:04 -05:00
Tyler Kellen
cd8937fbf4 remove unused var 2012-11-19 16:24:39 -05:00
Tyler Kellen
20a3b8aa0b remove expandFiles, grunt does it for us now 2012-11-19 15:58:24 -05:00
Tyler Kellen
fea4603fcd use local grunt-cli for npm test 2012-11-19 15:58:07 -05:00
Tyler Kellen
23ee0627fd install grunt-cli before testing 2012-11-13 16:43:29 -06:00
Tyler Kellen
a9a04260ff support this.file api 2012-11-13 16:12:23 -06:00
Tyler Kellen
112efb4455 update readme 2012-10-18 19:03:11 -05:00
Tyler Kellen
7e652956f5 rough in .4 2012-10-18 18:02:45 -05:00
31 changed files with 691 additions and 439 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Automatically normalize line endings for all text-based files
* text=crlf

13
.jshintrc Normal file
View File

@ -0,0 +1,13 @@
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"boss": true,
"eqnull": true,
"node": true
}

View File

@ -1,3 +1,6 @@
language: node_js language: node_js
node_js: node_js:
- 0.8 - "0.8"
- "0.10"
before_script:
- npm install -g grunt-cli

View File

@ -1,4 +1,5 @@
Tim Branyen (http://tbranyen.com) Tim Branyen (http://tbranyen.com)
Tyler Kellen (http://goingslowly.com/) Tyler Kellen (http://goingslowly.com/)
Chris Talkington (http://christalkington.com/) Chris Talkington (http://christalkington.com/)
Larry Davis (http://lazd.net/) Larry Davis (http://lazd.net/)
Adrien Antoine (http://adriantoine.com/)

View File

@ -1,8 +1,30 @@
v0.3.2: v0.5.1:
date: 2012-10-13 date: 2013-07-14
changes: changes:
- Add prettify option - Display filepath when fails to compile.
- Add amdWrapper option v0.5.0:
date: 2013-03-06
changes:
- When `namespace` is false and `amd` is true, return templates directly from AMD wrapper.
- Rename `amdwrapper` option to `amd` to match grunt-contrib-handlebars.
v0.4.1:
date: 2013-02-15
changes:
- First official release for Grunt 0.4.0.
v0.4.1rc7:
date: 2012-01-29
changes:
- Correct line endings for lodash output on windows.
v0.4.0rc7:
date: 2013-01-23
changes:
- Updating grunt/gruntplugin dependencies to rc7.
- Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
v0.4.0rc5:
date: 2013-01-09
changes:
- Updating to work with grunt v0.4.0rc5.
- Switching to this.files api.
v0.3.1: v0.3.1:
date: 2012-10-12 date: 2012-10-12
changes: changes:
@ -22,4 +44,4 @@ v0.2.2:
v0.2.0: v0.2.0:
date: 2012-08-10 date: 2012-08-10
changes: changes:
- Refactored from grunt-contrib into individual repo. - Refactored from grunt-contrib into individual repo.

1
CONTRIBUTING.md Normal file
View File

@ -0,0 +1 @@
Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project.

163
Gruntfile.js Normal file
View File

@ -0,0 +1,163 @@
/*
* grunt-contrib-jst
* http://gruntjs.com/
*
* Copyright (c) 2013 Tim Branyen, contributors
* Licensed under the MIT license.
*/
'use strict';
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
jshint: {
all: [
'Gruntfile.js',
'tasks/*.js',
'<%= nodeunit.tests %>'
],
options: {
jshintrc: '.jshintrc'
}
},
// Before generating any new files, remove any previously-created files.
clean: {
test: ['tmp']
},
// Configuration to be run (and then tested).
jst: {
compile: {
options: {
templateSettings: {
variable: 'obj'
}
},
files: {
"tmp/jst.js": ["test/fixtures/template.html"]
}
},
pretty_amd: {
options: {
templateSettings: {
variable: 'obj'
},
prettify: true,
amd: true
},
files: {
"tmp/pretty_amd.js": ["test/fixtures/template.html"]
}
},
prettify: {
options: {
templateSettings: {
variable: 'obj'
},
prettify: true
},
files: {
"tmp/pretty.js": ["test/fixtures/template.html"]
}
},
amd_wrapper: {
options: {
templateSettings: {
variable: 'obj'
},
amd:true
},
files: {
"tmp/amd_wrapper.js": ["test/fixtures/template.html"]
}
},
amd_wrapper_no_ns: {
options: {
templateSettings: {
variable: 'obj'
},
amd:true,
namespace:false
},
files: {
"tmp/amd_wrapper_no_ns.js": ["test/fixtures/template.html"]
}
},
uglyfile: {
options: {
templateSettings: {
variable: 'obj'
},
},
files: {
"tmp/uglyfile.js": ["test/fixtures/*bad-filename*"]
}
},
ns_nested: {
options: {
templateSettings: {
variable: 'obj'
},
namespace: "MyApp.JST.Main"
},
files: {
"tmp/ns_nested.js": ["test/fixtures/template.html"]
}
},
ns_nested_this: {
options: {
templateSettings: {
variable: 'obj'
},
namespace: "this.MyApp.JST.Main"
},
files: {
"tmp/ns_nested_this.js": ["test/fixtures/template.html"]
}
},
process_content: {
options: {
templateSettings: {
variable: 'obj'
},
processContent: function (src) {
return src.replace(/(^\s+|\s+$)/gm, '');
}
},
files: {
"tmp/process_content.js": ["test/fixtures/indent_template.html"]
}
},
local_scope: {
files: {
"tmp/local_scope.js": ["test/fixtures/template_local_scope.html"]
}
}
},
// Unit tests.
nodeunit: {
tests: ['test/*_test.js']
}
});
// Actually load this plugin's task(s).
grunt.loadTasks('tasks');
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.loadNpmTasks('grunt-contrib-internal');
grunt.loadNpmTasks('grunt-contrib-clean');
// Whenever the "test" task is run, first clean the "tmp" dir, then run this
// plugin's task(s), then test the result.
grunt.registerTask('test', ['clean', 'jst', 'nodeunit']);
// By default, lint and run all tests.
grunt.registerTask('default', ['jshint', 'test', 'build-contrib']);
};

View File

@ -1,4 +1,4 @@
Copyright (c) 2012 Tim Branyen, contributors Copyright (c) 2013 Tim Branyen, contributors
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation

284
README.md
View File

@ -1,116 +1,168 @@
# grunt-contrib-jst [![Build Status](https://secure.travis-ci.org/gruntjs/grunt-contrib-jst.png?branch=master)](http://travis-ci.org/gruntjs/grunt-contrib-jst) # grunt-contrib-jst v0.5.1 [![Build Status](https://travis-ci.org/gruntjs/grunt-contrib-jst.png?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-jst)
> Compile underscore templates to JST file. > Precompile Underscore templates to JST file.
## Getting Started
Install this grunt plugin next to your project's [grunt.js gruntfile][getting_started] with: `npm install grunt-contrib-jst`
## Getting Started
Then add this line to your project's `grunt.js` gruntfile: This plugin requires Grunt `~0.4.0`
```javascript If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
grunt.loadNpmTasks('grunt-contrib-jst');
``` ```shell
npm install grunt-contrib-jst --save-dev
[grunt]: https://github.com/gruntjs/grunt ```
[getting_started]: https://github.com/gruntjs/grunt/blob/master/docs/getting_started.md
Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
### Overview
```js
This task compiles Underscore compatible templates into functions that can be concatenated and minified with existing source files. grunt.loadNpmTasks('grunt-contrib-jst');
```
Inside your `grunt.js` file, add a section named `jst`. This section specifies the files to compile and the options passed to [underscore.template](http://underscorejs.org/#template).
*This plugin was designed to work with Grunt 0.4.x. If you're still using grunt v0.3.x it's strongly recommended that [you upgrade](http://gruntjs.com/upgrading-from-0.3-to-0.4), but in case you can't please use [v0.3.1](https://github.com/gruntjs/grunt-contrib-jst/tree/grunt-0.3-stable).*
#### Parameters
##### files ```object```
## Jst task
This defines what files this task will process and should contain key:value pairs. _Run this task with the `grunt jst` command._
The key (destination) should be an unique filepath (supports [grunt.template](https://github.com/gruntjs/grunt/blob/master/docs/api_template.md)) and the value (source) should be a filepath or an array of filepaths (supports [minimatch](https://github.com/isaacs/minimatch)). Task targets, files and options may be specified according to the grunt [Configuring tasks](http://gruntjs.com/configuring-tasks) guide.
Note: Values are precompiled to the namespaced JST array in the order passed. _This plugin uses [the Lo-Dash library](http://lodash.com/) to generate JavaScript template functions. Some developers generate template functions dynamically during development. If you are doing so, please be aware that the functions generated by this plugin may differ from those created at run-time. For instance, [the Underscore.js library](http://underscorejs.org/) will throw an exception if templates reference undefined top-level values, while Lo-Dash will silently insert an empty string in their place._
### Options
##### options ```object```
#### separator
This controls how this task (and its helpers) operate and should contain key:value pairs, see options below. Type: `String`
Default: linefeed + linefeed
#### Options
Concatenated files will be joined on this string.
##### namespace ```string```
#### namespace
The namespace in which the precompiled templates will be asssigned (default is JST). *Use dot notation (e.g. App.Templates) for nested namespaces.* Type: `String`
Default: 'JST'
Example:
``` javascript 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.
options: {
namespace: 'JST' #### processName
} Type: `function`
``` Default: null
##### prettify ```boolean``` This option accepts a function which takes one argument (the template filepath) and returns a string which will be used as the key for the precompiled template object. The example below stores all templates on the default JST namespace in capital letters.
When doing a quick once-over of your compiled template file, it's nice to see ```js
an easy-to-read format that has one line per template. This will accomplish options: {
that. processName: function(filename) {
return filename.toUpperCase();
Example: }
```javascript }
options: { ```
prettify: true
} #### templateSettings
``` Type: `Object`
Default: null
##### amdWrapper ```boolean```
The settings passed to underscore when compiling templates.
With Require.js and a pre-compiled template.js you want the templates to be
wrapped in a define. This will wrap the output in: ```js
``` javascript jst: {
define(function() { compile: {
//Templates options: {
return this["NAMESPACE"]; templateSettings: {
}); interpolate : /\{\{(.+?)\}\}/g
``` }
},
Example: files: {
``` javascript "path/to/compiled/templates.js": ["path/to/source/**/*.html"]
options: { }
amdWrapper: true }
} }
``` ```
##### processName ```function``` #### prettify
Type: `boolean`
This option accepts a function which takes one argument (the template filepath) and returns a string which will be used as the key for the precompiled template object. The example below stores all templates on the default JST namespace in capital letters. Default: false
``` javascript When doing a quick once-over of your compiled template file, it's nice to see
options: { an easy-to-read format that has one line per template. This will accomplish
processName: function(filename) { that.
return filename.toUpperCase();
} ```js
} options: {
``` prettify: true
}
##### templateSettings ```object``` ```
The settings passed to underscore when compiling templates. #### amd
Type: `boolean`
#### Config Examples Default: false
``` javascript 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.
jst: {
compile: { ```js
options: { define(function() {
templateSettings: { //...//
interpolate : /\{\{(.+?)\}\}/g return this['[template namespace]'];
} });
}, ```
files: {
"path/to/compiled/templates.js": ["path/to/source/**/*.html"] Example:
} ```js
} options: {
} amd: true
``` }
```
--
#### processContent
*Task submitted by [Tim Branyen](http://github.com/tbranyen).* Type: `function`
This option accepts a function which takes one argument (the file content) and
returns a string which will be used as template string.
The example below strips whitespace characters from the beginning and the end of
each line.
```js
options: {
processContent: function(src) {
return src.replace(/(^\s+|\s+$)/gm, '');
}
}
```
### Usage Examples
```js
jst: {
compile: {
options: {
templateSettings: {
interpolate : /\{\{(.+?)\}\}/g
}
},
files: {
"path/to/compiled/templates.js": ["path/to/source/**/*.html"]
}
}
}
```
Note that the `interpolate: /\{\{(.+?)\}\}/g` setting above is simply an example of overwriting lodash's default interpolation. If you want to parse templates with the default `_.template` behavior (i.e. using `<div><%= this.id %></div>`), there's no need to overwrite `templateSettings.interpolate`.
## Release History
* 2013-07-14v0.5.1Display filepath when fails to compile.
* 2013-03-06v0.5.0When `namespace` is false and `amd` is true, return templates directly from AMD wrapper. Rename `amdwrapper` option to `amd` to match grunt-contrib-handlebars.
* 2013-02-15v0.4.1First official release for Grunt 0.4.0.
* 2012-01-29v0.4.1rc7Correct line endings for lodash output on windows.
* 2013-01-23v0.4.0rc7Updating grunt/gruntplugin dependencies to rc7. Changing in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
* 2013-01-09v0.4.0rc5Updating to work with grunt v0.4.0rc5. Switching to this.files api.
* 2012-10-12v0.3.1Rename grunt-contrib-lib dep to grunt-lib-contrib.
* 2012-08-23v0.3.0Options no longer accepted from global config key.
* 2012-08-16v0.2.3Support for nested namespaces.
* 2012-08-12v0.2.2Added processName functionality & escaping single quotes in filenames.
* 2012-08-10v0.2.0Refactored from grunt-contrib into individual repo.
---
Task submitted by [Tim Branyen](http://tbranyen.com)
*This file was generated on Sat Oct 19 2013 14:22:27.*

View File

17
docs/jst-examples.md Normal file
View File

@ -0,0 +1,17 @@
# Usage Examples
```js
jst: {
compile: {
options: {
templateSettings: {
interpolate : /\{\{(.+?)\}\}/g
}
},
files: {
"path/to/compiled/templates.js": ["path/to/source/**/*.html"]
}
}
}
```
Note that the `interpolate: /\{\{(.+?)\}\}/g` setting above is simply an example of overwriting lodash's default interpolation. If you want to parse templates with the default `_.template` behavior (i.e. using `<div><%= this.id %></div>`), there's no need to overwrite `templateSettings.interpolate`.

98
docs/jst-options.md Normal file
View File

@ -0,0 +1,98 @@
# Options
## separator
Type: `String`
Default: linefeed + linefeed
Concatenated files will be joined on this string.
## namespace
Type: `String`
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.
## processName
Type: `function`
Default: null
This option accepts a function which takes one argument (the template filepath) and returns a string which will be used as the key for the precompiled template object. The example below stores all templates on the default JST namespace in capital letters.
```js
options: {
processName: function(filename) {
return filename.toUpperCase();
}
}
```
## templateSettings
Type: `Object`
Default: null
The settings passed to underscore when compiling templates.
```js
jst: {
compile: {
options: {
templateSettings: {
interpolate : /\{\{(.+?)\}\}/g
}
},
files: {
"path/to/compiled/templates.js": ["path/to/source/**/*.html"]
}
}
}
```
## prettify
Type: `boolean`
Default: false
When doing a quick once-over of your compiled template file, it's nice to see
an easy-to-read format that has one line per template. This will accomplish
that.
```js
options: {
prettify: true
}
```
## amd
Type: `boolean`
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.
```js
define(function() {
//...//
return this['[template namespace]'];
});
```
Example:
```js
options: {
amd: true
}
```
## processContent
Type: `function`
This option accepts a function which takes one argument (the file content) and
returns a string which will be used as template string.
The example below strips whitespace characters from the beginning and the end of
each line.
```js
options: {
processContent: function(src) {
return src.replace(/(^\s+|\s+$)/gm, '');
}
}
```

3
docs/jst-overview.md Normal file
View File

@ -0,0 +1,3 @@
Task targets, files and options may be specified according to the grunt [Configuring tasks](http://gruntjs.com/configuring-tasks) guide.
_This plugin uses [the Lo-Dash library](http://lodash.com/) to generate JavaScript template functions. Some developers generate template functions dynamically during development. If you are doing so, please be aware that the functions generated by this plugin may differ from those created at run-time. For instance, [the Underscore.js library](http://underscorejs.org/) will throw an exception if templates reference undefined top-level values, while Lo-Dash will silently insert an empty string in their place._

View File

@ -1,87 +0,0 @@
##### files ```object```
This defines what files this task will process and should contain key:value pairs.
The key (destination) should be an unique filepath (supports [grunt.template](https://github.com/gruntjs/grunt/blob/master/docs/api_template.md)) and the value (source) should be a filepath or an array of filepaths (supports [minimatch](https://github.com/isaacs/minimatch)).
Note: Values are precompiled to the namespaced JST array in the order passed.
##### options ```object```
This controls how this task (and its helpers) operate and should contain key:value pairs, see options below.
#### Options
##### namespace ```string```
The namespace in which the precompiled templates will be asssigned (default is JST). *Use dot notation (e.g. App.Templates) for nested namespaces.*
Example:
```js
options: {
namespace: 'JST'
}
```
##### prettify ```boolean```
When doing a quick once-over of your compiled template file, it's nice to see
an easy-to-read format that has one line per template. This will accomplish
that.
Example:
```javascript
options: {
prettify: true
}
```
##### amdWrapper ```boolean```
With Require.js and a pre-compiled template.js you want the templates to be
wrapped in a define. This will wrap the output in:
``` javascript
define(function() {
//Templates
return this["NAMESPACE"];
});
```
Example:
``` javascript
options: {
amdWrapper: true
}
```
##### processName ```function```
This option accepts a function which takes one argument (the template filepath) and returns a string which will be used as the key for the precompiled template object. The example below stores all templates on the default JST namespace in capital letters.
```js
options: {
processName: function(filename) {
return filename.toUpperCase();
}
}
```
##### templateSettings ```object```
The settings passed to underscore when compiling templates.
#### Config Examples
```js
jst: {
compile: {
options: {
templateSettings: {
interpolate : /\{\{(.+?)\}\}/g
}
},
files: {
"path/to/compiled/templates.js": ["path/to/source/**/*.html"]
}
}
}
```

View File

@ -1 +1 @@
This task compiles Underscore compatible templates into functions that can be concatenated and minified with existing source files. *This plugin was designed to work with Grunt 0.4.x. If you're still using grunt v0.3.x it's strongly recommended that [you upgrade](http://gruntjs.com/upgrading-from-0.3-to-0.4), but in case you can't please use [v0.3.1](https://github.com/gruntjs/grunt-contrib-jst/tree/grunt-0.3-stable).*

114
grunt.js
View File

@ -1,114 +0,0 @@
/*
* grunt-contrib-jst
* http://gruntjs.com/
*
* Copyright (c) 2012 Tim Branyen, contributors
* Licensed under the MIT license.
*/
module.exports = function(grunt) {
'use strict';
// Project configuration.
grunt.initConfig({
lint: {
all: ['grunt.js', 'tasks/*.js', '<config:nodeunit.tasks>']
},
jshint: {
options: {
curly: true,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
node: true,
es5: true
}
},
// Before generating any new files, remove any previously-created files.
clean: {
test: ['tmp']
},
// Configuration to be run (and then tested).
jst: {
compile: {
files: {
"tmp/jst.js": ["test/fixtures/template.html"]
}
},
pretty_amd: {
options: {
prettify: true,
amdWrapper: true
},
files: {
"tmp/pretty_amd.js": ["test/fixtures/template.html"]
}
},
prettify: {
options: {
prettify: true
},
files: {
"tmp/pretty.js": ["test/fixtures/template.html"]
}
},
amd_wrapper: {
options: {
amdWrapper:true
},
files: {
"tmp/amd_wrapper.js": ["test/fixtures/template.html"]
}
},
uglyfile: {
files: {
"tmp/uglyfile.js": ["test/fixtures/*bad-filename*"]
}
},
ns_nested: {
options: {
namespace: "MyApp.JST.Main"
},
files: {
"tmp/ns_nested.js": ["test/fixtures/template.html"]
}
},
ns_nested_this: {
options: {
namespace: "this.MyApp.JST.Main"
},
files: {
"tmp/ns_nested_this.js": ["test/fixtures/template.html"]
}
}
},
// Unit tests.
nodeunit: {
tasks: ['test/*_test.js']
}
});
// Actually load this plugin's task(s).
grunt.loadTasks('tasks');
// The clean plugin helps in testing.
grunt.loadNpmTasks('grunt-contrib-clean');
// Whenever the "test" task is run, first clean the "tmp" dir, then run this
// plugin's task(s), then test the result.
grunt.renameTask('test', 'nodeunit');
grunt.registerTask('test', 'clean jst nodeunit');
// By default, lint and run all tests.
grunt.registerTask('default', 'lint test');
};

View File

@ -1,41 +1,50 @@
{ {
"name": "grunt-contrib-jst", "name": "grunt-contrib-jst",
"description": "Precompile Underscore templates to JST file.", "description": "Precompile Underscore templates to JST file.",
"version": "0.3.2", "version": "0.5.1",
"homepage": "https://github.com/gruntjs/grunt-contrib-jst", "homepage": "https://github.com/gruntjs/grunt-contrib-jst",
"author": { "author": {
"name": "Grunt Team", "name": "Grunt Team",
"url": "http://gruntjs.com/" "url": "http://gruntjs.com/"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/gruntjs/grunt-contrib-jst.git" "url": "git://github.com/gruntjs/grunt-contrib-jst.git"
}, },
"bugs": { "bugs": {
"url": "https://github.com/gruntjs/grunt-contrib-jst/issues" "url": "https://github.com/gruntjs/grunt-contrib-jst/issues"
}, },
"licenses": [ "licenses": [
{ {
"type": "MIT", "type": "MIT",
"url": "https://github.com/gruntjs/grunt-contrib-jst/blob/master/LICENSE-MIT" "url": "https://github.com/gruntjs/grunt-contrib-jst/blob/master/LICENSE-MIT"
} }
], ],
"main": "grunt.js", "engines": {
"engines": { "node": ">= 0.8.0"
"node": ">= 0.8.0" },
}, "scripts": {
"scripts": { "test": "grunt test"
"test": "grunt test" },
}, "dependencies": {
"dependencies": { "lodash": "~1.0.0",
"underscore": "~1.3.3", "grunt-lib-contrib": "~0.5.1"
"grunt-lib-contrib": "~0.3.0" },
}, "devDependencies": {
"devDependencies": { "grunt-contrib-jshint": "~0.6.0",
"grunt": "~0.3.15", "grunt-contrib-nodeunit": "~0.2.0",
"grunt-contrib-clean": "~0.3.0" "grunt-contrib-clean": "~0.4.1",
}, "grunt-contrib-internal": "~0.4.5",
"keywords": [ "grunt": "~0.4.0"
"gruntplugin" },
] "peerDependencies": {
} "grunt": "~0.4.0"
},
"keywords": [
"gruntplugin"
],
"files": [
"tasks",
"LICENSE-MIT"
]
}

View File

@ -2,72 +2,94 @@
* grunt-contrib-jst * grunt-contrib-jst
* http://gruntjs.com/ * http://gruntjs.com/
* *
* Copyright (c) 2012 Tim Branyen, contributors * Copyright (c) 2013 Tim Branyen, contributors
* Licensed under the MIT license. * Licensed under the MIT license.
*/ */
module.exports = function(grunt) { 'use strict';
"use strict";
var _ = require("underscore"); module.exports = function(grunt) {
var helpers = require('grunt-lib-contrib').init(grunt);
var _ = require('lodash');
// filename conversion for templates // filename conversion for templates
var defaultProcessName = function(name) { return name; }; var defaultProcessName = function(name) { return name; };
grunt.registerMultiTask("jst", "Compile underscore templates to JST file", function() { grunt.registerMultiTask('jst', 'Compile underscore templates to JST file', function() {
var lf = grunt.util.linefeed;
var helpers = require("grunt-lib-contrib").init(grunt); var helpers = require('grunt-lib-contrib').init(grunt);
var options = helpers.options(this, {namespace: "JST", templateSettings: {}}); var options = this.options({
namespace: 'JST',
templateSettings: {},
processContent: function (src) { return src; },
separator: lf + lf,
template: _.template
});
// assign filename transformation functions // assign filename transformation functions
var processName = options.processName || defaultProcessName; var processName = options.processName || defaultProcessName;
grunt.verbose.writeflags(options, "Options"); var nsInfo;
if (options.namespace !== false) {
nsInfo = helpers.getNamespaceDeclaration(options.namespace);
}
// TODO: ditch this when grunt v0.4 is released this.files.forEach(function(f) {
this.files = this.files || helpers.normalizeMultiTaskFiles(this.data, this.target); var output = f.src.filter(function(filepath) {
// Warn on and remove invalid source files (if nonull was set).
var compiled, srcFiles, src, filename; if (!grunt.file.exists(filepath)) {
var output = []; grunt.log.warn('Source file "' + filepath + '" not found.');
var nsInfo = helpers.getNamespaceDeclaration(options.namespace); return false;
} else {
this.files.forEach(function(files) { return true;
srcFiles = grunt.file.expandFiles(files.src); }
srcFiles.forEach(function(file) { })
src = grunt.file.read(file); .map(function(filepath) {
var src = options.processContent(grunt.file.read(filepath));
var compiled, filename;
try { try {
compiled = _.template(src, false, options.templateSettings).source; compiled = options.template(src, false, options.templateSettings).source;
} catch (e) { } catch (e) {
grunt.log.error(e); grunt.log.error(e);
grunt.fail.warn("JST failed to compile."); grunt.fail.warn('JST "' + filepath + '" failed to compile.');
} }
if (options.prettify) { if (options.prettify) {
compiled = compiled.replace(/\n+/g, ''); compiled = compiled.replace(new RegExp('\n', 'g'), '');
} }
filename = processName(file); filename = processName(filepath);
output.push(nsInfo.namespace+"["+JSON.stringify(filename)+"] = "+compiled+";");
if (options.amd && options.namespace === false) {
return 'return ' + compiled;
}
return nsInfo.namespace+'['+JSON.stringify(filename)+'] = '+compiled+';';
}); });
if(output.length > 0) { if (output.length < 1) {
output.unshift(nsInfo.declaration); grunt.log.warn('Destination not written because compiled files were empty.');
if (options.amdWrapper) { } else {
if (options.prettify) { if (options.namespace !== false) {
output.forEach(function(line, index) { output.unshift(nsInfo.declaration);
output[index] = " " + line;
});
}
output.unshift("define(function(){");
output.push(" return " + nsInfo.namespace + ";\n});");
} }
grunt.file.write(files.dest, output.join("\n\n")); if (options.amd) {
grunt.log.writeln("File '" + files.dest + "' created."); if (options.prettify) {
output.forEach(function(line, index) {
output[index] = " " + line;
});
}
output.unshift("define(function(){");
if (options.namespace !== false) {
// Namespace has not been explicitly set to false; the AMD
// wrapper will return the object containing the template.
output.push(" return " + nsInfo.namespace + ";");
}
output.push("});");
}
grunt.file.write(f.dest, output.join(grunt.util.normalizelf(options.separator)));
grunt.log.writeln('File "' + f.dest + '" created.');
} }
}); });
}); });
}; };

View File

@ -2,15 +2,14 @@ define(function(){
this["JST"] = this["JST"] || {}; this["JST"] = this["JST"] || {};
this["JST"]["test/fixtures/template.html"] = function(obj){ this["JST"]["test/fixtures/template.html"] = function(obj) {
var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')}; var __t, __p = '', __e = _.escape;
with(obj||{}){ __p += '<head><title>' +
__p+='<head><title>'+ ((__t = ( obj.title )) == null ? '' : __t) +
( title )+
'</title></head>'; '</title></head>';
} return __p
return __p;
}; };
return this["JST"]; return this["JST"];
}); });

View File

@ -0,0 +1,11 @@
define(function(){
return function(obj) {
var __t, __p = '', __e = _.escape;
__p += '<head><title>' +
((__t = ( obj.title )) == null ? '' : __t) +
'</title></head>';
return __p
}
});

View File

@ -1,11 +1,9 @@
this["JST"] = this["JST"] || {}; this["JST"] = this["JST"] || {};
this["JST"]["test/fixtures/template.html"] = function(obj){ this["JST"]["test/fixtures/template.html"] = function(obj) {
var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')}; var __t, __p = '', __e = _.escape;
with(obj||{}){ __p += '<head><title>' +
__p+='<head><title>'+ ((__t = ( obj.title )) == null ? '' : __t) +
( title )+
'</title></head>'; '</title></head>';
} return __p
return __p;
}; };

View File

@ -0,0 +1,13 @@
this["JST"] = this["JST"] || {};
this["JST"]["test/fixtures/template_local_scope.html"] = function(obj) {
obj || (obj = {});
var __t, __p = '', __e = _.escape;
with (obj) {
__p += '<head><title>' +
((__t = ( title )) == null ? '' : __t) +
'</title></head>';
}
return __p
};

View File

@ -2,12 +2,10 @@ this["MyApp"] = this["MyApp"] || {};
this["MyApp"]["JST"] = this["MyApp"]["JST"] || {}; this["MyApp"]["JST"] = this["MyApp"]["JST"] || {};
this["MyApp"]["JST"]["Main"] = this["MyApp"]["JST"]["Main"] || {}; this["MyApp"]["JST"]["Main"] = this["MyApp"]["JST"]["Main"] || {};
this["MyApp"]["JST"]["Main"]["test/fixtures/template.html"] = function(obj){ this["MyApp"]["JST"]["Main"]["test/fixtures/template.html"] = function(obj) {
var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')}; var __t, __p = '', __e = _.escape;
with(obj||{}){ __p += '<head><title>' +
__p+='<head><title>'+ ((__t = ( obj.title )) == null ? '' : __t) +
( title )+
'</title></head>'; '</title></head>';
} return __p
return __p;
}; };

View File

@ -1,3 +1,3 @@
this["JST"] = this["JST"] || {}; this["JST"] = this["JST"] || {};
this["JST"]["test/fixtures/template.html"] = function(obj){var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};with(obj||{}){__p+='<head><title>'+( title )+'</title></head>';}return __p;}; this["JST"]["test/fixtures/template.html"] = function(obj) {var __t, __p = '', __e = _.escape;__p += '<head><title>' +((__t = ( obj.title )) == null ? '' : __t) +'</title></head>';return __p};

View File

@ -2,7 +2,8 @@ define(function(){
this["JST"] = this["JST"] || {}; this["JST"] = this["JST"] || {};
this["JST"]["test/fixtures/template.html"] = function(obj){var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};with(obj||{}){__p+='<head><title>'+( title )+'</title></head>';}return __p;}; this["JST"]["test/fixtures/template.html"] = function(obj) {var __t, __p = '', __e = _.escape;__p += '<head><title>' +((__t = ( obj.title )) == null ? '' : __t) +'</title></head>';return __p};
return this["JST"]; return this["JST"];
}); });

View File

@ -0,0 +1,9 @@
this["JST"] = this["JST"] || {};
this["JST"]["test/fixtures/indent_template.html"] = function(obj) {
var __t, __p = '', __e = _.escape;
__p += '<div>\n<div>\n<div>\n' +
((__t = ( obj.name )) == null ? '' : __t) +
'\n</div>\n</div>\n</div>';
return __p
};

View File

@ -1,9 +1,7 @@
this["JST"] = this["JST"] || {}; this["JST"] = this["JST"] || {};
this["JST"]["test/fixtures/it's-a-bad-filename.html"] = function(obj){ this["JST"]["test/fixtures/it's-a-bad-filename.html"] = function(obj) {
var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')}; var __t, __p = '', __e = _.escape;
with(obj||{}){ __p += 'never name your file like this.';
__p+='never name your file like this.'; return __p
}
return __p;
}; };

7
test/fixtures/indent_template.html vendored Normal file
View File

@ -0,0 +1,7 @@
<div>
<div>
<div>
<%= obj.name %>
</div>
</div>
</div>

View File

@ -1 +1 @@
<head><title><%= title %></title></head> <head><title><%= obj.title %></title></head>

View File

@ -0,0 +1 @@
<head><title><%= title %></title></head>

View File

@ -6,7 +6,7 @@ exports['jst'] = {
var expect, result; var expect, result;
test.expect(7); test.expect(10);
expect = grunt.file.read("test/expected/jst.js"); expect = grunt.file.read("test/expected/jst.js");
result = grunt.file.read("tmp/jst.js"); result = grunt.file.read("tmp/jst.js");
@ -23,7 +23,7 @@ exports['jst'] = {
expect = grunt.file.read("test/expected/ns_nested.js"); // same as previous test expect = grunt.file.read("test/expected/ns_nested.js"); // same as previous test
result = grunt.file.read("tmp/ns_nested_this.js"); result = grunt.file.read("tmp/ns_nested_this.js");
test.equal(expect, result, "should define parts of nested namespaces, ignoring this."); test.equal(expect, result, "should define parts of nested namespaces, ignoring this.");
expect = grunt.file.read("test/expected/pretty.js"); expect = grunt.file.read("test/expected/pretty.js");
result = grunt.file.read("tmp/pretty.js"); result = grunt.file.read("tmp/pretty.js");
test.equal(expect, result, "should make the output be 1 line per template, making the output less ugly"); test.equal(expect, result, "should make the output be 1 line per template, making the output less ugly");
@ -32,9 +32,21 @@ exports['jst'] = {
result = grunt.file.read("tmp/amd_wrapper.js"); result = grunt.file.read("tmp/amd_wrapper.js");
test.equal(expect, result, "should wrap the template with define for AMD pattern"); test.equal(expect, result, "should wrap the template with define for AMD pattern");
expect = grunt.file.read("test/expected/amd_wrapper_no_ns.js");
result = grunt.file.read("tmp/amd_wrapper_no_ns.js");
test.equal(expect, result, "should wrap the template with define for AMD pattern and return the function itself with no namespace");
expect = grunt.file.read("test/expected/pretty_amd.js"); expect = grunt.file.read("test/expected/pretty_amd.js");
result = grunt.file.read("tmp/pretty_amd.js"); result = grunt.file.read("tmp/pretty_amd.js");
test.equal(expect, result, "should make the AMD wrapper output pretty"); test.equal(expect, result, "should make the AMD wrapper output pretty");
expect = grunt.file.read("test/expected/process_content.js");
result = grunt.file.read("tmp/process_content.js");
test.equal(expect, result, "should convert file content");
expect = grunt.file.read("test/expected/local_scope.js");
result = grunt.file.read("tmp/local_scope.js");
test.equal(expect, result, "should add `with` block when templateSettings.variable is undefined");
test.done(); test.done();
} }