Ai
1 Star 0 Fork 8

哈哈哈/wego
暂停

forked from kzquu/wego 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
template.go 3.52 KB
一键复制 编辑 原始数据 按行查看 历史
kzquu 提交于 2020-01-18 10:36 +08:00 . 0
package template
import (
"bytes"
"html/template"
"io"
"path/filepath"
"strings"
"sync"
"text/template/parse"
"time"
)
// New 返回一个*Template
func New(path string) (t *Template, err error) {
var ht *template.Template
ht, err = getTemplate(path)
if err != nil {
return
}
t = new(Template)
t.T, err = ht.Clone()
t.cache = new(bytes.Buffer)
t.M = new(sync.RWMutex)
t.path = filepath.FromSlash(path)
return
}
// ****************************************************************************
// Template Template
type Template struct {
T *template.Template
cache *bytes.Buffer // 缓存
cacheExpireTime time.Time // 缓存过期时间
M *sync.RWMutex
path string
paths []string
associatesTemplateAutois bool
}
// AssociatesTemplate 关联模板
func (t *Template) AssociatesTemplate(paths ...string) (r []*template.Template, errPath string, err error) {
t.paths = append(t.paths, paths...)
var (
ht *template.Template
htt []*template.Template
j int
)
r = make([]*template.Template, 0, 3)
for i := 0; i < len(paths); i++ {
ht, err = getTemplate(paths[i])
if err != nil {
goto ERROR
}
r = append(r, ht)
htt = ht.Templates()
for j = 0; j < len(htt); j++ {
_, err = t.T.AddParseTree(htt[j].Name(), htt[j].Tree)
if err != nil {
goto ERROR
}
}
continue
ERROR:
errPath = paths[i]
return
}
return
}
// AssociatesTemplateAuto 在相同目录下自动寻找并关联模板
func (t *Template) AssociatesTemplateAuto() {
t.associatesTemplateAuto(t.T)
t.associatesTemplateAutois = true
}
func (t *Template) associatesTemplateAuto(a *template.Template) {
var (
ptn *parse.TemplateNode
ok = false
i = -1
r []*template.Template
path string
)
i = strings.LastIndexByte(t.path, byte(filepath.Separator))
if i != -1 {
path = t.path[:i+1]
}
for _, node := range a.Tree.Root.Nodes {
ptn, ok = node.(*parse.TemplateNode)
if ok {
r, _, _ = t.AssociatesTemplate(path + ptn.Name)
for i = 0; i < len(r); i++ {
t.associatesTemplateAuto(r[i])
}
}
}
}
// UseCache 使用缓存,前提是Execute时使用了缓存
func (t *Template) UseCache(wr io.Writer) (successful bool) {
t.M.RLock()
if t.cacheExpireTime.After(time.Now()) { // 缓存未过期
wr.Write(t.cache.Bytes())
successful = true
} else { // 缓存已经过期
successful = false
}
t.M.RUnlock()
return
}
// UseCacheAlways 当缓存数据存在时,不管是否过期都使用缓存
func (t *Template) UseCacheAlways(wr io.Writer) (successful bool) {
t.M.RLock()
if t.cache.Len() != 0 { // 缓存数据存在
wr.Write(t.cache.Bytes())
successful = true
} else { // 缓存数据不存在
successful = false
}
t.M.RUnlock()
return
}
// Execute Execute
// cacheTime: 缓存时间(单位秒),<=0 不缓存;>0 使用缓存,需要和UseCache配合使用
func (t *Template) Execute(wr io.Writer, data interface{}, cacheTime int64) (err error) {
if debug {
_t, err := New(t.path)
if err != nil {
return err
}
_, _, err = _t.AssociatesTemplate(t.paths...)
if err != nil {
return err
}
if t.associatesTemplateAutois {
_t.AssociatesTemplateAuto()
}
return _t.T.Execute(wr, data)
}
if cacheTime > 0 { // 使用缓存
t.M.Lock()
t.cache.Reset()
err = t.T.Execute(t.cache, data)
if err == nil {
t.cacheExpireTime = time.Now().Add(time.Duration(cacheTime) * time.Second)
_, err = wr.Write(t.cache.Bytes())
}
t.M.Unlock()
} else { // 不使用缓存
err = t.T.Execute(wr, data)
}
return
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/jameson512/wego.git
git@gitee.com:jameson512/wego.git
jameson512
wego
wego
206da09742f2

搜索帮助