1. 程式人生 > >Go語言生成頁面 -------html/template包

Go語言生成頁面 -------html/template包

官方介紹:
Package template (html/template) implements data-driven templates for generating HTML output safe against code injection. It provides the same interface as package text/template and should be used instead of text/template whenever the output is HTML.

template包(html/template)實現了資料驅動的模板,用於生成可對抗程式碼注入的安全HTML輸出。本包提供了和text/template包相同的介面,無論何時當輸出是HTML的時候都應使用本包。

欄位操作
Go語言的模板通過{{}}來包含需要在渲染時被替換的欄位,{{.}}表示當前的物件。

1<title>{{ .Title }}</title>

輸出巢狀欄位內容

那麼如果欄位裡面還有物件,我們可以使用{{with …}}…{{end}}和{{range …}}{{end}}來進行資料的輸出。


{{ range array }}
    {{ . }}
{{ end }}

{{range $index, $element := array}}
    {{ $index }}
    {{ $element }}
{{ end }}

條件處理

在Go模板裡面如果需要進行條件判斷,那麼我們可以使用和Go語言的if-else語法類似的方式來處理。
if:

{{ if isset .Params "title" }}<h4>{{ index .Params "title" }}</h4>{{ end }}

if …else:

{{ if isset .Params "alt" }}
    {{ index .Params "alt" }}
{{else}}
    {{ index .Params "caption" }}
{{ end }}

and & or:

{{ if and (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}}

with:

{{ with .Params.title }}<h4>{{ . }}</h4>{{ end }}

支援pipe資料


{{. | html}}

{{ if isset .Params "caption" | or isset .Params "title" | or isset .Params "attr" }}
Stuff Here
{{ end }}

模板變數

1 {{with $x := "output" | printf "%q"}}{{$x}}{{end}}

區域性變數的作用域在end前。

模板函式
……
func Must

func Must(t *Template, err error) *Template

模板包裡面有一個函式Must,它的作用是檢測模板是否正確,例如大括號是否匹配,註釋是否正確的關閉,變數是否正確的書寫.

*func (Template) Parse

func (t *Template) Parse(text string) (*Template, error)

進行解析
Parse parses text as a template body for t. Named template definitions ({{define …}} or {{block …}} statements) in text define additional templates associated with t and are removed from the definition of t itself.

*func (Template) Execute

func (t *Template) Execute(wr io.Writer, data interface{}) error
1
執行
Execute applies a parsed template to the specified data object, writing the output to wr. If an error occurs executing the template or writing its output, execution stops, but partial results may already have been written to the output writer. A template may be executed safely in parallel.

*func (Template) ParseFiles


func (t *Template) ParseFiles(filenames ...string) (*Template, error)

通過檔名指定模板:


t := template.New("hello")
template.Must(t.ParseFiles("hello.txt"))
template.Must(t.ParseFiles("world.txt"))
t.ExecuteTemplate(os.Stdout, "world.txt", nil)

簡單應用

程式碼1:

package main

import (
    "os"
    "text/template"
    "fmt"
    )

type Person struct {
    Name string
    nonExportedAgeField string
}

func main() {
    p:= Person{Name: "Mary", nonExportedAgeField: "31"}

    t := template.New("nonexported template demo")
    t, _ = t.Parse("hello {{.Name}}! Age is {{.nonExportedAgeField}}.")
    err := t.Execute(os.Stdout, p)
    if err != nil {
        fmt.Println("There was an error"
    }
}

輸出:
hello Mary! Age is There was an error

是不是有些失望呢,這裡想要提醒大家的是struct中欄位的首字母大寫,才可以匯出!!!
只是把nonExportedAgeField改為NonExportedAgeField即可,得到正確輸出:
hello Mary! Age is 31.

程式碼2:

package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    const tpl = `
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{{.Title}}</title>
    </head>
    <body>
        {{range .Items}}<div>{{ . }}</div>{{else}}<div><strong>no rows</strong></div>{{end}}
    </body>
</html>`

    check := func(err error) {
        if err != nil {
            log.Fatal(err)
        }
    }

    t, err := template.New("webpage").Parse(tpl)
    check(err)

    data := struct {
        Title string
        Items []string
    }{
        Title: "My page",
        Items: []string{
            "My pictures",
            "My dialog",
        },
    }
    err = t.Execute(os.Stdout, data)
    check(err)

    emptyItems := struct {
        Title string
        Items []string
    }{
        Title: "My white page",
        Items: []string{},
    }
    err = t.Execute(os.Stdout, emptyItems)
    check(err)

程式碼3:
從檔案讀取html模板,並且通過伺服器訪問。
首先寫一個todos.html:

<h1>Todos</h1>
<ul>
    {{range .Todos}}
        {{if .Done}}
            <li><s>{{.Task}}</s></li>
        {{else}}
            <li>{{.Task}}</li>
        {{end}}
    {{end}}
</ul>

main.go:

package main

import (
    "html/template"
    "net/http"
)

type Todo struct {
    Task string
    Done bool
}

func main() {
    tmpl := template.Must(template.ParseFiles("todos.html"))
    todos := []Todo{
        {"Learn Go", true},
        {"Read Go Web Examples", true},
        {"Create a web app in Go", false},
    }

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        tmpl.Execute(w, struct{ Todos []Todo }{todos})
    })

    http.ListenAndServe(":8080", nil)
}

*****http://localhost:8080/