diff --git a/README.md b/README.md index 4867971..c21a455 100644 --- a/README.md +++ b/README.md @@ -259,6 +259,19 @@ var output = tmpl.render(context); /// output == "1 2 3 4 " ``` +#### Iterating an array of objects shorthand. #### + +If you pass an array of objects to Combyne, you may iterate it via a shorthand: + +``` javascript +var template = "{%each%}{{foo}} {%endeach%}"; +var context = [{ foo: 1 }, { foo: 2 }, { foo: 3 }, { foo: 4 }]; + +var tmpl = combyne(template); + +var output = tmpl.render(context); +/// output == "1 2 3 4 " + #### Change the iterated identifer within loops. #### ``` javascript diff --git a/lib/compiler.js b/lib/compiler.js index 5e728a4..94e5fd9 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -263,22 +263,29 @@ define(function(require, exports, module) { * @return {string} The compiled JavaScript source string value. */ Compiler.prototype.compileLoop = function(node) { + var conditions = node.conditions || []; + var keyVal = [ // Key - (node.conditions[3] ? node.conditions[3].value : "i"), + (conditions[3] ? conditions[3].value : "i"), // Value. - (node.conditions[2] ? node.conditions[2].value : ".") + (conditions[2] ? conditions[2].value : ".") ]; + // Normalize the value to the condition if it exists. + var value = conditions.length && conditions[0].value; + + // Construct the loop, utilizing map because it will return back the + // template as an array and ready to join into the template. var loop = [ - "map(", normalizeIdentifier(node.conditions[0].value), ",", + "map(", value ? normalizeIdentifier(value) : "data", ",", // Index keyword. "'", keyVal[0], "'", ",", // Value keyword. - "'", keyVal[1], "'", ",", + "'", value ? keyVal[1] : "", "'", ",", // Outer scope data object. "data", ",", diff --git a/lib/shared/map.js b/lib/shared/map.js index 7cb69a3..36ce028 100644 --- a/lib/shared/map.js +++ b/lib/shared/map.js @@ -41,7 +41,14 @@ define(function(require, exports, module) { // Create a new scoped data object. dataObject = createObject(data); dataObject[index] = i; - dataObject[value] = obj[i]; + + if (value) { + dataObject[value] = obj[i]; + } + // If no value was supplied, use this object to key off of. + else { + dataObject = obj[i]; + } // Add return value of iterator function to output. output.push(iterator(dataObject)); @@ -59,7 +66,14 @@ define(function(require, exports, module) { // Create a new scoped data object. dataObject = createObject(data); dataObject[index] = key; - dataObject[value] = obj[key]; + + if (value) { + dataObject[value] = obj[key]; + } + // If no value was supplied, use this object to key off of. + else { + dataObject = obj[key]; + } // Add return value of iterator function to output. output.push(iterator(dataObject)); diff --git a/test/tests/expressions.js b/test/tests/expressions.js index 96f4931..99ccab5 100644 --- a/test/tests/expressions.js +++ b/test/tests/expressions.js @@ -297,6 +297,13 @@ define(function(require, exports, module) { assert.equal(output, "value"); }); + + it("can scope lookups to context object", function() { + var tmpl = combyne("{%each%}{{key}}{%endeach%}"); + var output = tmpl.render([{key:"value"}]); + + assert.equal(output, "value"); + }); }); describe("object loop", function() {