class TemplateEngine { constructor(tpl, adminData) { this.tpl = tpl; this.adminData = adminData; this.modeFallback = { ":EDIT": ":ADMIN", ":ADMIN": "", "": null }; } Render(content, marker, mode = "") { return this.render(marker, content, this.extractSection(this.tpl, marker, mode), mode); } render(sections, content, tpl, mode = "") { // content has to be an object of `marker` => `data` // data can be a primitive, an array, or an object // Boolean corresponds to a conditional section, call replaceCondition // String and number correspond to a simple marker, call replaceMarker for it // Array and object always correspond to a section // Object can be handed recursively to a new instance of render. Be sure to extract the correct section of tpl though // If data is an array, iterate over it and hand every entry to a new instance like with object. Concatenate the results if (typeof(content)!="object" || tpl=="") return ""; var ret = tpl; for (var marker in content) { var sectionMarker = (sections!="" ? sections+"."+marker : marker); var type = typeof(content[marker]); if (mode==":EDIT" && sections.indexOf("MAIN")!=-1 && typeof(this.adminData[marker])!="undefined") { var data = this.adminData[marker]; var admin_tpl = this.extractSection(ret, sectionMarker, mode); var admin_ret = ""; for (var i in data) { if (content[marker]==null) { data[i].SELECTED = data[i].ID=="__NULL__"; } else if (Array.isArray(content[marker])) { var selected = false; for (var j in content[marker]) { if (data[i].ID==content[marker][j].ID) { selected = true; } } data[i].SELECTED = selected; } else { data[i].SELECTED = data[i].ID==content[marker].ID; } admin_ret+= this.render(sectionMarker, data[i], admin_tpl, ""); } ret = this.replaceSection(ret, sectionMarker, admin_ret, ""); } else { if (content[marker]==null) { ret = this.replaceSection(ret, sectionMarker, "", mode); ret = this.replaceMarker(ret, sectionMarker, "__NULL__", mode); } if (type=="boolean") { ret = this.replaceCondition(ret, sectionMarker, content[marker], mode); } else if (type=="string" && "__CASE__:"==content[marker].substr(0, 9)) { ret = this.replaceSwitch(ret, sectionMarker, content[marker].split(":"), mode); } else if (type=="string" || type=="number") { ret = this.replaceMarker(ret, sectionMarker, content[marker], mode); } else if (type=="object" && Array.isArray(content[marker])) { var arr_tpl = this.extractSection(ret, sectionMarker, mode); var arr_ret = ""; for (var ind in content[marker]) { arr_ret+= this.render(sectionMarker, content[marker][ind], arr_tpl, mode); } ret = this.replaceSection(ret, sectionMarker, arr_ret, mode); } else if (type=="object") { // Hopefully a JSON ret = this.replaceSection(ret, sectionMarker, this.render(sectionMarker, content[marker], this.extractSection(ret, sectionMarker, mode), mode), mode); } } } return ret; } makeMarker(marker) { return "###" + marker + "###"; } makeSectionMarker(marker, pos) { //creates START or END marker of section return ""; } findMarkerModes(tpl, section) { var ret = []; var sectionMarker = this.makeMarker(section+":"); var markerLength = 5 + sectionMarker.length - 3; // 5 = " // True text // // False text // var modeTpl = this.findAndDeleteUnneededModes(tpl, section, mode); var sectionMarker = this.makeMarker(section + modeTpl.mode); var ifMarker = this.makeSectionMarker(sectionMarker, "IF"); var elseMarker = this.makeSectionMarker(sectionMarker, "ELSE"); var endMarker = this.makeSectionMarker(sectionMarker, "END"); var startPos = modeTpl.tpl.indexOf(ifMarker); var else_startPos = modeTpl.tpl.indexOf(elseMarker); var else_endPos = else_startPos + elseMarker.length; var endPos = modeTpl.tpl.lastIndexOf(endMarker) + endMarker.length; if ((startPos==-1) || (else_startPos==-1) || (endPos==-1) || (endPos<=startPos)) { if (bool) { return modeTpl.tpl; } else { return this.replaceSection(modeTpl.tpl, section, "", modeTpl.mode); } } var value = ""; if (bool) { // Show if-part value = modeTpl.tpl.substr(startPos, else_startPos - startPos); } else { // Show else-part value = modeTpl.tpl.substr(else_endPos, endPos - else_endPos - endMarker.length); } var ret = (startPos>0 ? modeTpl.tpl.substr(0, startPos) : ""); ret+= value; if (endPos // Default text // // Text A // // Text B // var modeTpl = this.findAndDeleteUnneededModes(tpl, section, mode); var sectionMarker = this.makeMarker(section + modeTpl.mode); var switchMarker = this.makeSectionMarker(sectionMarker, "SWITCH"); var endMarker = this.makeSectionMarker(sectionMarker, "END"); var anyMarker = this.makeSectionMarker(sectionMarker, "").substr(0, 5 + sectionMarker.length); // 5 = "