## 模板
### 模板渲染
使用 `Context#Render(code int, name string, data interface{}) error` 命令渲染帶有數據的模板,并發送帶有狀態代碼的 text / html 響應。通過 `Echo.Renderer` 的設置我們可以使用任何模板引擎。
下面是使用 Go `html/template` 的示例:
1. 實現 `echo.Renderer` 接口
```go
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`
```html
{{define "hello"}}Hello, {{.}}!{{end}}
```
```go
t := &Template{
templates: template.Must(template.ParseGlob("public/views/*.html")),
}
```
3. 聲明模板
```go
e := echo.New()
e.Renderer = t
e.GET("/hello", Hello)
```
4. 在 action 中渲染模板
```go
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
<html>
<body>
<h1>Hello {{index . "name"}}</h1>
<p>{{ with $x := index . "reverse" }}
{{ call $x "foobar" }} <-- this will call the $x with parameter "foobar"
{{ end }}
</p>
</body>
</html>
```
`server.go`
```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"))
}
```