Go 视图模板篇(五):模板布局和继承

共 2371字,需浏览 5分钟

 ·

2020-08-26 13:10

模板布局与继承

在 Go 模板中,可以结合 define 指令和 template 指令实现模板布局功能。

首先编写一段服务端示例代码:

package main

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

func layoutExample(w http.ResponseWriter, r *http.Request)  {
    t := template.Must(template.ParseFiles("layout.html"))
    t.ExecuteTemplate(w, "layout""")
}

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

对应的模板文件 layout.html 代码如下,这里我们将子视图模板和布局模板写到一个文件:

{{ define "layout" }}

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Layouttitle>
head>
<body>
    {{ template "content" . }}
body>
html>
{{ end }}

{{ define "content" }}
    Hello World!
{{ end }}

运行服务端代码,在终端窗口通过 curl 访问 /layout 路由,返回结果如下:

当然我们也可以在另一个模板文件中定义 content 子模板,比如 hello.html

{{ define "content" }}
    Hello World!
{{ end }}

然后在 layout.html 中移除 content 的定义,在处理器中增加对 hello.html 的解析:

t := template.Must(template.ParseFiles("layout.html""hello.html"))
t.ExecuteTemplate(w, "layout""")

结果完全一样。

可以看到,通过 define 指令,我们才可以真正实现布局文件的复用,之前那种按照文件名作为模板名的方式在这里显然不适用,因为这样一来,布局文件只能被一个子模板使用。

我们还可以实现一些更高级的玩法:

func layoutExample(w http.ResponseWriter, r *http.Request)  {
    rand.Seed(time.Now().Unix())
    var t *template.Template
    if rand.Intn(10) > 5 {
        t = template.Must(template.ParseFiles("layout.html""hello_blue.html"))
    } else {
        t = template.Must(template.ParseFiles("layout.html""hello_red.html"))
    }
    t.ExecuteTemplate(w, "layout""")
}

新增模板文件 hello_blue.html

{{ define "content" }}
    "color: blue;">Hello World!h1>
{{ end }} 

hello_red.html

{{ define "content" }}
    "color: red;">Hello World!h1>
{{ end }}   

再次运行服务端代码,在浏览器访问 /layout 路由,就可以随机看到红色和蓝色文本了(概率各 50%):

-w667

使用区块指令定义默认模板

我们可以通过 block 指令定义默认区块模板:

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

修改上述 layout.html 代码如下:

{{ define "layout" }}

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Layouttitle>
head>
<body>
    {{ block "content" . }}
        <h1 style="color: red;">Hello World!h1>
    {{ end }}
body>
html>
{{ end }}

然后调整处理器代码:

func layoutExample(w http.ResponseWriter, r *http.Request)  {
    rand.Seed(time.Now().Unix())
    var t *template.Template
    if rand.Intn(10) > 5 {
        t = template.Must(template.ParseFiles("layout.html""hello_blue.html"))
    } else {
        t = template.Must(template.ParseFiles("layout.html"))
    }
    t.ExecuteTemplate(w, "layout""")
}

else 区块没有指定 content 模板,此时由于布局模板中使用 block 指令定义了默认区块内容,所以也能实现同样的效果。

(全文完)



推荐阅读



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


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注


浏览 45
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

分享
举报