代码拉取完成,页面将自动刷新
同步操作将从 kzquu/wego 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
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
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。