Go語言標準庫之template

更新、更全的《Go從入門到放棄》的更新網站,更有python、go、人工智能教學等着你:http://www.javashuo.com/article/p-mxrjjcnn-hn.htmlpython

html/template包實現了數據驅動的模板,用於生成可對抗代碼注入的安全HTML輸出。它提供了和text/template包相同的接口,Go語言中輸出HTML的場景都應使用text/template包。後端

1、模板

在基於MVC的Web架構中,咱們一般須要在後端渲染一些數據到HTML文件中,從而實現動態的網頁效果。數組

2、模板示例

經過將模板應用於一個數據結構(即該數據結構做爲模板的參數)來執行,來得到輸出。模板中的註釋引用數據接口的元素(通常如結構體的字段或者字典的鍵)來控制執行過程和獲取須要呈現的值。模板執行時會遍歷結構並將指針表示爲’.‘(稱之爲」dot」)指向運行過程當中數據結構的當前位置的值。安全

用做模板的輸入文本必須是utf-8編碼的文本。」Action」—數據運算和控制單位—由」{{「和」}}「界定;在Action以外的全部文本都不作修改的拷貝到輸出中。Action內部不能有換行,但註釋能夠有換行。數據結構

HTML文件代碼以下:架構

函數

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hello</title>
</head>
<body>
<p>Hello {{.}}</p>
</body>
</html>
```

咱們的HTTP server端代碼以下:測試

// main.go

func sayHello(w http.ResponseWriter, r *http.Request) {
    // 解析指定文件生成模板對象
    tmpl, err := template.ParseFiles(&quot;./hello.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    // 利用給定數據渲染模板,並將結果寫入w
    tmpl.Execute(w, &quot;沙河小王子&quot;)
}
func main() {
    http.HandleFunc(&quot;/&quot;, sayHello)
    err := http.ListenAndServe(&quot;:9090&quot;, nil)
    if err != nil {
        fmt.Println(&quot;HTTP server failed,err:&quot;, err)
        return
    }
}

模板語法

{{.}}

模板語法都包含在{{}}中間,其中{{.}}中的點表示當前對象。網站

當咱們傳入一個結構體對象時,咱們能夠根據.來訪問結構體的對應字段。例如:

// main.go

type UserInfo struct {
    Name   string
    Gender string
    Age    int
}

func sayHello(w http.ResponseWriter, r *http.Request) {
    // 解析指定文件生成模板對象
    tmpl, err := template.ParseFiles(&quot;./hello.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    // 利用給定數據渲染模板,並將結果寫入w
    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    tmpl.Execute(w, user)
}

HTML文件代碼以下:

// main.go func sayHello(w http.ResponseWriter, r *http.Request) { // 解析指定文件生成模板對象 tmpl, err := template.ParseFiles(&quot;./hello.html&quot;) if err != nil { fmt.Println(&quot;create template failed, err:&quot;, err) return } // 利用給定數據渲染模板,並將結果寫入w tmpl.Execute(w, &quot;沙河小王子&quot;) } func main() { http.HandleFunc(&quot;/&quot;, sayHello) err := http.ListenAndServe(&quot;:9090&quot;, nil) if err != nil { fmt.Println(&quot;HTTP server failed,err:&quot;, err) return } }{{}}{{.}}.// main.go type UserInfo struct { Name string Gender string Age int } func sayHello(w http.ResponseWriter, r *http.Request) { // 解析指定文件生成模板對象 tmpl, err := template.ParseFiles(&quot;./hello.html&quot;) if err != nil { fmt.Println(&quot;create template failed, err:&quot;, err) return } // 利用給定數據渲染模板,並將結果寫入w user := UserInfo{ Name: &quot;小王子&quot;, Gender: &quot;男&quot;, Age: 18, } tmpl.Execute(w, user) }

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hello</title>
</head>
<body>
<p>Hello {{.Name}}</p>
<p>性別:{{.Gender}}</p>
<p>年齡:{{.Name}}</p>
</body>
</html>


<p>同理,當咱們傳入的變量是map時,也能夠在模板文件中經過<code>.</code>根據key來取值。</p>

## 2.1 註釋


<pre><code class="language-template">{{/* a comment */}}
註釋,執行時會忽略。能夠多行。註釋不能嵌套,而且必須緊貼分界符始止。

pipeline

pipeline是指產生數據的操做。好比{{.}}{{.Name}}等。Go的模板語法中支持使用管道符號|連接多個命令,用法和unix下的管道相似:|前面的命令會將運算結果(或返回值)傳遞給後一個命令的最後一個位置。

注意:並非只有使用了|纔是pipeline。Go的模板語法中,pipeline的概念是傳遞數據,只要能產生數據的,都是pipeline

變量

Action裏能夠初始化一個變量來捕獲管道的執行結果。初始化語法以下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hello</title>
</head>
<body>
<p>Hello {{.Name}}</p>
<p>性別:{{.Gender}}</p>
<p>年齡:{{.Name}}</p>
</body>
</html>

<p>同理,當咱們傳入的變量是map時,也能夠在模板文件中經過<code>.</code>根據key來取值。</p>

## 2.1 註釋


<pre><code class="language-template">{{/* a comment */}}
註釋,執行時會忽略。能夠多行。註釋不能嵌套,而且必須緊貼分界符始止。

pipeline

pipeline是指產生數據的操做。好比{{.}}{{.Name}}等。Go的模板語法中支持使用管道符號|連接多個命令,用法和unix下的管道相似:|前面的命令會將運算結果(或返回值)傳遞給後一個命令的最後一個位置。

注意:並非只有使用了|纔是pipeline。Go的模板語法中,pipeline的概念是傳遞數據,只要能產生數據的,都是pipeline

變量

Action裏能夠初始化一個變量來捕獲管道的執行結果。初始化語法以下:

<p>同理,當咱們傳入的變量是map時,也能夠在模板文件中經過<code>.</code>根據key來取值。</p> ## 2.1 註釋 <pre><code class="language-template">{{/* a comment */}} 註釋,執行時會忽略。能夠多行。註釋不能嵌套,而且必須緊貼分界符始止。pipeline{{.}}{{.Name}}|||pipeline的pipeline

$variable := pipeline


<p>其中$variable是變量的名字。聲明變量的action不會產生任何輸出。</p>

## 2.2 條件判斷


<p>Go模板語法中的條件判斷有如下幾種:</p>

<pre><code class="language-template">{{if pipeline}} T1 {{end}}

{{if pipeline}} T1 {{else}} T0 {{end}}

{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}

range

Go的模板語法中使用range關鍵字進行遍歷,有如下兩種寫法,其中pipeline的值必須是數組、切片、字典或者通道。

$variable := pipeline


<p>其中$variable是變量的名字。聲明變量的action不會產生任何輸出。</p>

## 2.2 條件判斷


<p>Go模板語法中的條件判斷有如下幾種:</p>

<pre><code class="language-template">{{if pipeline}} T1 {{end}}

{{if pipeline}} T1 {{else}} T0 {{end}}

{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}

range

Go的模板語法中使用range關鍵字進行遍歷,有如下兩種寫法,其中pipeline的值必須是數組、切片、字典或者通道。

$variable := pipeline

<p>其中$variable是變量的名字。聲明變量的action不會產生任何輸出。</p>

## 2.2 條件判斷


<p>Go模板語法中的條件判斷有如下幾種:</p>

<pre><code class="language-template">{{if pipeline}} T1 {{end}}

{{if pipeline}} T1 {{else}} T0 {{end}}

{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}

range

Go的模板語法中使用range關鍵字進行遍歷,有如下兩種寫法,其中pipeline的值必須是數組、切片、字典或者通道。

<p>其中$variable是變量的名字。聲明變量的action不會產生任何輸出。</p> ## 2.2 條件判斷 <p>Go模板語法中的條件判斷有如下幾種:</p> <pre><code class="language-template">{{if pipeline}} T1 {{end}} {{if pipeline}} T1 {{else}} T0 {{end}} {{if pipeline}} T1 {{else if pipeline}} T0 {{end}}rangepipeline

{{range pipeline}} T1 {{end}}
若是pipeline的值其長度爲0,不會有任何輸出

{{range pipeline}} T1 {{else}} T0 {{end}}
若是pipeline的值其長度爲0,則會執行T0。


## 2.3 with


<pre><code class="language-template">{{with pipeline}} T1 {{end}}
若是pipeline爲empty不產生輸出,不然將dot設爲pipeline的值並執行T1。不修改外面的dot。

{{with pipeline}} T1 {{else}} T0 {{end}}
若是pipeline爲empty,不改變dot並執行T0,不然dot設爲pipeline的值並執行T1。

預約義函數

執行模板時,函數從兩個函數字典中查找:首先是模板函數字典,而後是全局函數字典。通常不在模板內定義函數,而是使用Funcs方法添加函數到模板裏。

預約義的全局函數以下:

and
函數返回它的第一個empty參數或者最後一個參數;
就是說"and x y"等價於"if x then y else x";全部參數都會執行;
or
返回第一個非empty參數或者最後一個參數;
亦即"or x y"等價於"if x then x else y";全部參數都會執行;
not
返回它的單個參數的布爾值的否認
len
返回它的參數的整數類型長度
index
執行結果爲第一個參數以剩下的參數爲索引/鍵指向的值;
如"index x 1 2 3"返回x[1][2][3]的值;每一個被索引的主體必須是數組、切片或者字典。
print
即fmt.Sprint
printf
即fmt.Sprintf
println
即fmt.Sprintln
html
返回其參數文本表示的HTML逸碼等價表示。
urlquery
返回其參數文本表示的可嵌入URL查詢的逸碼等價表示。
js
返回其參數文本表示的JavaScript逸碼等價表示。
call
執行結果是調用第一個參數的返回值,該參數必須是函數類型,其他參數做爲調用該函數的參數;
如"call .X.Y 1 2"等價於go語言裏的dot.X.Y(1, 2);
其中Y是函數類型的字段或者字典的值,或者其餘相似狀況;
call的第一個參數的執行結果必須是函數類型的值(和預約義函數如print明顯不一樣);
該函數類型值必須有1到2個返回值,若是有2個則後一個必須是error接口類型;
若是有2個返回值的方法返回的error非nil,模板執行會中斷並返回給調用模板執行者該錯誤;


## 2.4 比較函數


<p>布爾函數會將任何類型的零值視爲假,其他視爲真。</p>

<p>下面是定義爲函數的二元比較運算的集合:</p>

<pre><code class="language-template">eq      若是arg1 == arg2則返回真
ne      若是arg1 != arg2則返回真
lt      若是arg1 &lt; arg2則返回真
le      若是arg1 &lt;= arg2則返回真
gt      若是arg1 &gt; arg2則返回真
ge      若是arg1 &gt;= arg2則返回真

爲了簡化多參數相等檢測,eq(只有eq)能夠接受2個或更多個參數,它會將第一個參數和其他參數依次比較,返回下式的結果:

{{eq arg1 arg2 arg3}}
```

比較函數只適用於基本類型(或重定義的基本類型,如」type Celsius float32」)。可是,整數和浮點數不能互相比較。

2.5 自定義函數

Go的模板支持自定義函數。

func sayHello(w http.ResponseWriter, r *http.Request) {
    htmlByte, err := ioutil.ReadFile(&quot;./hello.html&quot;)
    if err != nil {
        fmt.Println(&quot;read html failed, err:&quot;, err)
        return
    }
    // 自定義一個夸人的模板函數
    kua := func(arg string) (string, error) {
        return arg + &quot;真帥&quot;, nil
    }
    // 採用鏈式操做在Parse以前調用Funcs添加自定義的kua函數
    tmpl, err := template.New(&quot;hello&quot;).Funcs(template.FuncMap{&quot;kua&quot;: kua}).Parse(string(htmlByte))
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }

    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    // 使用user渲染模板,並將結果寫入w
    tmpl.Execute(w, user)
}

咱們能夠在模板文件hello.html中使用咱們自定義的kua函數了。

{{kua .Name}}


## 嵌套template

<p>咱們能夠在template中嵌套其餘的template。這個template能夠是單獨的文件,也能夠是經過<code>define</code>定義的template。</p>

<p>舉個例子:
t.html文件內容以下:</p>

<pre><code class="language-template">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;tmpl test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;h1&gt;測試嵌套template語法&lt;/h1&gt;
    &lt;hr&gt;
    {{template &quot;ul.html&quot;}}
    &lt;hr&gt;
    {{template &quot;ol.html&quot;}}
&lt;/body&gt;
&lt;/html&gt;

{{ define &quot;ol.html&quot;}}
&lt;h1&gt;這是ol.html&lt;/h1&gt;
&lt;ol&gt;
    &lt;li&gt;吃飯&lt;/li&gt;
    &lt;li&gt;睡覺&lt;/li&gt;
    &lt;li&gt;打豆豆&lt;/li&gt;
&lt;/ol&gt;
{{end}}

ul.html文件內容以下:

<ul>
<li>註釋</li>
<li>日誌</li>
<li>測試</li>
</ul>
```

咱們註冊一個templDemo路由處理函數.

http.HandleFunc(&quot;/tmpl&quot;, tmplDemo)

tmplDemo函數的具體內容以下:

func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles(&quot;./t.html&quot;, &quot;./ul.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    tmpl.Execute(w, user)
}

{{range pipeline}} T1 {{end}}
若是pipeline的值其長度爲0,不會有任何輸出

{{range pipeline}} T1 {{else}} T0 {{end}}
若是pipeline的值其長度爲0,則會執行T0。


## 2.3 with


<pre><code class="language-template">{{with pipeline}} T1 {{end}}
若是pipeline爲empty不產生輸出,不然將dot設爲pipeline的值並執行T1。不修改外面的dot。

{{with pipeline}} T1 {{else}} T0 {{end}}
若是pipeline爲empty,不改變dot並執行T0,不然dot設爲pipeline的值並執行T1。

預約義函數

執行模板時,函數從兩個函數字典中查找:首先是模板函數字典,而後是全局函數字典。通常不在模板內定義函數,而是使用Funcs方法添加函數到模板裏。

預約義的全局函數以下:

{{range pipeline}} T1 {{end}}
若是pipeline的值其長度爲0,不會有任何輸出

{{range pipeline}} T1 {{else}} T0 {{end}}
若是pipeline的值其長度爲0,則會執行T0。


## 2.3 with


<pre><code class="language-template">{{with pipeline}} T1 {{end}}
若是pipeline爲empty不產生輸出,不然將dot設爲pipeline的值並執行T1。不修改外面的dot。

{{with pipeline}} T1 {{else}} T0 {{end}}
若是pipeline爲empty,不改變dot並執行T0,不然dot設爲pipeline的值並執行T1。

預約義函數

執行模板時,函數從兩個函數字典中查找:首先是模板函數字典,而後是全局函數字典。通常不在模板內定義函數,而是使用Funcs方法添加函數到模板裏。

預約義的全局函數以下:

## 2.3 with <pre><code class="language-template">{{with pipeline}} T1 {{end}} 若是pipeline爲empty不產生輸出,不然將dot設爲pipeline的值並執行T1。不修改外面的dot。 {{with pipeline}} T1 {{else}} T0 {{end}} 若是pipeline爲empty,不改變dot並執行T0,不然dot設爲pipeline的值並執行T1。

and
函數返回它的第一個empty參數或者最後一個參數;
就是說"and x y"等價於"if x then y else x";全部參數都會執行;
or
返回第一個非empty參數或者最後一個參數;
亦即"or x y"等價於"if x then x else y";全部參數都會執行;
not
返回它的單個參數的布爾值的否認
len
返回它的參數的整數類型長度
index
執行結果爲第一個參數以剩下的參數爲索引/鍵指向的值;
如"index x 1 2 3"返回x[1][2][3]的值;每一個被索引的主體必須是數組、切片或者字典。
print
即fmt.Sprint
printf
即fmt.Sprintf
println
即fmt.Sprintln
html
返回其參數文本表示的HTML逸碼等價表示。
urlquery
返回其參數文本表示的可嵌入URL查詢的逸碼等價表示。
js
返回其參數文本表示的JavaScript逸碼等價表示。
call
執行結果是調用第一個參數的返回值,該參數必須是函數類型,其他參數做爲調用該函數的參數;
如"call .X.Y 1 2"等價於go語言裏的dot.X.Y(1, 2);
其中Y是函數類型的字段或者字典的值,或者其餘相似狀況;
call的第一個參數的執行結果必須是函數類型的值(和預約義函數如print明顯不一樣);
該函數類型值必須有1到2個返回值,若是有2個則後一個必須是error接口類型;
若是有2個返回值的方法返回的error非nil,模板執行會中斷並返回給調用模板執行者該錯誤;


## 2.4 比較函數


<p>布爾函數會將任何類型的零值視爲假,其他視爲真。</p>

<p>下面是定義爲函數的二元比較運算的集合:</p>

<pre><code class="language-template">eq      若是arg1 == arg2則返回真
ne      若是arg1 != arg2則返回真
lt      若是arg1 &lt; arg2則返回真
le      若是arg1 &lt;= arg2則返回真
gt      若是arg1 &gt; arg2則返回真
ge      若是arg1 &gt;= arg2則返回真

爲了簡化多參數相等檢測,eq(只有eq)能夠接受2個或更多個參數,它會將第一個參數和其他參數依次比較,返回下式的結果:

{{eq arg1 arg2 arg3}}
```

比較函數只適用於基本類型(或重定義的基本類型,如」type Celsius float32」)。可是,整數和浮點數不能互相比較。

2.5 自定義函數

Go的模板支持自定義函數。

func sayHello(w http.ResponseWriter, r *http.Request) {
    htmlByte, err := ioutil.ReadFile(&quot;./hello.html&quot;)
    if err != nil {
        fmt.Println(&quot;read html failed, err:&quot;, err)
        return
    }
    // 自定義一個夸人的模板函數
    kua := func(arg string) (string, error) {
        return arg + &quot;真帥&quot;, nil
    }
    // 採用鏈式操做在Parse以前調用Funcs添加自定義的kua函數
    tmpl, err := template.New(&quot;hello&quot;).Funcs(template.FuncMap{&quot;kua&quot;: kua}).Parse(string(htmlByte))
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }

    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    // 使用user渲染模板,並將結果寫入w
    tmpl.Execute(w, user)
}

咱們能夠在模板文件hello.html中使用咱們自定義的kua函數了。

{{kua .Name}}


## 嵌套template

<p>咱們能夠在template中嵌套其餘的template。這個template能夠是單獨的文件,也能夠是經過<code>define</code>定義的template。</p>

<p>舉個例子:
t.html文件內容以下:</p>

<pre><code class="language-template">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;tmpl test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;h1&gt;測試嵌套template語法&lt;/h1&gt;
    &lt;hr&gt;
    {{template &quot;ul.html&quot;}}
    &lt;hr&gt;
    {{template &quot;ol.html&quot;}}
&lt;/body&gt;
&lt;/html&gt;

{{ define &quot;ol.html&quot;}}
&lt;h1&gt;這是ol.html&lt;/h1&gt;
&lt;ol&gt;
    &lt;li&gt;吃飯&lt;/li&gt;
    &lt;li&gt;睡覺&lt;/li&gt;
    &lt;li&gt;打豆豆&lt;/li&gt;
&lt;/ol&gt;
{{end}}

ul.html文件內容以下:

<ul>
<li>註釋</li>
<li>日誌</li>
<li>測試</li>
</ul>
```

咱們註冊一個templDemo路由處理函數.

http.HandleFunc(&quot;/tmpl&quot;, tmplDemo)

tmplDemo函數的具體內容以下:

func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles(&quot;./t.html&quot;, &quot;./ul.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    tmpl.Execute(w, user)
}
and
函數返回它的第一個empty參數或者最後一個參數;
就是說"and x y"等價於"if x then y else x";全部參數都會執行;
or
返回第一個非empty參數或者最後一個參數;
亦即"or x y"等價於"if x then x else y";全部參數都會執行;
not
返回它的單個參數的布爾值的否認
len
返回它的參數的整數類型長度
index
執行結果爲第一個參數以剩下的參數爲索引/鍵指向的值;
如"index x 1 2 3"返回x[1][2][3]的值;每一個被索引的主體必須是數組、切片或者字典。
print
即fmt.Sprint
printf
即fmt.Sprintf
println
即fmt.Sprintln
html
返回其參數文本表示的HTML逸碼等價表示。
urlquery
返回其參數文本表示的可嵌入URL查詢的逸碼等價表示。
js
返回其參數文本表示的JavaScript逸碼等價表示。
call
執行結果是調用第一個參數的返回值,該參數必須是函數類型,其他參數做爲調用該函數的參數;
如"call .X.Y 1 2"等價於go語言裏的dot.X.Y(1, 2);
其中Y是函數類型的字段或者字典的值,或者其餘相似狀況;
call的第一個參數的執行結果必須是函數類型的值(和預約義函數如print明顯不一樣);
該函數類型值必須有1到2個返回值,若是有2個則後一個必須是error接口類型;
若是有2個返回值的方法返回的error非nil,模板執行會中斷並返回給調用模板執行者該錯誤;

## 2.4 比較函數


<p>布爾函數會將任何類型的零值視爲假,其他視爲真。</p>

<p>下面是定義爲函數的二元比較運算的集合:</p>

<pre><code class="language-template">eq      若是arg1 == arg2則返回真
ne      若是arg1 != arg2則返回真
lt      若是arg1 &lt; arg2則返回真
le      若是arg1 &lt;= arg2則返回真
gt      若是arg1 &gt; arg2則返回真
ge      若是arg1 &gt;= arg2則返回真

爲了簡化多參數相等檢測,eq(只有eq)能夠接受2個或更多個參數,它會將第一個參數和其他參數依次比較,返回下式的結果:

{{eq arg1 arg2 arg3}}
```

比較函數只適用於基本類型(或重定義的基本類型,如」type Celsius float32」)。可是,整數和浮點數不能互相比較。

2.5 自定義函數

Go的模板支持自定義函數。

func sayHello(w http.ResponseWriter, r *http.Request) {
    htmlByte, err := ioutil.ReadFile(&quot;./hello.html&quot;)
    if err != nil {
        fmt.Println(&quot;read html failed, err:&quot;, err)
        return
    }
    // 自定義一個夸人的模板函數
    kua := func(arg string) (string, error) {
        return arg + &quot;真帥&quot;, nil
    }
    // 採用鏈式操做在Parse以前調用Funcs添加自定義的kua函數
    tmpl, err := template.New(&quot;hello&quot;).Funcs(template.FuncMap{&quot;kua&quot;: kua}).Parse(string(htmlByte))
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }

    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    // 使用user渲染模板,並將結果寫入w
    tmpl.Execute(w, user)
}

咱們能夠在模板文件hello.html中使用咱們自定義的kua函數了。

{{kua .Name}}


## 嵌套template

<p>咱們能夠在template中嵌套其餘的template。這個template能夠是單獨的文件,也能夠是經過<code>define</code>定義的template。</p>

<p>舉個例子:
t.html文件內容以下:</p>

<pre><code class="language-template">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;tmpl test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;h1&gt;測試嵌套template語法&lt;/h1&gt;
    &lt;hr&gt;
    {{template &quot;ul.html&quot;}}
    &lt;hr&gt;
    {{template &quot;ol.html&quot;}}
&lt;/body&gt;
&lt;/html&gt;

{{ define &quot;ol.html&quot;}}
&lt;h1&gt;這是ol.html&lt;/h1&gt;
&lt;ol&gt;
    &lt;li&gt;吃飯&lt;/li&gt;
    &lt;li&gt;睡覺&lt;/li&gt;
    &lt;li&gt;打豆豆&lt;/li&gt;
&lt;/ol&gt;
{{end}}

ul.html文件內容以下:

<ul>
<li>註釋</li>
<li>日誌</li>
<li>測試</li>
</ul>
```

咱們註冊一個templDemo路由處理函數.

http.HandleFunc(&quot;/tmpl&quot;, tmplDemo)

tmplDemo函數的具體內容以下:

func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles(&quot;./t.html&quot;, &quot;./ul.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    tmpl.Execute(w, user)
}
## 2.4 比較函數 <p>布爾函數會將任何類型的零值視爲假,其他視爲真。</p> <p>下面是定義爲函數的二元比較運算的集合:</p> <pre><code class="language-template">eq 若是arg1 == arg2則返回真 ne 若是arg1 != arg2則返回真 lt 若是arg1 &lt; arg2則返回真 le 若是arg1 &lt;= arg2則返回真 gt 若是arg1 &gt; arg2則返回真 ge 若是arg1 &gt;= arg2則返回真{{eq arg1 arg2 arg3}}
```

比較函數只適用於基本類型(或重定義的基本類型,如」type Celsius float32」)。可是,整數和浮點數不能互相比較。

2.5 自定義函數

Go的模板支持自定義函數。

func sayHello(w http.ResponseWriter, r *http.Request) {
    htmlByte, err := ioutil.ReadFile(&quot;./hello.html&quot;)
    if err != nil {
        fmt.Println(&quot;read html failed, err:&quot;, err)
        return
    }
    // 自定義一個夸人的模板函數
    kua := func(arg string) (string, error) {
        return arg + &quot;真帥&quot;, nil
    }
    // 採用鏈式操做在Parse以前調用Funcs添加自定義的kua函數
    tmpl, err := template.New(&quot;hello&quot;).Funcs(template.FuncMap{&quot;kua&quot;: kua}).Parse(string(htmlByte))
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }

    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    // 使用user渲染模板,並將結果寫入w
    tmpl.Execute(w, user)
}

咱們能夠在模板文件hello.html中使用咱們自定義的kua函數了。

{{kua .Name}}


## 嵌套template

<p>咱們能夠在template中嵌套其餘的template。這個template能夠是單獨的文件,也能夠是經過<code>define</code>定義的template。</p>

<p>舉個例子:
t.html文件內容以下:</p>

<pre><code class="language-template">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;tmpl test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;h1&gt;測試嵌套template語法&lt;/h1&gt;
    &lt;hr&gt;
    {{template &quot;ul.html&quot;}}
    &lt;hr&gt;
    {{template &quot;ol.html&quot;}}
&lt;/body&gt;
&lt;/html&gt;

{{ define &quot;ol.html&quot;}}
&lt;h1&gt;這是ol.html&lt;/h1&gt;
&lt;ol&gt;
    &lt;li&gt;吃飯&lt;/li&gt;
    &lt;li&gt;睡覺&lt;/li&gt;
    &lt;li&gt;打豆豆&lt;/li&gt;
&lt;/ol&gt;
{{end}}

ul.html文件內容以下:

<ul>
<li>註釋</li>
<li>日誌</li>
<li>測試</li>
</ul>
```

咱們註冊一個templDemo路由處理函數.

http.HandleFunc(&quot;/tmpl&quot;, tmplDemo)

tmplDemo函數的具體內容以下:

func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles(&quot;./t.html&quot;, &quot;./ul.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    tmpl.Execute(w, user)
}
func sayHello(w http.ResponseWriter, r *http.Request) { htmlByte, err := ioutil.ReadFile(&quot;./hello.html&quot;) if err != nil { fmt.Println(&quot;read html failed, err:&quot;, err) return } // 自定義一個夸人的模板函數 kua := func(arg string) (string, error) { return arg + &quot;真帥&quot;, nil } // 採用鏈式操做在Parse以前調用Funcs添加自定義的kua函數 tmpl, err := template.New(&quot;hello&quot;).Funcs(template.FuncMap{&quot;kua&quot;: kua}).Parse(string(htmlByte)) if err != nil { fmt.Println(&quot;create template failed, err:&quot;, err) return } user := UserInfo{ Name: &quot;小王子&quot;, Gender: &quot;男&quot;, Age: 18, } // 使用user渲染模板,並將結果寫入w tmpl.Execute(w, user) }hello.htmlkua{{kua .Name}}

## 嵌套template

<p>咱們能夠在template中嵌套其餘的template。這個template能夠是單獨的文件,也能夠是經過<code>define</code>定義的template。</p>

<p>舉個例子:
t.html文件內容以下:</p>

<pre><code class="language-template">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;tmpl test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    
    &lt;h1&gt;測試嵌套template語法&lt;/h1&gt;
    &lt;hr&gt;
    {{template &quot;ul.html&quot;}}
    &lt;hr&gt;
    {{template &quot;ol.html&quot;}}
&lt;/body&gt;
&lt;/html&gt;

{{ define &quot;ol.html&quot;}}
&lt;h1&gt;這是ol.html&lt;/h1&gt;
&lt;ol&gt;
    &lt;li&gt;吃飯&lt;/li&gt;
    &lt;li&gt;睡覺&lt;/li&gt;
    &lt;li&gt;打豆豆&lt;/li&gt;
&lt;/ol&gt;
{{end}}

ul.html文件內容以下:

<ul>
<li>註釋</li>
<li>日誌</li>
<li>測試</li>
</ul>
```

咱們註冊一個templDemo路由處理函數.

http.HandleFunc(&quot;/tmpl&quot;, tmplDemo)

tmplDemo函數的具體內容以下:

func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles(&quot;./t.html&quot;, &quot;./ul.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    tmpl.Execute(w, user)
}
## 嵌套template <p>咱們能夠在template中嵌套其餘的template。這個template能夠是單獨的文件,也能夠是經過<code>define</code>定義的template。</p> <p>舉個例子: t.html文件內容以下:</p> <pre><code class="language-template">&lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt; &lt;head&gt; &lt;meta charset=&quot;UTF-8&quot;&gt; &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt; &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt; &lt;title&gt;tmpl test&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;測試嵌套template語法&lt;/h1&gt; &lt;hr&gt; {{template &quot;ul.html&quot;}} &lt;hr&gt; {{template &quot;ol.html&quot;}} &lt;/body&gt; &lt;/html&gt; {{ define &quot;ol.html&quot;}} &lt;h1&gt;這是ol.html&lt;/h1&gt; &lt;ol&gt; &lt;li&gt;吃飯&lt;/li&gt; &lt;li&gt;睡覺&lt;/li&gt; &lt;li&gt;打豆豆&lt;/li&gt; &lt;/ol&gt; {{end}}<ul>
<li>註釋</li>
<li>日誌</li>
<li>測試</li>
</ul>
```

咱們註冊一個templDemo路由處理函數.

http.HandleFunc(&quot;/tmpl&quot;, tmplDemo)

tmplDemo函數的具體內容以下:

func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles(&quot;./t.html&quot;, &quot;./ul.html&quot;)
    if err != nil {
        fmt.Println(&quot;create template failed, err:&quot;, err)
        return
    }
    user := UserInfo{
        Name:   &quot;小王子&quot;,
        Gender: &quot;男&quot;,
        Age:    18,
    }
    tmpl.Execute(w, user)
}
templDemohttp.HandleFunc(&quot;/tmpl&quot;, tmplDemo)tmplDemofunc tmplDemo(w http.ResponseWriter, r *http.Request) { tmpl, err := template.ParseFiles(&quot;./t.html&quot;, &quot;./ul.html&quot;) if err != nil { fmt.Println(&quot;create template failed, err:&quot;, err) return } user := UserInfo{ Name: &quot;小王子&quot;, Gender: &quot;男&quot;, Age: 18, } tmpl.Execute(w, user) }
相關文章
相關標籤/搜索