golang echo 代码详解之模版篇

Laily · 2017-12-12 15:57:05 · 4737 次点击 · 预计阅读时间 3 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2017-12-12 15:57:05 的文章,其中的信息可能已经有所发展或是发生改变。

在 echo 里使用模版则必须先注册一个,如果不注册就会报出下面这样的错误

{"time":"2017-12-12T23:03:57.939138716+08:00","level":"ERROR","prefix":"echo","file":"echo.go","line":"284","message":"Renderer not registered"}

注册就是给 echo.Renderer 赋值。

echo 的 Renderer 属性是一个接口

Renderer interface {
    Render(io.Writer, string, interface{}, Context) error
}

一、使用标准库模版

echo 的文档给出了使用官方模版注册的方式

// 实现 Renderer 接口
type Template struct {
    templates *template.Template
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return t.templates.ExecuteTemplate(w, name, data)
}
// 处理 view 目录下的文件生成对应的模版
// 关于 ExecuteTemplate 和 ParseGlob 方法可以查看 
// https://wizardforcel.gitbooks.io/golang-stdlib-ref/content/67.html#Template.ExecuteTemplate
t := &Template{
    templates: template.Must(template.ParseGlob("public/views/*.html")),
}
// 赋值
e.Renderer = t

二、使用 pongo2

gopkg.in/flosch/pongo2.v3 是一个很不错的模版引擎,很多时候会选择它来渲染模版。

首先还是实现 Renderer 接口

type Template struct {
    // 这里使用一个 map 来存储预处理了的模版
    tmplMap map[string]*pongo2.Template
}

func (t *Template) Render(w io.Writer, templateName string, data interface{}, c echo.Context) error {
    // 这里根据传来的 name 从 tmplMap 里查找模版来渲染
      // 注意 ExcuteWriter 的参数必须是 map[string]interface{} 的
    dataMap := data.(map[string]interface{})
    template, exist := t.tmplMap[templateName]
    if !exist {
        return errors.New("template " + templateName + " not found")
    }
    return template.ExecuteWriter(dataMap, w)
}

然后预编译模版

// 读取目录下的文件预处理
func preCompile(dir string) *Template {
    tmplMap := make(map[string]*pongo2.Template)

    dirPath := filepath.Dir(dir)
    fileInfos, _ := ioutil.ReadDir(dirPath)

    for _, fileInfo := range fileInfos {
        t, err := pongo2.FromFile(path.Join(dir, fileInfo.Name()))
        if err != nil {
            log.Fatalf("\"%s\": %v", fileInfo.Name(), err)
        }
        tmplMap[strings.Replace(fileInfo.Name(), path.Ext(fileInfo.Name()), "", -1)] = t

    }

    return &Template{tmplMap}
}

最后赋值

func NewTemplates(dir string) *Template {
    return preCompile(dir)
}

t := NewTemplates("./views/")
e.Renderer = t

这样自定义的 renderer 就算完成了。

原文地址:laily.net


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4737 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
2 回复  |  直到 2017-12-13 03:00:28
polaris
polaris · #1 · 7年之前

欢迎在本站开通你自己的专栏,开通方法:https://studygolang.com/subject/new

Laily
Laily · #2 · 7年之前
polarispolaris #1 回复

欢迎在本站开通你自己的专栏,开通方法:https://studygolang.com/subject/new

好的,已经开通

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传