前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 视图模板篇(二):模板指令

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

作者头像
学院君
发布2020-08-20 10:02:49
4550
发布2020-08-20 10:02:49
举报

指令用于在 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 路由,可以看到对应的返回结果如下:

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,输出结果如下:

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

<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,返回结果如下:

同样,设置指令也支持 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,输出结果如下:

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

{{ template "t2.html" . }}

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

(全文完)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 极客书房 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、条件指令
    • 2、迭代指令
      • 3、设置指令
        • 4、引入指令
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档