diff --git a/examples/helpers.html b/examples/helpers.html
new file mode 100644
index 0000000..ad3d792
--- /dev/null
+++ b/examples/helpers.html
@@ -0,0 +1,2 @@
+Hi {{name}}.
+Hi {{ucase name}}.
diff --git a/examples/helpers.js b/examples/helpers.js
new file mode 100644
index 0000000..a6b1c00
--- /dev/null
+++ b/examples/helpers.js
@@ -0,0 +1,8 @@
+var helpers_helpers = {
+ ucase: function(s) {return s.toUpperCase(); }
+};
+
+var helpers = {
+ name: "Chris"
+};
+
diff --git a/examples/helpers.txt b/examples/helpers.txt
new file mode 100644
index 0000000..43ceaa2
--- /dev/null
+++ b/examples/helpers.txt
@@ -0,0 +1,2 @@
+Hi Chris.
+Hi CHRIS.
diff --git a/examples/helpers_error.html b/examples/helpers_error.html
new file mode 100644
index 0000000..5a499cc
--- /dev/null
+++ b/examples/helpers_error.html
@@ -0,0 +1,3 @@
+Hi {{name}}.
+Hi {{ucase name}}.
+Hi {{lcase name}}.
diff --git a/examples/helpers_error.js b/examples/helpers_error.js
new file mode 100644
index 0000000..92e955e
--- /dev/null
+++ b/examples/helpers_error.js
@@ -0,0 +1,8 @@
+var helpers_error_helpers = {
+ ucase: function(s) {return s.toUpperCase(); }
+};
+
+var helpers_error = {
+ name: "Chris"
+};
+
diff --git a/examples/helpers_error.txt b/examples/helpers_error.txt
new file mode 100644
index 0000000..44b4e05
--- /dev/null
+++ b/examples/helpers_error.txt
@@ -0,0 +1 @@
+ERROR: Helper 'lcase' is not a registered helper
diff --git a/mustache.js b/mustache.js
index 5677871..44cf00d 100644
--- a/mustache.js
+++ b/mustache.js
@@ -13,6 +13,7 @@ var Mustache = function() {
ctag: "}}",
pragmas: {},
buffer: [],
+ helper_functions: {},
pragmas_implemented: {
"IMPLICIT-ITERATOR": true
},
@@ -269,7 +270,22 @@ var Mustache = function() {
}
var value;
-
+ var helper;
+
+ // check for helper e.g. name = "helperfun name"
+ var helper_name = name.split(" ");
+ if(helper_name.length == 2) { // we have a helper
+ helper = helper_name[0];
+ name = helper_name[1];
+ if(!this.helper_functions[helper]
+ || typeof this.helper_functions[helper] != "function") {
+ throw {message:
+ "Helper '" + helper + "' is not a registered helper"};
+ } else {
+ helper = this.helper_functions[helper];
+ }
+ }
+
// check for dot notation eg. foo.bar
if(name.match(/([a-z_]+)\./ig)){
var childValue = this.walk_context(name, context);
@@ -286,8 +302,13 @@ var Mustache = function() {
}
if(typeof value === "function") {
- return value.apply(context);
+ value = value.apply(context);
}
+
+ if(helper) {
+ value = helper.apply(context, [value]);
+ }
+
if(value !== undefined) {
return value;
}
@@ -408,11 +429,14 @@ var Mustache = function() {
/*
Turns a template and view into HTML
*/
- to_html: function(template, view, partials, send_fun) {
- var renderer = new Renderer();
+ to_html: function(template, view, partials, send_fun, helpers) {
+ var renderer = new Renderer(helpers);
if(send_fun) {
renderer.send = send_fun;
}
+ if(helpers) {
+ renderer.helper_functions = helpers;
+ }
renderer.render(template, view || {}, partials);
if(!send_fun) {
return renderer.buffer.join("\n");
diff --git a/test/mustache_spec.rb b/test/mustache_spec.rb
index 5ce8bea..67cc2ea 100644
--- a/test/mustache_spec.rb
+++ b/test/mustache_spec.rb
@@ -84,9 +84,10 @@ describe "mustache" do
runner = <<-JS
try {
#{@boilerplate}
+ var #{testname}_helpers = null;
#{view}
var template = #{template};
- var result = Mustache.to_html(template, #{testname});
+ var result = Mustache.to_html(template, #{testname}, null, null, #{testname}_helpers);
print(result);
} catch(e) {
print('ERROR: ' + e.message);
@@ -102,6 +103,7 @@ describe "mustache" do
runner = <<-JS
try {
#{@boilerplate}
+ var #{testname}_helpers = null;
#{view}
var chunks = [];
var sendFun = function(chunk) {
@@ -110,7 +112,7 @@ describe "mustache" do
}
}
var template = #{template};
- Mustache.to_html(template, #{testname}, null, sendFun);
+ Mustache.to_html(template, #{testname}, null, sendFun, #{testname}_helpers);
print(chunks.join("\\n"));
} catch(e) {
print('ERROR: ' + e.message);
@@ -132,10 +134,11 @@ describe "mustache" do
runner = <<-JS
try {
#{@boilerplate}
+ var #{testname}_helpers = null;
#{view}
var template = #{template};
var partials = {"partial": #{partial}};
- var result = Mustache.to_html(template, partial_context, partials);
+ var result = Mustache.to_html(template, partial_context, partials, null, #{testname}_helpers);
print(result);
} catch(e) {
print('ERROR: ' + e.message);
@@ -152,7 +155,8 @@ describe "mustache" do
runner = <<-JS
try {
#{@boilerplate}
- #{view};
+ var #{testname}_helpers = null;
+ #{view}
var template = #{template};
var partials = {"partial": #{partial}};
var chunks = [];
@@ -161,7 +165,7 @@ describe "mustache" do
chunks.push(chunk);
}
}
- Mustache.to_html(template, partial_context, partials, sendFun);
+ Mustache.to_html(template, partial_context, partials, sendFun, #{testname}_helpers);
print(chunks.join("\\n"));
} catch(e) {
print('ERROR: ' + e.message);