Merge branch 'master' of http://github.com/wycats/handlebars.js
This commit is contained in:
+6
-1
@@ -112,9 +112,14 @@ Known Issues
|
||||
------------
|
||||
* Handlebars.js can be a bit cryptic when there's an error during compilation, and it can be even more cryptic when there's an error while rendering.
|
||||
|
||||
Handlebars Contrib
|
||||
------------------
|
||||
Alan Johnson, a.k.a. commondream, keeps a repository of useful helpers in the [handlebars-contrib](http://github.com/commondream/handlebars-contrib) repository. Feel free to copy those, or add some of your own.
|
||||
|
||||
Handlebars in the Wild
|
||||
-----------------
|
||||
* Don Park wrote an Express.js view engine adapter for Handlebars called [hbs](http://github.com/donpark/hbs)
|
||||
* Don Park wrote an Express.js view engine adapter for Handlebars.js called [hbs](http://github.com/donpark/hbs)
|
||||
* [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey, supports Handlebars.js as one of its template plugins.
|
||||
|
||||
Helping Out
|
||||
-----------
|
||||
|
||||
+19
-16
@@ -4,7 +4,7 @@ var Handlebars = {
|
||||
compile: function(string) {
|
||||
if (Handlebars.compilerCache[string] == null) {
|
||||
var fnBody = Handlebars.compileFunctionBody(string);
|
||||
var fn = new Function("context", "fallback", "Handlebars", fnBody);
|
||||
var fn = new Function("context", "fallback", "Handlebars", fnBody);
|
||||
Handlebars.compilerCache[string] =
|
||||
function(context, fallback) { return fn(context, fallback, Handlebars); };
|
||||
}
|
||||
@@ -76,7 +76,9 @@ var Handlebars = {
|
||||
return compiled;
|
||||
},
|
||||
|
||||
evalExpression: function(path, context, stack) {
|
||||
evalExpression: function(path, context, stack, fallback) {
|
||||
fallback = fallback || {};
|
||||
|
||||
var parsedPath = Handlebars.parsePath(path);
|
||||
var depth = parsedPath[0];
|
||||
var parts = parsedPath[1];
|
||||
@@ -86,10 +88,14 @@ var Handlebars = {
|
||||
context = stack[stack.length - depth];
|
||||
}
|
||||
|
||||
for (var i = 0; i < parts.length && context !== undefined; i++) {
|
||||
for (var i = 0; i < parts.length && typeof context !== "undefined"; i++) {
|
||||
context = context[parts[i]];
|
||||
}
|
||||
|
||||
|
||||
if (parts.length == 1 && typeof context === "undefined") {
|
||||
return fallback[parts[0]];
|
||||
}
|
||||
|
||||
return context;
|
||||
},
|
||||
|
||||
@@ -151,8 +157,10 @@ var Handlebars = {
|
||||
isEmpty: function(value) {
|
||||
if (typeof value === "undefined") {
|
||||
return true;
|
||||
} else if (!value) {
|
||||
} else if (value === null) {
|
||||
return true;
|
||||
} else if (value === false) {
|
||||
return true;
|
||||
} else if(Object.prototype.toString.call(value) === "[object Array]" && value.length == 0) {
|
||||
return true;
|
||||
} else {
|
||||
@@ -345,17 +353,12 @@ Handlebars.Compiler.prototype = {
|
||||
},
|
||||
|
||||
lookupFor: function(param) {
|
||||
var parsed = Handlebars.parsePath(param);
|
||||
var depth = parsed[0];
|
||||
var parts = parsed[1];
|
||||
|
||||
if (depth > 0 || parts.length > 1) {
|
||||
return "(Handlebars.evalExpression('" + param + "', context, stack))";
|
||||
} else if (parts.length == 1) {
|
||||
return "(context['" + parts[0] + "'] || fallback['" + parts[0] + "'])";
|
||||
} else {
|
||||
return "(context || fallback)";
|
||||
}
|
||||
if (typeof param === "undefined") {
|
||||
return "context";
|
||||
}
|
||||
else {
|
||||
return "(Handlebars.evalExpression('" + param + "', context, stack, fallback))";
|
||||
}
|
||||
},
|
||||
|
||||
compileToEndOfBlock: function(mustache) {
|
||||
|
||||
+13
-2
@@ -40,6 +40,13 @@ test("boolean", function() {
|
||||
"booleans do not show the contents when false");
|
||||
});
|
||||
|
||||
test("zeros", function() {
|
||||
shouldCompileTo("num1: {{num1}}, num2: {{num2}}", {num1: 42, num2: 0},
|
||||
"num1: 42, num2: 0");
|
||||
shouldCompileTo("num: {{.}}", 0, "num: 0");
|
||||
shouldCompileTo("num: {{num1/num2}}", {num1: {num2: 0}}, "num: 0");
|
||||
});
|
||||
|
||||
test("newlines", function() {
|
||||
shouldCompileTo("Alan's\nTest", {}, "Alan's\nTest");
|
||||
shouldCompileTo("Alan's\rTest", {}, "Alan's\rTest");
|
||||
@@ -94,16 +101,20 @@ test("nested paths with empty string value", function() {
|
||||
});
|
||||
|
||||
test("bad idea nested paths", function() {
|
||||
var hash = {goodbyes: [{text: "goodbye"}, {text: "Goodbye"}, {text: "GOODBYE"}], world: "world"};
|
||||
shouldThrow(function() {
|
||||
Handlebars.compile("{{#goodbyes}}{{../name/../name}}{{/goodbyes}}");
|
||||
Handlebars.compile("{{#goodbyes}}{{../name/../name}}{{/goodbyes}}")(hash);
|
||||
}, Handlebars.Exception,
|
||||
"Cannot jump (..) into previous context after moving into a context.");
|
||||
|
||||
var string = "{{#goodbyes}}{{.././world}} {{/goodbyes}}";
|
||||
var hash = {goodbyes: [{text: "goodbye"}, {text: "Goodbye"}, {text: "GOODBYE"}], world: "world"};
|
||||
shouldCompileTo(string, hash, "world world world ", "Same context (.) is ignored in paths");
|
||||
});
|
||||
|
||||
test("that current context path ({{.}}) doesn't hit fallback", function() {
|
||||
shouldCompileTo("test: {{.}}", [null, {helper: "awesome"}], "test: ");
|
||||
});
|
||||
|
||||
test("complex but empty paths", function() {
|
||||
shouldCompileTo("{{person/name}}", {person: {name: null}}, "");
|
||||
shouldCompileTo("{{person/name}}", {person: {}}, "");
|
||||
|
||||
Reference in New Issue
Block a user