天天看點

Go 視圖模闆篇(二):模闆指令

指令用于在 Go 模闆中嵌入指令,通過

{{

}}

來定義,Go 提供了豐富的指令集,包括條件判斷、循環、設定和引入等。

在衆多 Go 模闆指令中,

.

是最重要的一個,它用于解析傳遞到模闆的資料,其他指令和函數大多都是圍繞這個

.

進行格式化和顯示。

1、條件指令

要在視圖模闆中使用 if 條件判斷,可以這麼做:

{{ if arg }} 
    some content 
{{ end }}
           

複制

還可以編寫 if…else… 控制結構語句:

{{ if arg }} 
    some content 
{{ else }}
    other content 
{{ end }}
           

複制

其中

arg

可以是常量、變量、或者傳回某個值的函數或方法。

下面看一個簡單的示例,編寫服務端處理器代碼如下:

package main

import (
    "html/template"
    "math/rand"
    "net/http"
    "time"
)

func process(w http.ResponseWriter, r *http.Request)  {
    t := template.Must(template.ParseFiles("condition.html"))
    rand.Seed(time.Now().Unix())
    t.Execute(w, rand.Intn(10) > 5)
}

func main()  {
    http.HandleFunc("/condition", process)
    http.ListenAndServe(":8080", nil)
}
           

複制

對應的模闆代碼

condition.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Condition Actions</title>
</head>
<body>
    {{ if . }}
        Number is greater than 5!
    {{ else }}
        Number is less than or equal to 5!
    {{ end }}
</body>
</html>
           

複制

運作服務端代碼啟動伺服器,在終端視窗通過 curl 請求

/condition

路由,可以看到對應的傳回結果如下:

Go 視圖模闆篇(二):模闆指令

2、疊代指令

疊代指令可以用于循環疊代數組、切片、字典和通道:

{{ range array }} 
    Dot is set to the element {{ . }} 
{{ end }}
           

複制

編寫一段服務端處理器示例代碼如下:

package main

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

func iterationActionExample( w http.ResponseWriter, r *http.Request)  {
    t := template.Must(template.ParseFiles("iteration.html"))
    daysOfWeek := []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
    t.Execute(w, daysOfWeek)
}

func main() {
    http.HandleFunc("/iteration", iterationActionExample)
    http.ListenAndServe(":8080", nil)
}
           

複制

以及對應的模闆代碼

iteration.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Iteration Actions</title>
</head>
<body>
    <ul>
        {{ range . }}
            <li>{{ . }}</li>
        {{ end }}
    </ul>
</body>
</html>
           

複制

運作服務端代碼啟動伺服器,在浏覽器通路

http://localhost:8080/iteration

,輸出結果如下:

Go 視圖模闆篇(二):模闆指令

可以看到無論是外層的循環體,還是循環體内部的元素,都是通過

.

來替代。如果待疊代的變量為空的話,還可以通過下面這種方式來處理:

<ul>
    {{ range . }}
        <li>{{ . }}</li>
    {{ else }}
        <p>Nothing to show</p>
    {{ end }}
</ul>
           

複制

3、設定指令

此外,在 Go 模闆中,還可以通過

with

指令設定變量值:

{{ with arg }} 
    Dot is set to arg 
{{ end }}
           

複制

這樣一來,在

{{ with arg }}

{{ end }}

之間的

.

會被設定為

arg

我們編寫一段示例代碼進行示範,對應的服務端處理器代碼如下:

package main

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

func setActionExample(w http.ResponseWriter, r *http.Request)  {
    t := template.Must(template.ParseFiles("set.html"))
    t.Execute(w, "golang")
}

func main()  {
    http.HandleFunc("/set_action", setActionExample)
    http.ListenAndServe(":8080", nil)
}
           

複制

對應的模闆檔案

set.html

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Set Action</title>
</head>
<body>
    <div>The dot is {{ . }}</div>
    <div>
        {{ with "php" }}
            Now the dot is set to {{ . }}
        {{ end }}
    </div>
    <div>The dot is {{ . }} again</div>
</body>
</html>
           

複制

運作服務端代碼啟動伺服器,在浏覽器中通路

http://localhost:8080/set_action

,傳回結果如下:

Go 視圖模闆篇(二):模闆指令

同樣,設定指令也支援

else

{{ with arg }} 
    Dot is set to arg 
{{ else }}
    Fallback if arg is empty 
{{ end }}
           

複制

其含義是如果

arg

值為空,則調用

else

區塊對應的邏輯,例如:

{{ with "" }} 
    Dot is set to {{ . }} 
{{ else }}
    Dot is still {{ . }}
{{ end }}
           

複制

4、引入指令

最後,我們還可以通過引入指令來嵌入子模闆:

{{ template "name" }}
           

複制

我們編寫一段服務端處理器示例代碼如下,這裡我們解析了兩個模闆檔案,其中

t1.html

是主模闆,

t2.html

是前者引入的子模闆:

package main

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

func includeActionExample(w http.ResponseWriter, r *http.Request)  {
    t := template.Must(template.ParseFiles("t1.html", "t2.html"))
    t.Execute(w, "Hello World!")
}

func main()  {
    http.HandleFunc("/include", includeActionExample)
    http.ListenAndServe(":8080", nil)
}
           

複制

對應的模闆檔案

t1.html

代碼(主模闆,通過

template

指令引入子模闆

t2.html

):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Template 1</title>
</head>
<body>
    <div> This is t1.html before </div>
    <div> This is the value of the dot in t1.html - [{{ . }}] </div>
    <hr/>
    {{ template "t2.html" }}
    <hr/>
    <div> This is t1.html after </div>
</body>
</html>
           

複制

以及模闆文本

t2.html

代碼(這是一個子模闆):

<div style="background-color: yellow;">
    This is t2.html
    <br/>
    This is the value of the dot in t2.html - [{{ . }}]
</div>
           

複制

運作服務端代碼啟動伺服器,在浏覽器中通路

http://localhost:8080/include

,輸出結果如下:

Go 視圖模闆篇(二):模闆指令

可以看到嵌套模闆中的變量值為空,這是因為我們沒有從第一個模闆将變量傳入第二個模闆,如果要傳入的話可以這麼做:

{{ template "t2.html" . }}
           

複制

這樣就可以在嵌套模闆中看到這個值了:

Go 視圖模闆篇(二):模闆指令

(全文完)