Skip to main content

A JavaScript template engine in just 20 lines.

/**
 * JavaScript template engine in just 20 lines.
 *
 * article: https://krasimirtsonev.com/blog/article/Javascript-template-engine-in-just-20-line
 * code: https://github.com/krasimir/absurd/blob/master/lib/processors/html/helpers/TemplateEngine.js
 *
 * @param {string} html
 * @param {object} options
 */
var TemplateEngine = function (html, options) {
  var re = /<%(.+?)%>/g,
    reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g,
    code = "with(obj) { var r=[];\n",
    cursor = 0,
    result,
    match;

  var add = function (line, js) {
    js
      ? (code += line.match(reExp) ? line + "\n" : "r.push(" + line + ");\n")
      : (code +=
          line != "" ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : "");
    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 = (code + 'return r.join(""); }').replace(/[\r\t\n]/g, " ");

  try {
    result = new Function("obj", code).apply(options, [options]);
  } catch (err) {
    console.error("'" + err.message + "'", " in \n\nCode:\n", code, "\n");
  }

  return result;
};

// Usage

var template =
  `Hello, my name is <%this.name%>. I'm <%this.profile.age%> years old.`;
console.log(
  TemplateEngine(template, {
    name: "Krasimir Tsonev",
    profile: { age: 29 },
  })
);

var template =
  "My skills: " +
  "<% for (var index in this.skills) { %>" +
    "<% this.skills[index] %>," +
  "<% } %>";
console.log(
  TemplateEngine(template, {
    skills: ["js", "html", "css"],
  })
);