Make the Handlebars environment into an object
The idea is that the environment wraps up the mutable stuff in Handlebars (like the helpers) and that you could theoretically create a new one at any time and pass it in to Handlebars.template. Every test makes a new environment and uses it in template compilation.
This commit is contained in:
+9
-2
@@ -1,4 +1,4 @@
|
||||
import { base as handlebars } from "./handlebars/base";
|
||||
import { HandlebarsEnvironment } from "./handlebars/base";
|
||||
|
||||
// Each of these augment the Handlebars object. No need to setup here.
|
||||
// (This is done to easily share code between commonjs and browse envs)
|
||||
@@ -8,7 +8,14 @@ import { template } from "./handlebars/runtime";
|
||||
|
||||
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||
var create = function() {
|
||||
var hb = handlebars();
|
||||
var hb = {},
|
||||
env = new HandlebarsEnvironment();
|
||||
|
||||
// support new environments in global namespace mode
|
||||
hb.HandlebarsEnvironment = HandlebarsEnvironment;
|
||||
|
||||
hb.registerHelper = env.registerHelper.bind(env);
|
||||
hb.registerPartial = env.registerPartial.bind(env);
|
||||
|
||||
hb.SafeString = SafeString;
|
||||
hb.Exception = Exception;
|
||||
|
||||
+32
-33
@@ -1,6 +1,6 @@
|
||||
/*jshint eqnull: true */
|
||||
|
||||
import { Exception, extend } from "./utils";
|
||||
import { Exception, extend, isEmpty } from "./utils";
|
||||
|
||||
var K = function() { return this; };
|
||||
|
||||
@@ -14,40 +14,41 @@ export var REVISION_CHANGES = {
|
||||
4: '>= 1.0.0'
|
||||
};
|
||||
|
||||
// TODO: Make this a class
|
||||
export function base(helpers, partials) {
|
||||
var toString = Object.prototype.toString,
|
||||
functionType = '[object Function]',
|
||||
objectType = '[object Object]';
|
||||
|
||||
var exports = {};
|
||||
export function HandlebarsEnvironment(helpers, partials) {
|
||||
this.helpers = helpers || {};
|
||||
this.partials = partials || {};
|
||||
|
||||
var helpers = helpers || {};
|
||||
var partials = partials || {};
|
||||
registerDefaultHelpers(this);
|
||||
}
|
||||
|
||||
exports.helpers = helpers;
|
||||
exports.partials = partials;
|
||||
HandlebarsEnvironment.prototype = {
|
||||
constructor: HandlebarsEnvironment,
|
||||
|
||||
var toString = Object.prototype.toString,
|
||||
functionType = '[object Function]',
|
||||
objectType = '[object Object]';
|
||||
|
||||
exports.registerHelper = function(name, fn, inverse) {
|
||||
registerHelper: function(name, fn, inverse) {
|
||||
if (toString.call(name) === objectType) {
|
||||
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||
extend(helpers, name);
|
||||
extend(this.helpers, name);
|
||||
} else {
|
||||
if (inverse) { fn.not = inverse; }
|
||||
helpers[name] = fn;
|
||||
this.helpers[name] = fn;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
exports.registerPartial = function(name, str) {
|
||||
registerPartial: function(name, str) {
|
||||
if (toString.call(name) === objectType) {
|
||||
extend(partials, name);
|
||||
extend(this.partials, name);
|
||||
} else {
|
||||
partials[name] = str;
|
||||
this.partials[name] = str;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
exports.registerHelper('helperMissing', function(arg) {
|
||||
function registerDefaultHelpers(instance) {
|
||||
instance.registerHelper('helperMissing', function(arg) {
|
||||
if(arguments.length === 2) {
|
||||
return undefined;
|
||||
} else {
|
||||
@@ -55,7 +56,7 @@ export function base(helpers, partials) {
|
||||
}
|
||||
});
|
||||
|
||||
exports.registerHelper('blockHelperMissing', function(context, options) {
|
||||
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||
|
||||
var type = toString.call(context);
|
||||
@@ -68,7 +69,7 @@ export function base(helpers, partials) {
|
||||
return inverse(this);
|
||||
} else if(type === "[object Array]") {
|
||||
if(context.length > 0) {
|
||||
return Handlebars.helpers.each(context, options);
|
||||
return instance.helpers.each(context, options);
|
||||
} else {
|
||||
return inverse(this);
|
||||
}
|
||||
@@ -77,7 +78,7 @@ export function base(helpers, partials) {
|
||||
}
|
||||
});
|
||||
|
||||
exports.registerHelper('each', function(context, options) {
|
||||
instance.registerHelper('each', function(context, options) {
|
||||
var fn = options.fn, inverse = options.inverse;
|
||||
var i = 0, ret = "", data;
|
||||
|
||||
@@ -112,34 +113,32 @@ export function base(helpers, partials) {
|
||||
return ret;
|
||||
});
|
||||
|
||||
exports.registerHelper('if', function(conditional, options) {
|
||||
instance.registerHelper('if', function(conditional, options) {
|
||||
var type = toString.call(conditional);
|
||||
if(type === functionType) { conditional = conditional.call(this); }
|
||||
|
||||
if(!conditional || Handlebars.Utils.isEmpty(conditional)) {
|
||||
if(!conditional || isEmpty(conditional)) {
|
||||
return options.inverse(this);
|
||||
} else {
|
||||
return options.fn(this);
|
||||
}
|
||||
});
|
||||
|
||||
exports.registerHelper('unless', function(conditional, options) {
|
||||
return Handlebars.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
|
||||
instance.registerHelper('unless', function(conditional, options) {
|
||||
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn});
|
||||
});
|
||||
|
||||
exports.registerHelper('with', function(context, options) {
|
||||
instance.registerHelper('with', function(context, options) {
|
||||
var type = toString.call(context);
|
||||
if(type === functionType) { context = context.call(this); }
|
||||
|
||||
if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
|
||||
if (!isEmpty(context)) return options.fn(context);
|
||||
});
|
||||
|
||||
exports.registerHelper('log', function(context, options) {
|
||||
instance.registerHelper('log', function(context, options) {
|
||||
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||
Handlebars.log(level, context);
|
||||
});
|
||||
|
||||
return exports;
|
||||
}
|
||||
|
||||
var levels = {
|
||||
|
||||
@@ -443,17 +443,17 @@ export function compile(input, options) {
|
||||
|
||||
var compiled;
|
||||
|
||||
function compile() {
|
||||
function compileInput() {
|
||||
var ast = parse(input);
|
||||
var environment = new Compiler().compile(ast, options);
|
||||
var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
|
||||
return template(templateSpec);
|
||||
return template(templateSpec, options.env || Handlebars, compile);
|
||||
}
|
||||
|
||||
// Template is only compiled on first use and cached after that point.
|
||||
return function(context, options) {
|
||||
if (!compiled) {
|
||||
compiled = compile();
|
||||
compiled = compileInput();
|
||||
}
|
||||
return compiled.call(this, context, options);
|
||||
};
|
||||
|
||||
@@ -3,17 +3,14 @@ import { COMPILER_REVISION, REVISION_CHANGES } from "./base";
|
||||
|
||||
// TODO: Remove this line and break up compilePartial
|
||||
|
||||
export function template(templateSpec, Hbars) {
|
||||
// TODO: Make this less global
|
||||
Hbars = Hbars || Handlebars;
|
||||
|
||||
if (Hbars.compile) {
|
||||
export function template(templateSpec, Hbars, compile) {
|
||||
if (compile) {
|
||||
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||
var result = invokePartial.apply(this, arguments);
|
||||
if (result) { return result; }
|
||||
|
||||
var options = { helpers: helpers, partials: partials, data: data };
|
||||
partials[name] = Hbars.compile(partial, { data: data !== undefined });
|
||||
partials[name] = compile(partial, { data: data !== undefined });
|
||||
return partials[name](context, options);
|
||||
};
|
||||
} else {
|
||||
@@ -24,6 +21,10 @@ export function template(templateSpec, Hbars) {
|
||||
};
|
||||
}
|
||||
|
||||
if (!Hbars) {
|
||||
throw new Error("YUNO HANDLEBARS");
|
||||
}
|
||||
|
||||
// Just add water
|
||||
var container = {
|
||||
escapeExpression: escapeExpression,
|
||||
@@ -56,9 +57,6 @@ export function template(templateSpec, Hbars) {
|
||||
return function(context, options) {
|
||||
options = options || {};
|
||||
|
||||
Hbars = Hbars || require("handlebars");
|
||||
|
||||
// TODO: Why does templateSpec require a reference to the global Handlebars?
|
||||
var result = templateSpec.call(container, Hbars, context, options.helpers, options.partials, options.data);
|
||||
|
||||
var compilerInfo = container.compilerInfo || [],
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
global.handlebarsEnv = null;
|
||||
|
||||
beforeEach(function() {
|
||||
global.handlebarsEnv = new Handlebars.HandlebarsEnvironment();
|
||||
});
|
||||
|
||||
describe("basic context", function() {
|
||||
it("most basic", function() {
|
||||
shouldCompileTo("{{foo}}", { foo: "foo" }, "foo");
|
||||
|
||||
Vendored
+5
-3
@@ -3,12 +3,14 @@ require('./common');
|
||||
global.Handlebars = require('../../zomg/lib/handlebars');
|
||||
|
||||
global.CompilerContext = {
|
||||
compile: function(template, options) {
|
||||
compile: function(template, options, env) {
|
||||
env = env || handlebarsEnv;
|
||||
var templateSpec = Handlebars.precompile(template, options);
|
||||
console.log(templateSpec);
|
||||
return Handlebars.template(eval('(' + templateSpec + ')'));
|
||||
return Handlebars.template(eval('(' + templateSpec + ')'), env);
|
||||
},
|
||||
compileWithPartial: function(template, options) {
|
||||
options = options || {};
|
||||
options.env = handlebarsEnv;
|
||||
return Handlebars.compile(template, options);
|
||||
}
|
||||
};
|
||||
|
||||
Vendored
+3
-3
@@ -5,11 +5,11 @@ global.Handlebars = require('../../dist/handlebars.runtime');
|
||||
var compiler = require('../../lib/handlebars');
|
||||
|
||||
global.CompilerContext = {
|
||||
compile: function(template, options) {
|
||||
compile: function(template, options, env) {
|
||||
var templateSpec = compiler.precompile(template, options);
|
||||
return Handlebars.template(eval('(' + templateSpec + ')'));
|
||||
return Handlebars.template(eval('(' + templateSpec + ')'), env);
|
||||
},
|
||||
compileWithPartial: function(template, options) {
|
||||
compileWithPartial: function(template, options, env) {
|
||||
return compiler.compile(template, options);
|
||||
}
|
||||
};
|
||||
|
||||
+5
-8
@@ -176,15 +176,12 @@ describe('helpers', function() {
|
||||
var helpers = Handlebars.helpers;
|
||||
try {
|
||||
Handlebars.helpers = {};
|
||||
Handlebars.registerHelper('if', helpers['if']);
|
||||
Handlebars.registerHelper('world', function() { return "world!"; });
|
||||
Handlebars.registerHelper('test_helper', function() { return 'found it!'; });
|
||||
|
||||
//Handlebars.registerHelper({
|
||||
//'if': helpers['if'],
|
||||
//world: function() { return "world!"; },
|
||||
//test_helper: function() { return 'found it!'; }
|
||||
//});
|
||||
Handlebars.registerHelper({
|
||||
'if': helpers['if'],
|
||||
world: function() { return "world!"; },
|
||||
test_helper: function() { return 'found it!'; }
|
||||
});
|
||||
|
||||
shouldCompileTo(
|
||||
"{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}",
|
||||
|
||||
Reference in New Issue
Block a user