Go HTML/template 模板使用方法

bigbug-gg發表於2019-10-25

html/template 它是 Go 官方維護的,但是在初次接觸的時候,缺乏文件指南,看了很多零碎的相關資料,大概知道了 {{ . }} 的用法,翻看 官方DOC ...沒辦法立馬給到我想要的答案:如何模版複用、迴圈渲染(慢慢研究可能會得到答案)... 所以本篇文章的是關於模版複用的實現嘗試.要獲取更詳細的用法,可以看這篇文章go html模板的使用

1 在模版內,使用 {{ define "名稱" }} 內容 {{ end }} 定義模版,如:

{{ define "header" }}
    <!doctype html>
    <html lang="">
    <head>
      <title>定義頭</title>
    </head>
    <body>
{{ end }}

{{ define "footer" }}
</body>
</html>
{{ end }}

2 再需要引用的模版內,使用 {{ template "名稱" . }},引用模版,注意 . 別漏了,如:

{{ template "header" . }}
    <h1>Hello world</h1>
{{ template "footer" . }}

以上就是模版複用的方法,實際在官方文件有相關介紹,但它只介紹了輪子,沒告訴我們輪子使用範圍:

import "html/template"
...
t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")

你看到這個例子,能立馬想到模版裡面如何複用嗎?反正我是不能!

主要是通過 {{ . }},下面以我目前所瞭解的用法分享給大家:

1.直接渲染值:
...
<h1>{{ .name }}</h1>
...

2.加入語法(還有其它語法,只是指條路):
...
<ul>
    {{ range .Listdata }}
         <li>{{ .Title }} </li>
    {{ end }}
</ul>
...

1.使用 . 訪問當前資料域:比如 range 裡使用 . 訪問的其實是迴圈項的資料域:

// 虛擬碼 傳遞的資料
Listdata := []struct {
            Title    string
            Nickname string
        }{{Title: "gang", Nickname: "sdfsf"},
            {Title: "gang", Nickname: "sdfsf"}})
        ctx.View("test.html")
    }
...
<ul>
    {{ range .Listdata }}
        這個時候, . 範圍在 Listdata 資料域,所以可以使用 . 來訪問對應欄位
         <li>{{ .Title }} </li>
    {{ end }}
</ul>
...
  1. 使用 $. 訪問絕對頂層資料域:
// 虛擬碼 傳遞的資料
Age := 12
Listdata := []struct {
            Title    string
            Nickname string
        }{{Title: "gang", Nickname: "sdfsf"},
            {Title: "gang", Nickname: "sdfsf"}})
        ctx.View("test.html")
    }
...
<ul>
    {{ range .Listdata }}
        這個時候, . 範圍在 Listdata 資料域,所以可以使用 . 來訪問對應欄位
         <li>{{ .Title }}  ---> {{ $.Age }}</li>
    {{ end }}
</ul>
...
  • 檔案目錄結構

    main.go
    └── views
        ├── layouts
        │   ├── layout_test.html
        ├── test.html
  • main.go 程式碼

    package main
    import (
    "github.com/kataras/iris"
    )
    func main() {
    app := iris.New()
    app.RegisterView(iris.HTML("./views", ".html").Reload(true))
    app.Get("/", func(ctx iris.Context) {
        ctx.ViewData("Age", 12)
        ctx.ViewData("Listdata", []struct {
            Title    string
            Nickname string
        }{{Title: "gang", Nickname: "sdfsf"},
            {Title: "gang", Nickname: "sdfsf"}})
        ctx.View("test.html")
    })
    app.Run(iris.Addr(":8080"))
    }
  • layout_test.html 程式碼

    {{ define "headertest" }}
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Hello</title>
    </head>
    <body>
    {{ end }}
    {{ define "footertest" }}
    </body>
    </html>
    {{ end }}
  • test.html 程式碼

    {{ template "headertest" . }}
    <h1>Hello world</h1>
    <ul>
    {{ range .Listdata }}
     <li>{{ .Title }} {{ $.Age }}</li>
    {{ end }}
    </ul>
    {{ template "footertest" . }}
  • 執行

    $ go run main.go 
    Now listening on: http://localhost:8080
    Application started. Press CMD+C to shut down.
  • 瀏覽器

Go HTML/template 模板使用方法

本文介紹只是冰山一角,可能還有其它更好的方法等待著我們發現,在發表本文之前,除了官方doc, 還主要參考了:

物有本末,事有始終,知所先後,則近道矣。

相關文章