Search code examples
javascripttemplatestemplatingclient-side-templatingtemplating-engine

JavaScript templating engine - Converting left hand ternary (without an assignment) into conditional statement(s)


I've found the perfect JavaScript templating engine, built by Krasimir, it is just what I needed.
The templating engine works great but naturally I couldn't resist the urge to hack at it a bit and maybe even add a couple of features.
Unfortunately I am having trouble understanding some of the code.

Here is the code:

var TemplateEngine = function(html, options) {
  var re = /<%([^%>]+)?%>/g,
    reExp = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g,
    code = 'var r=[];\n',
    cursor = 0,
    match;
  var add = function(line, js) {
    /* --begin problem  */
    js ? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') : (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
    /* --end problem    */
    return add;
  };
  while (match = re.exec(html)) {
    add(html.slice(cursor, match.index))(match[1], true);
    cursor = match.index + match[0].length;
  }
  add(html.substr(cursor, html.length - cursor));
  code += 'return r.join("");';
  return new Function(code.replace(/[\r\t\n]/g, '')).apply(options);
};

Here is the line I don't understand:

js ? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') : (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');

I'm not new to JavaScript but that's some weird looking code and from what I know it is a ternary operator without a left hand assignment (correct me if I'm wrong)

So in order to get a better understanding of what the author was doing I have attempted to convert the ternary operator into conditional statements.

This is what I have so far:

if(js) {
  if(code += line.match(reExp)) {
    line += '\n';
  } else {
    line += 'r.push(' + line + ');\n';
  }
} else {
  if(code += line !== '') {
    line += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
  } else {
    line += "";
  }
}

This failed and threw the error "Uncaught SyntaxError: Unexpected token if"

Can anybody help me convert this code into conditional statements and maybe even give me an explanation as to what the code does?

Also out of curiosity could anybody tell me if IE8 supports this code?
NOTE: I don't mind IE8 support I would just like to know if this templating engine supports IE8.

You can find the templating engine on Krasimir's Website or Krasimir's Github


Solution

  • I know this question has not gotten a lot of attention but I thought I'd post this answer anyways in hopes that it would help someone who is facing this problem.
    With some effort and a ton of help from JSHint I have figured out the solution to my question.
    I was appending the current compiled line to the "line" variable and not the "code" variable.
    This resulted with the "line" variable containing the last line of the template and the rest of the compiled code, meaning that the "code" variable had no code :D and was therefor equivalent to null.

    Here is the code I had before I figured out what I was doing wrong:

    var add = function(line, js) {
      if(js) {
        if(code += line.match(reExp)) {
          line += '\n';
        } else {
          line += 'r.push(' + line + ');\n';
        }
      } else {
        if(code += line !== '') {
          line += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
        } else {
          line += "";
        }
      }
    };
    

    After replacing the "line" variable with the "code" variable here and there and making a couple of optimisations here is the final working answer:

    var add = function(line, js) {
      if(js && typeof js !== "undefined") {
        if(line.match(reExp)) {
          code += line;
        } else {
          code += "r.push(" + line + ");";
        }
      } else if(line !== "") {
        code += "r.push(\"" + line.replace(/"/g, '\\"') + "\");";
      }
    };