Permalink
Browse files

allow pre-compiling into a standalone function

This lets you compile EJS templates in node, and save the generated
function into client side JavaScript file, and not depend on a client-side EJS
library.

Example usage:

	var templatesContents = 'Templates.user = ' + ejs.compile('user.ejs', {
		client: true,
		compileDebug: false // not needed, but desireable for production
	}).toString();
  • Loading branch information...
1 parent b398e53 commit 612f73ab87e4d47e67297ecff0cf5b2f20c6165c @seanmonstar seanmonstar committed Aug 24, 2012
Showing with 45 additions and 13 deletions.
  1. +2 −0 Readme.md
  2. +24 −13 lib/ejs.js
  3. +19 −0 test/ejs.js
View
@@ -41,6 +41,8 @@ Embedded JavaScript templates.
- `filename` Used by `cache` to key caches
- `scope` Function execution context
- `debug` Output generated function body
+ - `compileDebug` When `false` no debug instrumentation is compiled
+ - `client` Returns standalone compiled function
- `open` Open tag, defaulting to "<%"
- `close` Closing tag, defaulting to "%>"
- * All others are template-local variables
View
@@ -110,10 +110,11 @@ var parse = exports.parse = function(str, options){
, open = options.open || exports.open || '<%'
, close = options.close || exports.close || '%>'
, filename = options.filename
+ , compileDebug = options.compileDebug !== false
, buf = [];
buf.push('var buf = [];');
- if (false !== options._with) buf.push('\nwith (locals) {');
+ if (false !== options._with) buf.push('\nwith (locals || {}) {');
buf.push('\n buf.push(\'');
var lineno = 1;
@@ -123,7 +124,7 @@ var parse = exports.parse = function(str, options){
if (str.slice(i, open.length + i) == open) {
i += open.length
- var prefix, postfix, line = '__stack.lineno=' + lineno;
+ var prefix, postfix, line = (compileDebug ? '__stack.lineno=' : '') + lineno;
switch (str.substr(i, 1)) {
case '=':
prefix = "', escape((" + line + ', ';
@@ -206,26 +207,36 @@ var compile = exports.compile = function(str, options){
options = options || {};
var input = JSON.stringify(str)
+ , compileDebug = options.compileDebug !== false
+ , client = options.client
, filename = options.filename
? JSON.stringify(options.filename)
: 'undefined';
- // Adds the fancy stack trace meta info
- str = [
- 'var __stack = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };',
- rethrow.toString(),
- 'try {',
- exports.parse(str, options),
- '} catch (err) {',
- ' rethrow(err, __stack.input, __stack.filename, __stack.lineno);',
- '}'
- ].join("\n");
+ if (compileDebug) {
+ // Adds the fancy stack trace meta info
+ str = [
+ 'var __stack = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };',
+ rethrow.toString(),
+ 'try {',
+ exports.parse(str, options),
+ '} catch (err) {',
+ ' rethrow(err, __stack.input, __stack.filename, __stack.lineno);',
+ '}'
+ ].join("\n");
+ } else {
+ str = exports.parse(str, options);
+ }
if (options.debug) console.log(str);
+ if (client) str = 'escape = escape || ' + utils.escape.toString() + ';\n' + str;
var fn = new Function('locals, filters, escape', str);
+
+ if (client) return fn;
+
return function(locals){
- return fn.call(this, locals || {}, filters, utils.escape);
+ return fn.call(this, locals, filters, utils.escape);
}
};
View
@@ -52,6 +52,13 @@ describe('ejs.compile(str, options)', function(){
delete ejs.open;
delete ejs.close;
})
+
+ it('should have a working client option', function(){
+ var fn = ejs.compile('<p><%= foo %></p>', { client: true });
+ var str = fn.toString();
+ eval('var preFn = ' + str);
+ preFn({ foo: 'bar' }).should.equal('<p>bar</p>');
+ })
})
describe('ejs.render(str, options)', function(){
@@ -164,6 +171,18 @@ describe('exceptions', function(){
done();
}
})
+
+ it('should not include __stack if compileDebug is false', function() {
+ try {
+ ejs.render(fixture('error.ejs'), {
+ filename: 'error.ejs',
+ compileDebug: false
+ });
+ } catch (err) {
+ err.should.not.have.property('path');
+ err.stack.split('\n').slice(0, 8).join('\n').should.not.equal(fixture('error.out'));
+ }
+ });
})
describe('includes', function(){

0 comments on commit 612f73a

Please sign in to comment.