Echo模版嵌套
一个基本的Echo项目
main.go
package main
import (
"net/http"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.Logger.Fatal(e.Start(":1323"))
}
返回一个JSON响应
package main
import (
"net/http"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.GET("/json", func(c echo.Context) error {
return c.JSONBlob(
http.StatusOK,
[]byte(`{"id": "1", "msg": "Hello, China!"}`),
)
})
e.Logger.Fatal(e.Start(":1323"))
}
返回HTML
package main
import (
"net/http"
"github.com/labstack/echo"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
})
e.GET("/json", func(c echo.Context) error {
return c.JSONBlob(
http.StatusOK,
[]byte(`{"id": "1", "msg": "Hello, China!"}`),
)
})
e.GET("/html", func(c echo.Context) error {
return c.HTML(
http.StatusOK,
"<h1>Hello, Suzhou!</h1>",
)
})
e.Logger.Fatal(e.Start(":1323"))
}
使用模板引擎呈现HTML
这次有点不一样,多个文件了,目录结构如下:
➜ golang-echo-template-example tree
.
├── handler
│ └── home_handler.go
├── main.go
└── view
└── home.html
main.go
package main
import (
"io"
"html/template"
"github.com/kissjava/golang-echo-template-example/handler"
"github.com/labstack/echo"
)
// TemplateRegistry 定义模板注册表结构
type TemplateRegistry struct {
templates *template.Template
}
// Render 实现 e.Renderer接口
func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return t.templates.ExecuteTemplate(w, name, data)
}
func main() {
e := echo.New()
// 实例化一个模板注册表并在视图文件夹中注册所有html文件
e.Renderer = &TemplateRegistry{
templates: template.Must(template.ParseGlob("view/*.html")),
}
e.GET("/", handler.HomeHandler)
e.Logger.Fatal(e.Start(":1323"))
}
handler/home_handler.go
package handler
import (
"net/http"
"github.com/labstack/echo"
)
// HomeHandler 根路径处理器函数
func HomeHandler(c echo.Context) error {
// 第二个参数 home.html 是view/home.html中{{ define }}定义的名称
return c.Render(http.StatusOK, "home.html", map[string]interface{}{
"name": "HOME",
"msg": "Hello, World!",
})
}
view/home.html
{{define "home.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kissjava Blog | {{index . "name"}}</title>
</head>
<body>
<h1>{{index . "msg"}}</h1>
</body>
</html>
{{end}}
模版嵌套
在上面的设置中,HTML模板是一组完整的HTML代码。
如果是整个站点来使用,其中许多代码就是重复的。
使用嵌套模板使项目维护更加容易。
最初TemplateRegistry
中的templates
字段包含所有模板文件。
在新的设置中,我们将其设置为一个map
字段,每一项都是针对特定HTML页面的一组模板文件。
新的项目结构如下:
➜ golang-echo-template-example tree
.
├── handler
│ ├── about__handler.go
│ └── home_handler.go
├── main.go
└── view
├── about.html
├── base.html
└── home.html
main.go 如下:
package main
import (
"errors"
"io"
"html/template"
"github.com/kissjava/golang-echo-template-example/handler"
"github.com/labstack/echo"
)
// TemplateRegistry 定义模板注册表结构
type TemplateRegistry struct {
templates map[string]*template.Template
}
// Render 实现 e.Renderer接口
func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
tmpl, ok := t.templates[name]
if !ok {
err := errors.New("没有找到模版 -> " + name)
return err
}
return tmpl.ExecuteTemplate(w, "base.html", data)
}
func main() {
e := echo.New()
//用模板集数组实例化一个模板注册表
templates := make(map[string]*template.Template)
templates["home.html"] = template.Must(template.ParseFiles("view/home.html", "view/base.html"))
templates["about.html"] = template.Must(template.ParseFiles("view/about.html", "view/base.html"))
e.Renderer = &TemplateRegistry{
templates: templates,
}
e.GET("/", handler.HomeHandler)
e.GET("/about", handler.AboutHandler)
e.Logger.Fatal(e.Start(":1323"))
}
view/base.html
{{define "base.html"}}
<!DOCTYPE html>
<html>
<head>
<title>{{template "title" .}}</title>
</head>
<body>
{{template "body" .}}
</body>
</html>
{{end}}
view/about.html
{{define "title"}}
Kissjava Blog | {{index . "name"}}
{{end}}
{{define "body"}}
<h1>{{index . "msg"}}</h1>
<h2>This is the about page.</h2>
{{end}}
handler/about_handler.go
package handler
import (
"net/http"
"github.com/labstack/echo"
)
// AboutHandler /about处理器
func AboutHandler(c echo.Context) error {
// 请注意第二个参数“about.html”是模板名
// 等于main.go中定义的TemplateRegistry数组中的一个键
return c.Render(http.StatusOK, "about.html", map[string]interface{}{
"name": "About",
"msg": "All about kissjava!",
})
}
结束
前面故意没有去改动home.html
,可以参考 about.hmtl
去比较实现。
{{define "title"}}
Kissjava Blog | {{index . "name"}}
{{end}}
{{define "body"}}
<h1>{{index . "msg"}}</h1>
<h2>This is the home page.</h2>
{{end}}
最后修改于 2020-06-27