UNPKG

maki-template

Version:

HTML-Style Express.js rendering engine

115 lines (113 loc) 2.71 kB
var fs = require("fs"); var cheerio = require("cheerio"); var clone = require("clone"); var path = require("path"); var minify = require("html-minifier").minify; var es = require("./lib/html-escape"); var viewPath = "./views"; function getValue(scope, attr) { with(scope) { var res; try { res = eval(es.unEscape(attr)); } catch (er) { res = ''; } finally { return res; } } } function format(str, data) { return minify(str.replace(/[{]{2}(.+?)[}]{2}/g, function (attr) { return es.escape(getValue(data, attr)); }), {removeComments: true}); } exports.render = function (str, data, callback, viewContent) { try { var $ = cheerio.load(str); $("maki-if,maki-switch,maki-each").each(function () { var th = $(this); switch(this.name) { case "maki-if": if(!getValue(data, th.attr("cond"))) { th.remove(); } else { th.replaceWith(th.children()); } break; case "maki-switch": var res = th.find("maki-case[value=" + getValue(data, th.attr("target")) + "]"); if(res.length) { th.replaceWith(res.contents()); } else { th.replaceWith(th.find("maki-default").children()); } break; case "maki-each": var target = getValue(data, th.attr("target")); var name = th.attr("value"); var result = ""; var targetLength = target.length; var copyData = clone(data); for(var i = 0;i < targetLength;i++) { copyData[name] = target[i]; exports.render(th.html(), copyData, function (err, res) { result += res; }); } th.replaceWith(result); break; // TODO need additional parsing } }); if($("maki-view").length) { if(viewContent) { $("maki-view").replaceWith(viewContent); } else { $("maki-view").remove(); } } if($("maki-layout").length) { var layoutSrc = $("maki-layout").attr("src"); $("maki-layout").remove(); if(!data.ignoreLayout) { exports.renderFile(layoutSrc, data, function (err, res) { callback(null, res); }, format($.html(), data)); return null; } else { return callback(null, format($.html(), data)); } } else { return callback(null, format($.html(), data)); } } catch (er) { return callback(er); } }; exports.renderFile = function (src, data, callback, viewContent) { if(src.split(".").length < 1) { src += ".maki"; } fs.readFile(path.resolve(viewPath, src), function (err, dat) { if(!err) { exports.render(dat, data, callback, viewContent); } else { callback(err); } }); }; exports.__express = exports.renderFile; exports.init = function (app) { app.engine("maki", exports.renderFile); viewPath = app.get("views"); };