一波修复
parent
de97924950
commit
1fd64ee360
22
index.js
22
index.js
|
@ -7,6 +7,7 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
require('es.shim')
|
require('es.shim')
|
||||||
|
|
||||||
const Tool = require('./lib/tool')
|
const Tool = require('./lib/tool')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
|
@ -22,17 +23,19 @@ class Smarty {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__REG__ = new RegExp(this.opt.ext + '$')
|
this.__REG__ = new RegExp(this.opt.ext + '$')
|
||||||
this.tool = new Tool()
|
this.tool = new Tool(this.opt)
|
||||||
this.__DATA__ = Object.create(null) // 预定义的变量储存
|
this.__DATA__ = Object.create(null) // 预定义的变量储存
|
||||||
this.__CACHE__ = Object.create(null) // 模块缓存
|
this.__TMP__ = Object.create(null) // 模板缓存
|
||||||
|
this.__CACHE__ = Object.create(null) // 渲染缓存(模板被解析后)
|
||||||
}
|
}
|
||||||
|
|
||||||
config(key, val) {
|
config(key, val) {
|
||||||
key += ''
|
key += ''
|
||||||
if (!key || !val) {
|
if (!key || val === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.opt[key] = val
|
this.opt[key] = val
|
||||||
|
this.tool.opt[key] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,7 +61,7 @@ class Smarty {
|
||||||
*/
|
*/
|
||||||
render(tpl = '', noParse = false) {
|
render(tpl = '', noParse = false) {
|
||||||
var key = null
|
var key = null
|
||||||
if (!this.tool.opt.path) {
|
if (!this.opt.path) {
|
||||||
throw new Error('Smarty engine must define path option')
|
throw new Error('Smarty engine must define path option')
|
||||||
}
|
}
|
||||||
if (!tpl) {
|
if (!tpl) {
|
||||||
|
@ -72,17 +75,20 @@ class Smarty {
|
||||||
|
|
||||||
key = hash(tpl)
|
key = hash(tpl)
|
||||||
|
|
||||||
if (this.opt.cache && this.__CACHE__[key]) {
|
if (this.__CACHE__[key]) {
|
||||||
return Promise.resolve(this.__CACHE__[key])
|
return Promise.resolve(this.__CACHE__[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__CACHE__[key] = this.tool.__tpl__(tpl, noParse)
|
this.__TMP__[key] = this.tool.__readFile__(tpl, noParse)
|
||||||
|
|
||||||
if (noParse) {
|
if (noParse) {
|
||||||
return this.__CACHE__[key]
|
this.__CACHE__[key] = this.__TMP__[key]
|
||||||
|
delete this.__TMP__[key]
|
||||||
|
return Promise.resolve(this.__CACHE__[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.__CACHE__[key] = this.tool.parse(this.__CACHE__[key], this.__DATA__)
|
this.__CACHE__[key] = this.tool.parse(this.__TMP__[key], this.__DATA__)
|
||||||
return Promise.resolve(this.__CACHE__[key])
|
return Promise.resolve(this.__CACHE__[key])
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return Promise.reject(err)
|
return Promise.reject(err)
|
||||||
|
|
40
lib/tool.js
40
lib/tool.js
|
@ -8,9 +8,10 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const fs = require('iofs')
|
const fs = require('iofs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
class Tool {
|
class Tool {
|
||||||
constructor() {
|
constructor(opt) {
|
||||||
this.opt = {
|
this.opt = {
|
||||||
delimiter: ['<!--{', '}-->'], //模板界定符
|
delimiter: ['<!--{', '}-->'], //模板界定符
|
||||||
labels: {
|
labels: {
|
||||||
|
@ -31,6 +32,10 @@ class Tool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object.assign(this.opt, opt)
|
||||||
|
|
||||||
|
this.__REG__ = new RegExp(this.opt.ext + '$')
|
||||||
|
|
||||||
//过滤器
|
//过滤器
|
||||||
this.filters = {
|
this.filters = {
|
||||||
html: function(str = '') {
|
html: function(str = '') {
|
||||||
|
@ -67,7 +72,7 @@ class Tool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__tpl__(file) {
|
__readFile__(file, noParse) {
|
||||||
var buf = null
|
var buf = null
|
||||||
if (!fs.exists(file)) {
|
if (!fs.exists(file)) {
|
||||||
throw new Error(`Can not find template "${file}"`)
|
throw new Error(`Can not find template "${file}"`)
|
||||||
|
@ -91,8 +96,8 @@ class Tool {
|
||||||
|
|
||||||
//生成模板标签
|
//生成模板标签
|
||||||
__label__(id) {
|
__label__(id) {
|
||||||
let opt = this.opt
|
var opt = this.opt
|
||||||
let tag = opt.labels[id]
|
var tag = opt.labels[id]
|
||||||
return this.__exp__(opt.delimiter[0] + tag + opt.delimiter[1])
|
return this.__exp__(opt.delimiter[0] + tag + opt.delimiter[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,17 +218,18 @@ class Tool {
|
||||||
matchInclude(m) {
|
matchInclude(m) {
|
||||||
let begin = this.__exp__('^' + this.opt.delimiter[0] + 'include\\s+')
|
let begin = this.__exp__('^' + this.opt.delimiter[0] + 'include\\s+')
|
||||||
let end = this.__exp__(this.opt.delimiter[1] + '$')
|
let end = this.__exp__(this.opt.delimiter[1] + '$')
|
||||||
|
var tpl = ''
|
||||||
|
|
||||||
m = m
|
m = m
|
||||||
.replace(begin, '')
|
.replace(begin, '')
|
||||||
.replace(end, '')
|
.replace(end, '')
|
||||||
.replace(/^['"]/, '')
|
.replace(/^['"]/, '')
|
||||||
.replace(/['"]$/, '')
|
.replace(/['"]$/, '')
|
||||||
.replace(/\.tpl$/, '') //去掉可能出现的自带的模板后缀
|
.replace(this.__REG__, '') //去掉可能出现的自带的模板后缀
|
||||||
|
|
||||||
m += '.tpl' //统一加上后缀
|
m += this.opt.ext //统一加上后缀
|
||||||
|
|
||||||
let tpl = this.__tpl__(m)
|
tpl = this.__readFile__(path.resolve(this.opt.path, m))
|
||||||
//递归解析include
|
//递归解析include
|
||||||
tpl = tpl.replace(this.__label__('inc'), m1 => {
|
tpl = tpl.replace(this.__label__('inc'), m1 => {
|
||||||
return this.matchInclude(m1)
|
return this.matchInclude(m1)
|
||||||
|
@ -274,7 +280,7 @@ class Tool {
|
||||||
|
|
||||||
// 解析extends标签
|
// 解析extends标签
|
||||||
parseExtends(str) {
|
parseExtends(str) {
|
||||||
let matches = str.match(/^<!--{extends ([^\\{\\}\\(\\)]*?)}-->/)
|
let matches = str.match(/^<!--{extends ([^\\{\\}\\(\\)]*?)\s*?}-->/)
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
str = str
|
str = str
|
||||||
.replace(this.__label__('blockL'), '')
|
.replace(this.__label__('blockL'), '')
|
||||||
|
@ -293,25 +299,27 @@ class Tool {
|
||||||
str = matches[1]
|
str = matches[1]
|
||||||
.replace(/^['"]/, '')
|
.replace(/^['"]/, '')
|
||||||
.replace(/['"]$/, '')
|
.replace(/['"]$/, '')
|
||||||
.replace(/\.tpl$/, '') //去掉可能出现的自带的模板后缀
|
.replace(this.__REG__, '') //去掉可能出现的自带的模板后缀
|
||||||
|
|
||||||
str += '.tpl' //统一加上后缀
|
str += this.opt.ext //统一加上后缀
|
||||||
|
|
||||||
str = this.__tpl__(str).replace(this.__label__('blockL'), (m, flag) => {
|
str = this.__readFile__(path.resolve(this.opt.path, str)).replace(
|
||||||
|
this.__label__('blockL'),
|
||||||
|
(m, flag) => {
|
||||||
flag = flag.trim()
|
flag = flag.trim()
|
||||||
return blocks[flag] || ''
|
return blocks[flag] || ''
|
||||||
})
|
}
|
||||||
blocks = undefined
|
)
|
||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析模板
|
//解析模板
|
||||||
parse(str, data) {
|
parse(str, data) {
|
||||||
this.vars = `"use strict"; let __filters__ = f; `
|
var vars = `"use strict"; let __filters__ = f; `
|
||||||
for (let i in data) {
|
for (let i in data) {
|
||||||
let tmp = JSON.stringify(data[i]) || ''
|
let tmp = JSON.stringify(data[i]) || ''
|
||||||
this.vars += `let ${i} = ${tmp}; `
|
vars += `let ${i} = ${tmp}; `
|
||||||
}
|
}
|
||||||
str = str
|
str = str
|
||||||
.trim()
|
.trim()
|
||||||
|
@ -322,7 +330,7 @@ class Tool {
|
||||||
str = this.parseExtends(str)
|
str = this.parseExtends(str)
|
||||||
str = this.parseNormal(str)
|
str = this.parseNormal(str)
|
||||||
|
|
||||||
str = `${this.vars} let tpl=\`${str}\`; return tpl;`
|
str = `${vars} let tpl=\`${str}\`; return tpl;`
|
||||||
|
|
||||||
return new Function('f', str)(this.filters)
|
return new Function('f', str)(this.filters)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "smartyx",
|
"name": "smartyx",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"description": "nodeJS模板引擎,理念源自于PHP的smarty模板引擎",
|
"description": "nodeJS模板引擎,理念源自于PHP的smarty模板引擎",
|
||||||
"keywords": ["fivejs", "smarty", "template", "ejs", "jade"],
|
"keywords": ["fivejs", "smarty", "template", "ejs", "jade"],
|
||||||
"author": "宇天 <yutent@doui.cc>",
|
"author": "宇天 <yutent@doui.cc>",
|
||||||
|
|
Loading…
Reference in New Issue