Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update koa-view-ng #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions plugin/directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(function() {
var directives = {};
if (typeof exports === 'object' && typeof module === 'object') {
module.exports = directives;
} else if (typeof define === 'function' && define.amd)
define(function() {
return directives;
});
else if (typeof exports === 'object')
exports["directives"] = directives;
else
window.directives = directives;
})();
18 changes: 18 additions & 0 deletions plugin/discribe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(function() {
var discribes = {};
if (typeof exports === 'object' && typeof module === 'object') {
var fs = require('fs');
var path = require('path');
discribes.nodeTplPath = function(htmlPath) {
return fs.readFileSync(path.resolve(__dirname, '../../../../common/templates', htmlPath), 'utf-8');
};
module.exports = discribes;
} else if (typeof define === 'function' && define.amd) {
define(function() {
return discribes;
});
} else if (typeof exports === 'object') {
} else {
window.discribes = discribes;
}
})();
31 changes: 31 additions & 0 deletions plugin/filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
(function() {
var filters = {
toFixed: function(input, number) {
input = Number(input)
if (isNaN(input)) {
return 0;
}
return input.toFixed(number)
},
date: function(input, fmt) {
var type = typeof input
if (type == 'number' || (type == 'string' && new Date(input))) {
return new Date(input).Format(fmt)
} else if (type == 'object' && input.getTime) {
return input.Format(fmt)
} else {
return '无效的日期参数'
}
}
}
if (typeof exports === 'object' && typeof module === 'object') {
module.exports = filters;
} else if (typeof define === 'function' && define.amd)
define(function() {
return filters;
});
else if (typeof exports === 'object')
exports["filters"] = filters;
else
window.filters = filters;
})();
133 changes: 58 additions & 75 deletions plugin/koa-view-ng.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@
// 加载模板引擎
// ngViews(app, {
// extension: ".html",
// filters: ngTemplateFilter,
// templateDir: path.join(__dirname, './common/templates/views'),
// viewsDir: path.join(__dirname, './common/templates/views'),
// cache: LRU({
// max: 500, // The maximum number of items allowed in the cache
// max_age: 1000 * 60 * 60 * 24 // The maximum life of a cached item in milliseconds
// }),
// beforeRender: (viewName, scope, ctx, setting) => {
// let { prefix, extension } = setting;
// let combScope = Object.assign({
// HMC: Object.assign({}, ctx.state, {
// tplSettings: { prefix, extension },
// currPage: viewName,
// jsRev: ctx.state.jsRevList[viewName + ".min.js"],
// pointList: ctx.state.pointData.common.concat(ctx.state.pointData.pages[viewName] || [])
// cssRev: ctx.state.cssRevList[viewName + ".min.css"],
// pointList: ctx.state.pointData.common.concat(ctx.state.pointData.pages[viewName] || []),
// data: scope && scope.data || {}
// })
// }, scope, {
// templates: scope && scope.templates || {}
// })
// delete combScope.HMC.jsRevList;
// delete combScope.HMC.cssRevList;
// delete combScope.HMC.pointData;
// return { viewName, combScope, setting }
// },
Expand All @@ -47,17 +47,14 @@
*/
const fs = require('fs');
const path = require('path');
const ngTemplate = require('sodajs/node');
const ngTemplate = require('./ngTemplate');
const crypto = require('crypto');

/**
* default render options
* @type {Object}
*/
const defaultSettings = {
prefix: 'ng',
templateDir: __dirname
};
const defaultSettings = {};

let tplCache = new Map()

Expand All @@ -71,75 +68,61 @@ let tplCache = new Map()
* @param {Application} app koa application instance
* @param {Object} settings user settings
*/
exports = module.exports = function (app, settings) {
if (app.context.render) {
return;
}

if (!settings || !settings.templateDir) {
throw new Error('settings.templateDir required');
}

settings = Object.assign({}, defaultSettings, settings);

if (settings.cache) {
tplCache = settings.cache;
settings.cache = null;
}

exports = module.exports = function(app, settings) {
if (app.context.render) {
return;
}

// 初始化ngTemplate设置
ngTemplate.prefix(settings.prefix);
//ngTemplate.templateDir = settings.templateDir;
if (!settings || !settings.viewsDir) {
throw new Error('settings.viewsDir required');
}

for (var key in settings.filters) {
ngTemplate.filter(key, settings.filters[key])
}
settings = Object.assign({}, defaultSettings, settings);

/**
* generate html with view name and options
* @param {String} view
* @param {Object} options
* @return {String} html
*/
async function render(view, options, ctx, setting) {
const viewPath = path.join(setting.templateDir, view + setting.extension);
const tpl = await fs.readFileSync(viewPath, 'utf-8');
let hashKey = "";
let hash = crypto.createHmac('sha256', "hmc_secret");
if (process.env.NODE_ENV === 'development') {
hashKey = hash.update(tpl + JSON.stringify(setting.serverCacheKey || options)).digest('hex');
}
else {
hashKey = hash.update(viewPath + JSON.stringify(setting.serverCacheKey || options)).digest('hex');
}
// 从缓存获取模版
if (!setting.disabledCache && tplCache && tplCache.get(hashKey)) {
ctx.set("fromCache", true);
return tplCache.get(hashKey);
if (settings.cache) {
tplCache = settings.cache;
settings.cache = null;
}

let template = ngTemplate(tpl, options)
// 加入缓存
if (!setting.disabledCache && tplCache) {
tplCache.set(hashKey, template);
/**
* generate html with view name and state
* @param {String} view
* @param {Object} state
* @return {String} html
*/
async function render(viewName, scope, ctx, setting) {
const viewPath = path.join(setting.viewsDir, viewName + setting.extension);
const tpl = await fs.readFileSync(viewPath, 'utf-8');
let hashKey = "";
let hash = crypto.createHmac('sha256', "hmc_secret");
if (process.env.NODE_ENV === 'development') {
hashKey = hash.update(tpl + JSON.stringify(setting.serverCacheKey || scope)).digest('hex');
} else {
hashKey = hash.update(viewPath + JSON.stringify(setting.serverCacheKey || scope)).digest('hex');
}
// 从缓存获取模版
if (!setting.disabledCache && tplCache && tplCache.get(hashKey)) {
ctx.set("fromCache", true);
return tplCache.get(hashKey);
}
let template = ngTemplate(tpl, scope)
// 加入缓存
if (!setting.disabledCache && tplCache) {
tplCache.set(hashKey, template);
}
return template;
}
return template;
}

app.context.render = async function (view, _context, setting) {
const ctx = this;
setting = Object.assign({}, settings, setting);
let { prefix, extension } = setting;
Object.assign(ctx.state, {
tplSettings: { prefix, extension }
});
const context = Object.assign({}, ctx.state, _context);

let html = await render(view, context, ctx, setting);
ctx.type = 'html';
ctx.body = html.replace("</!DOCTYPE>", "").replace("<!DOCTYPE>", "<!DOCTYPE html>");
};
};

exports.ngTemplate = ngTemplate;
app.context.render = async function(viewName, scope, setting) {
const ctx = this;
// 合并配置
setting = Object.assign({}, settings, setting);
// 合并state
let combScope = Object.assign({}, ctx.state, scope);
// 渲染前预处理
setting.beforeRender && ({ viewName, combScope, setting } = setting.beforeRender(viewName, scope, ctx, setting))
let html = await render(viewName, combScope, ctx, setting);
ctx.type = 'html';
ctx.body = html.replace("</!doctype>", "").replace("<!doctype>", "<!DOCTYPE HTML>");
};
};
70 changes: 70 additions & 0 deletions plugin/ngTemplate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
(function() {
function init(soda, filters, discribes, directives) {
filters = filters || {};
discribes = discribes || {};
directives = directives || {};
soda.prefix('ng-');
for (var key in filters) {
soda.filter(key, filters[key])
}
for (var key in discribes) {
soda.discribe(key, discribes[key])
}
for (var key in directives) {
soda.directive(key, directives[key])
}
return soda;
}
if (typeof exports === 'object' && typeof module === 'object') {
// CMD
var soda = require('sodajs/node');
// var soda_old = require('../lib/soda.old');
var filters = require('./filter');
var discribes = require('./discribe');
var directives = require('./directive');
var ngTemplate = init(soda, filters, discribes, directives);
module.exports = ngTemplate;
} else if (typeof define === 'function' && define.amd) {
// AMD
define([], function() {
var engine = null;
var ngTemplate = {
render: function(str, scope) {
var dfd = $.Deferred();
getTemplateEngine().then(function(engine) {
dfd.resolve(engine(str, scope))
}, function(e) {
console.log(e)
})
return dfd.promise();
}
};
// 获取模版引擎
function getTemplateEngine() {
var dfd = $.Deferred();
if (engine) {
dfd.resolve(engine)
} else {
require(['soda', 'filters', 'discribes', 'directives'], function(soda, filters, discribes, directives) {
if (soda) {
engine = init(soda, filters, discribes, directives);
dfd.resolve(engine)
} else {
dfd.reject('加载失败')
}
}, function(e) {
console.log(e)
dfd.reject('加载失败')
})
}
return dfd.promise();
}
window.ngTemplate = ngTemplate;
return ngTemplate;
});
} else if (typeof exports === 'object') {
// ES6
} else {
window.ngTemplate = init(soda, filters, discribes, directives);
}
})();