Skip to content

Commit

Permalink
Template compilation and loading improvements
Browse files Browse the repository at this point in the history
* Remove dust.load from public API and dust.compileFn completely.
* When a template is compiled, dust.compile returns a reference to the compiled template that can be passed to dust.render / dust.stream directly
* Compiled template references have a `templateName` property if they were compiled with a name
  • Loading branch information
Seth Kinast committed Apr 14, 2015
1 parent c287d5c commit 885d7e2
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 80 deletions.
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ var vm = require('vm'),

// use Node equivalents for some Dust methods
var context = vm.createContext({dust: dust});
dust.loadSource = function(source, path) {
return vm.runInContext(source, context, path);
dust.loadSource = function(source) {
return vm.runInContext(source, context);
};

dust.nextTick = process.nextTick;
Expand Down
42 changes: 24 additions & 18 deletions lib/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@
// for templates that are compiled as a callable (compileFn)
//
// for the common case (using compile and render) a name is required so that templates will be cached by name and rendered later, by name.
if (!name && name !== null) {
throw new Error('Template name parameter cannot be undefined when calling dust.compile');
}

try {
var ast = filterAST(parse(source));
Expand Down Expand Up @@ -164,18 +161,21 @@
auto: 'h'
},
escapedName = dust.escapeJs(name),
body_0 = 'function(dust){dust.register(' +
(name ? '"' + escapedName + '"' : 'null') + ',' +
compiler.compileNode(context, ast) +
');' +
compileBlocks(context) +
compileBodies(context) +
'return body_0;}';
compiled = '';

compiler.compileNode(context, ast);

if(name) {
compiled += 'dust.register("' + escapedName + '",body_0);';
}

compiled += compileBlocks(context) +
compileBodies(context);

if(dust.config.amd) {
return 'define("' + escapedName + '",["dust.core"],' + body_0 + ');';
return 'define("' + escapedName + '",["dust.core"],function(dust){' + compiled + 'return body_0});';
} else {
return '(' + body_0 + ')(dust);';
return '(function(dust){' + compiled + 'return body_0})(dust);';
}
}

Expand Down Expand Up @@ -427,13 +427,19 @@
function(str) { return '"' + escapeToJsSafeString(str) + '"';} :
JSON.stringify;

function renderSource(source, context, callback) {
var tmpl = dust.loadSource(dust.compile(source));
if(callback) {
return dust.render(tmpl, context, callback);
} else {
return dust.stream(tmpl, context);
}
}

// expose compiler methods
dust.compile = compiler.compile;
dust.filterNode = compiler.filterNode;
dust.optimizers = compiler.optimizers;
dust.pragmas = compiler.pragmas;
dust.compileNode = compiler.compileNode;
dust.nodes = compiler.nodes;
dust.compiler = compiler;
dust.compile = dust.compiler.compile;
dust.renderSource = renderSource;

return compiler;

Expand Down
54 changes: 16 additions & 38 deletions lib/dust.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,62 +84,40 @@
if (!name) {
return;
}
tmpl.templateName = name;
dust.cache[name] = tmpl;
};

dust.render = function(nameOrTemplate, context, callback) {
var chunk = new Stub(callback).head;
try {
dust.load(nameOrTemplate, chunk, Context.wrap(context, nameOrTemplate)).end();
load(nameOrTemplate, chunk, context).end();
} catch (err) {
chunk.setError(err);
}
};

dust.stream = function(name, context) {
dust.stream = function(nameOrTemplate, context) {
var stream = new Stream(),
chunk = stream.head;
dust.nextTick(function() {
try {
dust.load(name, stream.head, Context.wrap(context, name)).end();
load(nameOrTemplate, chunk, context).end();
} catch (err) {
chunk.setError(err);
}
});
return stream;
};

dust.renderSource = function(source, context, callback) {
return dust.compileFn(source)(context, callback);
};

/**
* Compile a template to an invokable function.
* If `name` is provided, also registers the template under `name`.
* @param source {String} template source
* @param [name] {String} template name
* @return {Function} has the signature `fn(context, cb)`
*/
dust.compileFn = function(source, name) {
name = name || null;
var tmpl = dust.loadSource(dust.compile(source, name));
return function(context, callback) {
var master = callback ? new Stub(callback) : new Stream();
dust.nextTick(function() {
if(typeof tmpl === 'function') {
tmpl(master.head, Context.wrap(context, name)).end();
} else {
dust.log(new Error('Template `' + name + '` could not be loaded'), ERROR);
}
});
return master;
};
};

dust.load = function(nameOrTemplate, chunk, context) {

This comment has been minimized.

Copy link
@longtian

longtian Apr 20, 2015

if dust.load is undefined
then dust.load.name will cause error
where https://github.com/krakenjs/adaro/blob/v0.1.8/lib/patch/index.js#L121

var tmpl = nameOrTemplate.__dustBody ? nameOrTemplate : dust.cache[nameOrTemplate];
function load(nameOrTemplate, chunk, context) {
if(!nameOrTemplate) {
return chunk.setError(new Error('No template or template name provided to render'));
}
var tmpl = nameOrTemplate.__dustBody ? nameOrTemplate : dust.cache[nameOrTemplate],
templateName = tmpl.templateName;
if (tmpl) {
return tmpl(chunk, context);
return tmpl(chunk, Context.wrap(context, templateName));
} else {
if (dust.onLoad) {
return chunk.map(function(chunk) {
Expand All @@ -150,13 +128,13 @@
if (!dust.cache[nameOrTemplate]) {
dust.loadSource(dust.compile(src, nameOrTemplate));
}
dust.cache[nameOrTemplate](chunk, context).end();
dust.cache[nameOrTemplate](chunk, Context.wrap(context, nameOrTemplate)).end();
});
});
}
return chunk.setError(new Error('Template Not Found: ' + nameOrTemplate));
}
};
}

dust.loadSource = function(source) {
/*jshint evil:true*/
Expand All @@ -173,7 +151,7 @@

dust.nextTick = (function() {
return function(callback) {
setTimeout(callback,0);
setTimeout(callback, 0);
};
} )();

Expand Down Expand Up @@ -848,11 +826,11 @@
// Load the partial after getting its name and end the async chunk
return this.capture(elem, context, function(name, chunk) {
context.templateName = name;
dust.load(name, chunk, context).end();
load(name, chunk, context).end();
});
} else {
context.templateName = elem;
return dust.load(elem, this, context);
return load(elem, this, context);
}
};

Expand Down
15 changes: 0 additions & 15 deletions test/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,6 @@ exports.coreSetup = function(suite, auto) {
});
});

suite.test("compileFn", function() {
var unit = this,
tmpl = dust.compileFn('Hello World');
tmpl({}, function(err, out) {
try {
unit.ifError(err);
unit.equals(out, "Hello World");
} catch(err) {
unit.fail(err);
return;
}
unit.pass();
});
});

suite.test("renderSource (stream)", function() {
var unit = this;
dust.renderSource('Hello World', {}).on('data', function(data) {
Expand Down
6 changes: 0 additions & 6 deletions test/jasmine-test/spec/coreTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,6 @@ var coreTests = [
expected: '',
message: "should test the stream rendering"
},
{
name: undefined,
source: "compilation_failure",
error: "Template name parameter cannot be undefined when calling dust.compile",
message: "if the name is not there compilation should be failed, unless it is called from renderSource"
},
{
name: "hello_world",
source: "Hello World!",
Expand Down
2 changes: 1 addition & 1 deletion test/jasmine-test/spec/renderTestSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe ('Pipe', function() {
});

function prepare(test) {
dust.config = test.config || { whitespace: false };
dust.config = test.config || { whitespace: false, amd: false, cache: true };
dust.loadSource(dust.compile(test.source, test.name));
context = test.context;
if (test.base) {
Expand Down

0 comments on commit 885d7e2

Please sign in to comment.