模板

模板渲染

使用 Context#Render(code int, name string, data interface{}) error 命令渲染带有数据的模板,并发送带有状态代码的 text / html 响应。通过 Echo.Renderer 的设置我们可以使用任何模板引擎。

下面是使用 Go html/template 的示例:

  1. 实现 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)
    }
  2. 预编译模板

    public/views/hello.html

     \{\{define "hello"\}\}Hello, \{\{.\}\}!\{\{end\}\}
    t := &Template{
        templates: template.Must(template.ParseGlob("public/views/*.html")),
    }
  3. 声明模板

    e := echo.New()
    e.Renderer = t
    e.GET("/hello", Hello)
  4. 在 action 中渲染模板

    func Hello(c echo.Context) error {
         return c.Render(http.StatusOK, "hello", "World")
     }

高级 - 在模版中调用 Echo

在某些情况下,从模板生成 uri 可能很有用,为此,您需要从模板本身调用 Echo#Reverse。此时,Golang 的 html/template 包并不一定合适这种情况,但我们可以通过两种方法实现它:第一种,给所有的传递到模版的对象提供一个公用的方法;第二种,将 map[string]interface{} 作为参数传递并在自定义渲染器中扩充此模版。鉴于后一种方法的灵活性,这里有一个示例程序:
template.html

<html>
    <body>
        <h1>Hello {{index . "name"}}</h1>

        <p>{{ with $x := index . "reverse" }}
           {{ call $x "foobar" }} &lt;-- this will call the $x with parameter "foobar"
           {{ end }}
        </p>
    </body>
</html>

server.go

package main

import (
    "html/template"
    "io"
    "log"
    "net/http"

    "github.com/labstack/echo"
)

// TemplateRenderer is a custom html/template renderer for Echo framework
type TemplateRenderer struct {
    templates *template.Template
}

// Render renders a template document
func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {

    // Add global methods if data is a map
    if viewContext, isMap := data.(map[string]interface{}); isMap {
        viewContext["reverse"] = c.Echo().Reverse
    }

    return t.templates.ExecuteTemplate(w, name, data)
}

func main() {
  e := echo.New()
  renderer := &TemplateRenderer{
      templates: template.Must(template.ParseGlob("*.html")),
  }
  e.Renderer = renderer

  // Named route "foobar"
  e.GET("/something", func(c echo.Context) error {
      return c.Render(http.StatusOK, "something.html", map[string]interface{}{
          "name": "Dolly!",
      })
  }).Name = "foobar"

  log.Fatal(e.Start(":8000"))
}
文档更新时间: 2020-07-20 16:34   作者:kuteng