diff --git a/README.md b/README.md index b547c72..810205c 100644 --- a/README.md +++ b/README.md @@ -36,10 +36,13 @@ a string or a number. ### If An "if:" section can contain other objects, but the entirety of -the section is only rendered if the current context scope contains the -current name, and the value associated with that name is "true" in a -boolean context. You might use to show someone's name, if the name -field is populated, and show nothing if it isn't. +the section is only rendered if the current context scope, and *only* +the current context scope, contains the current name, and the value +associated with that name is "true" in a boolean context. You might +use to show someone's name, if the name field is populated, and show +nothing if it isn't. This is useful for detecting if the current +context has a field, but you don't want previous contexts' synonyms +showing up. If your datasource returns: @@ -49,6 +52,12 @@ Then your template would use: {if:name}Hello {name}!{/if:name} +### When + +A "when:" section is the same as the "if", but it will render if +the current context scope, and any previous context scope on the +stack, contains the current name. + ### Block A "block:" section can contain other objects, but the entirety diff --git a/lib/lexer.js b/lib/lexer.js index e76a47c..9cc1dff 100644 --- a/lib/lexer.js +++ b/lib/lexer.js @@ -816,7 +816,7 @@ module.exports = (function() { var _VBT_LENGTH = _VALID_BLOCK_TYPES.length; function is_valid_block_type(b) { - for(i = 0; i < _VBT_LENGTH; i++) { + for(var i = 0; i < _VBT_LENGTH; i++) { if (_VALID_BLOCK_TYPES[i] == b) { return true; } diff --git a/lib/parser.js b/lib/parser.js index 4501832..457bf25 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -110,8 +110,15 @@ }; Contexter.prototype.render = function(name) { + var ret; if ((this.templates[name] != null) && _.isFunction(this.templates[name])) { - return this.templates[name](this); + this.depth++; + if (this.depth > 10) { + throw new Error('recursion-error'); + } + ret = this.templates[name](this); + this.depth--; + return ret; } else { return ""; } diff --git a/src/lexer.peg b/src/lexer.peg index 3e6b2be..54f5a5e 100644 --- a/src/lexer.peg +++ b/src/lexer.peg @@ -4,7 +4,7 @@ var _VBT_LENGTH = _VALID_BLOCK_TYPES.length; function is_valid_block_type(b) { - for(i = 0; i < _VBT_LENGTH; i++) { + for(var i = 0; i < _VBT_LENGTH; i++) { if (_VALID_BLOCK_TYPES[i] == b) { return true; } diff --git a/src/parser.coffee b/src/parser.coffee index 7197883..eb5050d 100644 --- a/src/parser.coffee +++ b/src/parser.coffee @@ -71,7 +71,14 @@ class Contexter return "" render: (name) -> - if @templates[name]? and _.isFunction(@templates[name]) then @templates[name](@) else "" + if @templates[name]? and _.isFunction(@templates[name]) + @depth++ + throw new Error('recursion-error') if @depth > 10 + ret = @templates[name](@) + @depth-- + ret + else + "" module.exports = (ast, data) ->