首页 文章详情

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

Go语言精选 | 502 2020-08-24 07:54 0 0 0
UniSMS (合一短信)

指令用于在 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爱好者值得关注



good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter