diff --git a/README.md b/README.md index 8a42525..caddc41 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ Jazz is a simple template engine built specifically for nodejs. +This is a fork of the original Jazz templating engine which is hosted here: [Shinetech Jazz templating engine](https://github.com/shinetech/jazz) +This fork enhances the templating engine by asynchronous conditional statements. + # Usage var jazz = require("jazz"); @@ -63,7 +66,7 @@ result. e.g. here we simulate a blocking operation using setTimeout(). Note that even though the execution of the callback is delayed, this example still works. -## Conditional Statements +## Conditional Statements (synchronous) You can check if a variable evaluates to a true value like so: @@ -119,6 +122,61 @@ You can also group expressions using parentheses: ... {end} +## Conditional Statements (asynchronous) + +With _when_ it's possible to call an externel function to check if a certain part shall be included or not. + + // condition.jazz + + {when isStringFoo("foo")} + The parameter is foo. + {end} + + // condition.js + + var jazz = require("jazz"); + + var params = { + isStringFoo: function(arg1, cb) { + cb(arg1 == "foo"); + } + } + + jazz.compile("condition.jazz").eval(params, function(output) { console.log(output); }); + +You can use _otherwise_ to include another part when the check returns false. + + {when isStringFoo("bar")} + The parameter is foo. + {otherwhise} + The parameter is NOT foo. + {end} + +It's also possible to check on false + + {when not isStringFoo("bar")} + The parameter is NOT foo. + {end} + +Or to combine _not_ and _otherwise_ + + {when not isStringFoo("bar")} + The parameter is NOT foo. + {otherwise} + The parameter IS foo. + {end} + +As it is already possible to encapsulate expression, this aspect can also be applied here without restriction. + + {when isStringFoo("foo")} + The parameter is NOT foo. {someVariable} +
{pair.key} = {pair.value}
{end} - + ## Synchronous functions {if @blah('a')} @@ -150,8 +208,7 @@ The function is provided to the template the same way asynchronous functions areIndex (0 based): {__index}
{pair.key} = {pair.value}
{end} - + ## Looking into arrays/objects{object['array'][0].cheese}
- diff --git a/lib/jazz/ast.js b/lib/jazz/ast.js index 00cdcbe..c5447c2 100644 --- a/lib/jazz/ast.js +++ b/lib/jazz/ast.js @@ -46,6 +46,18 @@ IfStmt.prototype.toString = function() { return "IfStmt(" + this.expr.toString() + ", " + this.suite.toString() + ", " + (this.orelse ? this.orelse.toString() : "null") + ")"; } +function WhenStmt(expr, suite, orelse) { + this.type = "jazz.ast.WhenStmt"; + this.expr = expr; + this.suite = suite; + this.orelse = orelse; + return this; +} + +WhenStmt.prototype.toString = function() { + return "When(" + this.expr.toString() + ", " + this.suite.toString() + ", " + (this.orelse ? this.orelse.toString() : "null") + ")"; +} + function ForEach(ident, expr, suite) { this.type = "jazz.ast.ForEach"; this.ident = ident; @@ -203,6 +215,7 @@ GetArr.prototype.toString = function() { exports.Suite = Suite; exports.Ident = Ident; exports.IfStmt = IfStmt; +exports.WhenStmt = WhenStmt; exports.Echo = Echo; exports.ForEach = ForEach; exports.GetAttr = GetAttr; diff --git a/lib/jazz/compiler.js b/lib/jazz/compiler.js index 96fb36e..16017c6 100644 --- a/lib/jazz/compiler.js +++ b/lib/jazz/compiler.js @@ -145,6 +145,9 @@ Compiler_JS.prototype._compileStatement = function(stmt) { if (stmt.constructor == ast.IfStmt) { code += this._compileIfStmt(stmt); } + else if (stmt.constructor == ast.WhenStmt) { + code += this._compileWhenStmt(stmt); + } else if (stmt.constructor == ast.ForEach) { code += this._compileForEach(stmt); } @@ -202,6 +205,32 @@ Compiler_JS.prototype._compileIfStmt = function(stmt) { return code; } +Compiler_JS.prototype._compileWhenStmt = function(stmt) { + var code = ""; + + code += "(" + this._compileExpr(stmt.expr.expr) + ")("; + for (var i = 0; i < stmt.expr.args.length; i++) { + code += this._compileExpr(stmt.expr.args[i]); + code += ", "; + } + code += "function(conditionCheckResult) { "; + if(stmt.expr.negateResult) + { + code += "if(!(conditionCheckResult == true))"; + } + else + { + code += "if(conditionCheckResult == true)"; + } + code += this._compileSuite(stmt.suite); + if (stmt.otherwise) { + code += " else " + this._compileStatement(stmt.otherwise); + } + code += "});\n"; + + return code; +} + Compiler_JS.prototype._compileForEach = function(stmt) { var exprVar = this._newVar(); var indexVar = this._newVar(); diff --git a/lib/jazz/parser.js b/lib/jazz/parser.js index 2562060..27d35e8 100644 --- a/lib/jazz/parser.js +++ b/lib/jazz/parser.js @@ -231,6 +231,11 @@ Parser.prototype._parseSuite = function() { body.push(this._parseIfStmt()); break; } + case tokens.WHEN: + { + body.push(this._parseWhenStmt()); + break; + } case tokens.ECHO: { body.push(this._parseEcho()); @@ -278,6 +283,27 @@ Parser.prototype._parseIfStmt = function() { return root; } +Parser.prototype._parseWhenStmt = function() { + this._expect(tokens.WHEN); + var negateResult = false + if(this.current().type == tokens.NOT) + { + this._expect(tokens.NOT); + negateResult = true; + } + var expr = this._parseEchoExpr(); + expr.negateResult = negateResult; + var suite = this._parseSuite(); + var root = new ast.WhenStmt(expr, suite); + var ref = root; + if (this.current().type === tokens.OTHERWISE) { + this._expect(tokens.OTHERWISE); + ref.otherwise = this._parseSuite(); + } + this._expect(tokens.END); + return root; +} + Parser.prototype._parseEcho = function() { var value = this._check(tokens.ECHO).value; this.next(); diff --git a/lib/jazz/scanner.js b/lib/jazz/scanner.js index 73db2ec..7fcb9b1 100644 --- a/lib/jazz/scanner.js +++ b/lib/jazz/scanner.js @@ -313,6 +313,16 @@ Scanner.prototype._codeState = function() { step(2); break; } + else if (keyword("when", s, i)) { + result = this._makeToken(tokens.WHEN); + step(4); + break; + } + else if (keyword("otherwise", s, i)) { + result = this._makeToken(tokens.OTHERWISE); + step(9); + break; + } else if (keyword("elif", s, i)) { result = this._makeToken(tokens.ELIF); step(4); diff --git a/lib/jazz/tokens.js b/lib/jazz/tokens.js index a6a9d27..ba4f669 100644 --- a/lib/jazz/tokens.js +++ b/lib/jazz/tokens.js @@ -9,6 +9,8 @@ exports.ECHO = TOKEN_PREFIX + "ECHO"; exports.IF = TOKEN_PREFIX + "IF"; exports.ELIF = TOKEN_PREFIX + "ELIF"; exports.ELSE = TOKEN_PREFIX + "ELSE"; +exports.WHEN = TOKEN_PREFIX + "WHEN"; +exports.OTHERWISE = TOKEN_PREFIX + "OTHERWISE"; exports.FOREACH = TOKEN_PREFIX + "FOREACH"; exports.IN = TOKEN_PREFIX + "IN"; exports.AND = TOKEN_PREFIX + "AND";