Go 视图模板篇(二):模板指令

Go语言精选

共 3833字,需浏览 8分钟

 ·

2020-08-24 07:54

指令用于在 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


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

运行服务端代码启动服务器,在终端窗口通过 curl 请求 /condition 路由,可以看到对应的返回结果如下:

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


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

运行服务端代码启动服务器,在浏览器访问 http://localhost:8080/iteration,输出结果如下:

可以看到无论是外层的循环体,还是循环体内部的元素,都是通过 . 来替代。如果待迭代的变量为空的话,还可以通过下面这种方式来处理:

<ul>
    {{ range . }}
        <li>{{ . }}li>
    {{ else }}
        <p>Nothing to showp>
    {{ 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 代码如下:


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

运行服务端代码启动服务器,在浏览器中访问 http://localhost:8080/set_action,返回结果如下:

同样,设置指令也支持 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):


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Template 1title>
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,输出结果如下:

可以看到嵌套模板中的变量值为空,这是因为我们没有从第一个模板将变量传入第二个模板,如果要传入的话可以这么做:

{{ template "t2.html" . }}

这样就可以在嵌套模板中看到这个值了:

(全文完)



推荐阅读



学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注



浏览 27
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报