From 9fcd85bbac33c643efa02c3a144c0a50e25d13cc Mon Sep 17 00:00:00 2001 From: wycats Date: Sat, 11 Dec 2010 18:43:58 -0800 Subject: [PATCH] Allow helperMissing to apply to simple mustaches (paves the way to support things like link_to in a Rails context) --- lib/handlebars.js | 2 +- lib/handlebars/runtime.js | 21 ++++++++++++++++----- spec/qunit_spec.js | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lib/handlebars.js b/lib/handlebars.js index 3d85b22b..df16cae4 100644 --- a/lib/handlebars.js +++ b/lib/handlebars.js @@ -54,7 +54,7 @@ Handlebars.registerPartial = function(name, str) { this.partials[name] = str; }; -Handlebars.registerHelper('helperMissing', function(context, fn) { +Handlebars.registerHelper('blockHelperMissing', function(context, fn) { var ret = ""; if(context === true) { diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js index b58ba241..e091b99e 100644 --- a/lib/handlebars/runtime.js +++ b/lib/handlebars/runtime.js @@ -113,11 +113,22 @@ Handlebars.Runtime.prototype = { params[i] = this[param.type](param).data; } - if(toString.call(idObj.data) === "[object Function]") { - buf = idObj.data.apply(this.wrapContext(), params); + var data = idObj.data; + + var type = toString.call(data); + var functionType = (type === "[object Function]"); + + if(!functionType && params.length) { + params = params.slice(0); + params.unshift(data || mustache.id.original); + data = this.context.helpers.helperMissing; + functionType = true; + } + + if(functionType) { + buf = data.apply(this.wrapContext(), params); } else { - if(params.length) { throw new Error(mustache.id.parts.join("/") + " is not a Function, so you cannot have Function parameters"); } - buf = idObj.data; + buf = data; } if(buf && mustache.escaped) { buf = Handlebars.Utils.escapeExpression(buf); } @@ -136,7 +147,7 @@ Handlebars.Runtime.prototype = { if(toString.call(data) !== "[object Function]") { params = [data]; - data = this.context.helpers.helperMissing; + data = this.context.helpers.blockHelperMissing; } else { params = this.evaluateParams(mustache.params); } diff --git a/spec/qunit_spec.js b/spec/qunit_spec.js index dee88919..5ccc4578 100644 --- a/spec/qunit_spec.js +++ b/spec/qunit_spec.js @@ -1,5 +1,11 @@ module("basic context"); +Handlebars.registerHelper('helperMissing', function(helper, context) { + if(helper === "link_to") { + return new Handlebars.SafeString("" + context + ""); + } +}); + var shouldCompileTo = function(string, hash, expected, message) { var template = Handlebars.compile(string); if(Object.prototype.toString.call(hash) === "[object Array]") { @@ -459,3 +465,11 @@ test("constructing a safestring from a string and checking its type", function() equal(safe, "testing 1, 2, 3", "SafeString is equivalent to its underlying string"); }); +module("helperMissing"); + +test("if a context is not found, helperMissing is used", function() { + var string = "{{hello}} {{link_to world}}" + var context = { hello: "Hello", world: "world" }; + + shouldCompileTo(string, context, "Hello world") +})