2020-09-18 14:16:26 +08:00
|
|
|
/**
|
|
|
|
* nodeJS 模板引擎
|
|
|
|
* @author yutent<yutent.io@gmail.com>
|
|
|
|
* @date 2020/09/18 13:36:47
|
|
|
|
*/
|
|
|
|
|
|
|
|
import 'es.shim'
|
|
|
|
import path from 'path'
|
|
|
|
import fs from 'iofs'
|
2020-09-27 19:32:13 +08:00
|
|
|
import { fileURLToPath } from 'url'
|
2020-09-18 14:16:26 +08:00
|
|
|
|
|
|
|
import Tool from './lib/tool.mjs'
|
|
|
|
|
|
|
|
function hash(str) {
|
|
|
|
return Buffer.from(str).toString('hex')
|
|
|
|
}
|
|
|
|
|
2020-09-27 19:32:13 +08:00
|
|
|
var __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
var cacheDir = path.resolve(__dirname, './cache/')
|
|
|
|
|
2020-09-18 14:16:26 +08:00
|
|
|
export default class Smarty {
|
|
|
|
constructor(opt) {
|
2020-09-27 19:32:13 +08:00
|
|
|
this.opt = { ext: '.htm' }
|
2020-09-18 14:16:26 +08:00
|
|
|
if (opt) {
|
|
|
|
Object.assign(this.opt, opt)
|
|
|
|
}
|
|
|
|
|
|
|
|
this.__REG__ = new RegExp(this.opt.ext + '$')
|
|
|
|
this.tool = new Tool(this.opt)
|
2020-09-27 19:32:13 +08:00
|
|
|
|
|
|
|
this.reset()
|
2020-09-18 14:16:26 +08:00
|
|
|
this.__CACHE__ = Object.create(null) // 渲染缓存
|
2020-09-27 19:32:13 +08:00
|
|
|
// 消除缓存目录
|
|
|
|
fs.rm(cacheDir)
|
|
|
|
}
|
|
|
|
|
|
|
|
reset() {
|
|
|
|
this.__DATA__ = Object.create(null) // 预定义的变量储存
|
2020-09-18 14:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
config(key, val) {
|
|
|
|
key += ''
|
|
|
|
if (!key || val === undefined) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this.opt[key] = val
|
|
|
|
this.tool.opt[key] = val
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 定义变量
|
|
|
|
* @param {Str} key 变量名
|
|
|
|
* @param {any} val 值
|
|
|
|
*/
|
|
|
|
assign(key, val) {
|
|
|
|
key += ''
|
|
|
|
if (!key) {
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
this.__DATA__[key] = val
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* [render 模板渲染]
|
|
|
|
* @param {String} filePath 模板路径
|
|
|
|
* @param {Boolean} noParse 不解析直接读取
|
|
|
|
* @return {Promise} 返回一个Promise对象
|
|
|
|
*/
|
|
|
|
render(filePath = '', noParse = false) {
|
2020-09-27 19:32:13 +08:00
|
|
|
var key, ckey, cache, needWrite
|
|
|
|
|
2020-09-18 14:16:26 +08:00
|
|
|
if (!this.opt.path) {
|
|
|
|
throw new Error('Smarty engine must define path option')
|
|
|
|
}
|
|
|
|
if (!filePath) {
|
|
|
|
return Promise.reject('argument[filePath] can not be empty')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.__REG__.test(filePath)) {
|
|
|
|
filePath += this.opt.ext
|
|
|
|
}
|
|
|
|
filePath = path.resolve(this.opt.path, filePath)
|
|
|
|
|
|
|
|
key = hash(filePath)
|
2020-09-27 19:32:13 +08:00
|
|
|
ckey = path.join(cacheDir, key)
|
2020-09-18 14:16:26 +08:00
|
|
|
|
|
|
|
if (this.__CACHE__[key]) {
|
2020-09-27 19:32:13 +08:00
|
|
|
cache = fs.cat(ckey)
|
|
|
|
} else {
|
|
|
|
cache = fs.cat(filePath)
|
|
|
|
this.__CACHE__[key] = true
|
|
|
|
needWrite = true
|
2020-09-18 14:16:26 +08:00
|
|
|
}
|
|
|
|
|
2020-09-27 19:32:13 +08:00
|
|
|
// 无需解析时, 直接输出
|
2020-09-18 14:16:26 +08:00
|
|
|
if (noParse) {
|
2020-09-27 19:32:13 +08:00
|
|
|
if (needWrite) {
|
|
|
|
fs.echo(cache, ckey)
|
|
|
|
}
|
2020-09-18 14:16:26 +08:00
|
|
|
return Promise.resolve(cache)
|
2020-09-27 19:32:13 +08:00
|
|
|
} else {
|
|
|
|
if (needWrite) {
|
|
|
|
cache = this.tool.parse(cache)
|
|
|
|
fs.echo(cache, ckey)
|
|
|
|
}
|
2020-09-18 14:16:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2020-09-27 19:32:13 +08:00
|
|
|
var body = this.tool.exec(cache, this.__DATA__)
|
|
|
|
this.reset()
|
|
|
|
return Promise.resolve(body)
|
2020-09-18 14:16:26 +08:00
|
|
|
} catch (err) {
|
|
|
|
return Promise.reject(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|