代码拉取完成,页面将自动刷新
package template
import (
"errors"
"gitee.com/lllgo/gopkg/files"
"gitee.com/lllgo/gopkg/utils"
"github.com/valyala/bytebufferpool"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"text/template"
)
type MetaKey interface{}
type FuncMap template.FuncMap
var (
metaData = map[MetaKey]interface{}{}
templateFilePath string
)
type Config struct {
//渲染模板资源根路径 配置的其它文件都相对该路径
BasePath string
//模板来源
TplFile, TplDir, TplText string
//渲染模板输出 如果都没配置就输出到控制台
DestDir, DestFile string
DestStdout bool
//变量开始和结束标志
LeftDelim, RightDelim string
//自定义函数
Funcs FuncMap
//渲染模板的数据
Data interface{}
}
func AddMetaData(key MetaKey, val interface{}) error {
metaData[key] = val
return nil
}
func GetMetaData(key MetaKey) interface{} {
return metaData[key]
}
func (c *Config) getData(data []interface{}) interface{} {
if len(data) > 0 {
return data[0]
}
return c.Data
}
func (c *Config) Render(data ...interface{}) ([]byte, error) {
if c.TplFile == "" && c.TplText == "" {
return nil, errors.New("请指定模板源")
}
t := c.getOriginalTemplate()
//模板字符串优先级比文件高
tempText := c.TplText
if tempText == "" && c.TplFile != "" {
tempText = getTmplByFile(c.TplFile)
}
return render(t, tempText, c.getData(data))
}
// 读取文件内容为字符串
func getTmplByFile(tmplFile string) string {
bytes, err := ioutil.ReadFile(tmplFile)
if err != nil {
panic("读取模板文件失败" + err.Error())
}
return string(bytes)
}
// 封装渲染模板方式
func render(t *template.Template, tmplText string, data interface{}) ([]byte, error) {
if tmplText == "" {
return nil, errors.New("模板内容为空")
}
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
parse, err := t.Parse(tmplText)
if err != nil {
return nil, err
}
if err = parse.Execute(buf, data); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// 封装写入到文件方法
func writeFile(content []byte, destFile string) error {
dest := os.Stdout
if destFile != "" {
var err error
dest, err = os.Create(destFile)
if err != nil {
return err
}
defer dest.Close()
}
_, err := dest.Write(content)
return err
}
// 支持渲染结果输出到控制台、文件、文件目录(只有模板文件为目录时有效)
func (c *Config) Write(data ...interface{}) error {
if c.TplDir == "" && c.TplFile == "" && c.TplText == "" {
return errors.New("请指定模板源")
}
if c.TplFile != "" || c.TplText != "" {
render, err := c.Render(data...)
if err != nil {
return err
}
return writeFile(render, c.DestFile)
} else if c.TplDir != "" {
t := c.getOriginalTemplate()
allFile := files.GetAllFile(c.TplDir, "")
for _, f := range allFile {
tmplText := getTmplByFile(filepath.Join(c.TplDir, f))
bytes, err := render(t, tmplText, c.getData(data))
if err != nil {
return err
}
destFile := ""
if c.DestDir != "" {
destFile = filepath.Join(c.DestDir, f)
}
err = writeFile(bytes, destFile)
if err != nil {
return err
}
}
} else {
return errors.New("不支持的配置")
}
return nil
}
func (c *Config) getOriginalTemplate() *template.Template {
funcs := template.FuncMap{
"contains": contains,
"exists": exists,
"split": strings.Split,
"replace": strings.Replace,
"default": defaultValue,
"parseUrl": parseUrl,
"atoi": strconv.Atoi,
"add": add,
"isTrue": isTrue,
"lower": strings.ToLower,
"upper": strings.ToUpper,
"jsonQuery": jsonQuery,
"loop": loop,
"abs": abs,
"type": getType,
}
for k, v := range c.Funcs {
funcs[k] = v
}
if c.LeftDelim == "" {
c.LeftDelim = "{{"
}
if c.RightDelim == "" {
c.RightDelim = "}}"
}
c.TplDir = utils.GetDefStringWithBool(c.TplDir != "", files.Abs(c.BasePath, c.TplDir), c.TplDir)
c.TplFile = utils.GetDefStringWithBool(c.TplFile != "", files.Abs(c.BasePath, c.TplFile), c.TplFile)
c.DestFile = utils.GetDefStringWithBool(c.DestFile != "", files.Abs(c.BasePath, c.DestFile), c.DestFile)
c.DestDir = utils.GetDefStringWithBool(c.DestDir != "", files.Abs(c.BasePath, c.DestDir), c.DestDir)
if c.TplFile != "" {
templateFilePath = c.TplFile
}
if c.TplDir != "" {
templateFilePath = c.TplDir
}
t := template.New("").Funcs(funcs).Delims(c.LeftDelim, c.RightDelim)
return t
}
func RenderText2File(tmplText, destFile string, data interface{}) error {
t := Config{TplText: tmplText, DestFile: destFile}
return t.Write(data)
}
func RenderText(tmplText string, data interface{}) ([]byte, error) {
t := Config{TplText: tmplText}
return t.Render(data)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。