Based on Chris's commit 4dc42864e0
with-js-extras
| @@ -37,6 +37,12 @@ Tags are always surrounded by mustaches like this `{{foobar}}`. | |||||
| template = "{{say_hello}}, {{name}}" | template = "{{say_hello}}, {{name}}" | ||||
| ### Dotted Tags | |||||
| Tags can also be nested to address object and array members in the context. | |||||
| var view = {name: {first: "Chris", last: "Anderson"}, values: [1, 2]}; | |||||
| template = "{{name.last}}, {{name.first}} {{values.0}}"; | |||||
| ### Conditional Sections | ### Conditional Sections | ||||
| Conditional sections begin with `{{#condition}}` and end with `{{/condition}}`. When `condition` evaluates to true, the section is rendered, otherwise the hole block will output nothing at all. `condition` may be a function returning true/false or a simple boolean. | Conditional sections begin with `{{#condition}}` and end with `{{/condition}}`. When `condition` evaluates to true, the section is rendered, otherwise the hole block will output nothing at all. `condition` may be a function returning true/false or a simple boolean. | ||||
| @@ -0,0 +1,3 @@ | |||||
| Yay {{person.name}}! | |||||
| Array style {{value.0}} {{value.1}} | |||||
| And {{more.nested.1.values}}! | |||||
| @@ -0,0 +1,10 @@ | |||||
| var nested = { | |||||
| person: { | |||||
| name: "Chris" | |||||
| }, | |||||
| ohyeah: "awesome!", | |||||
| value: ["is", function() {return this.ohyeah;}], | |||||
| more: { | |||||
| nested: [29, {values: "kbai"}] | |||||
| } | |||||
| }; | |||||
| @@ -0,0 +1,4 @@ | |||||
| Yay Chris! | |||||
| Array style is awesome! | |||||
| And kbai! | |||||
| @@ -0,0 +1 @@ | |||||
| Out of bounds! {{foo.5}} | |||||
| @@ -0,0 +1,3 @@ | |||||
| var nested_array_bounds = { | |||||
| foo: [1, 2] | |||||
| }; | |||||
| @@ -0,0 +1 @@ | |||||
| ERROR: 'foo.5' not found in context | |||||
| @@ -0,0 +1 @@ | |||||
| This doesn't exist: {{foo.bar}} | |||||
| @@ -0,0 +1 @@ | |||||
| var nested_error = {not_foo: {not_bar: "yay error!"}}; | |||||
| @@ -0,0 +1 @@ | |||||
| ERROR: 'foo.bar' not found in context | |||||
| @@ -130,11 +130,12 @@ var Mustache = function() { | |||||
| */ | */ | ||||
| find: function(name, context) { | find: function(name, context) { | ||||
| name = this.trim(name); | name = this.trim(name); | ||||
| if(typeof context[name] === "function") { | |||||
| return context[name].apply(context); | |||||
| var value = this.getValue(context, name); | |||||
| if(typeof value === "function") { | |||||
| return value.apply(context); | |||||
| } | } | ||||
| if(context[name] !== undefined) { | |||||
| return context[name]; | |||||
| if(value !== undefined) { | |||||
| return value; | |||||
| } | } | ||||
| throw({message: "'" + name + "' not found in context"}); | throw({message: "'" + name + "' not found in context"}); | ||||
| }, | }, | ||||
| @@ -157,6 +158,22 @@ var Mustache = function() { | |||||
| }); | }); | ||||
| }, | }, | ||||
| getValue: function(context, name) { | |||||
| if(name == "." && context[name] != undefined) { | |||||
| return context[name]; | |||||
| } | |||||
| var ctx = context; | |||||
| var parts = name.split("."); | |||||
| while(parts.length) { | |||||
| p = parts.shift(); | |||||
| if(ctx[p] === undefined) { | |||||
| throw({message: "'" + name + "' not found in context"}); | |||||
| } | |||||
| ctx = ctx[p]; | |||||
| } | |||||
| return ctx | |||||
| }, | |||||
| /* | /* | ||||
| Merges all properties of object `b` into object `a`. | Merges all properties of object `b` into object `a`. | ||||
| `b.property` overwrites a.property` | `b.property` overwrites a.property` | ||||