本文介绍: 在一些前后端不分离的Web架构中,我们通常需要在后端将一些数据渲染到HTML文档中,从而实现动态的网页(网页的布局和样式大致一样,但展示的内容并不一样)效果。我们这里说的模板可以理解为事先定义好的HTML文档文件,模板渲染的作用机制可以简单理解为文本替换操作–使用相应的数据去替换HTML文档中事先准备好的标记。Go语言内置了文本模板引擎text/template和用于HTML文档的html/template。

1 模板语法

在一些前后端不分离的Web架构中,我们通常需要在后端将一些数据渲染到HTML文档中,从而实现动态的网页(网页的布局和样式大致一样,但展示的内容并不一样)效果。我们这里说的模板可以理解为事先定义好的HTML文档文件,模板渲染的作用机制可以简单理解为文本替换操作–使用相应的数据去替换HTML文档中事先准备好的标记。

Go语言内置了文本模板引擎text/template和用于HTML文档的html/template。它们的作用机制可以简单归纳如下:

1 模板文件通常定义为.tmpl和.tpl为后缀(也可以使用其他的后缀),必须使用UTF8编码。
2 模板文件中使用{{和}}包裹和标识需要传入的数据。
3 传给模板这样的数据就可以通过点号 ‘.’ 来访问,如果数据是复杂类型的数据,可以通过{ { .FieldName }}来访问它的字段。除{{和}}包裹的内容外,其他内容均不做修改原样输出。

1.1 Hello World

在这里插入图片描述

package main

import (
	"fmt"
	"net/http"
	"text/template"
)

func main() {

	http.HandleFunc("/hello", hello)
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Printf("HTTP server start failed, err :  %v", err)
		return
	}

}

func hello(w http.ResponseWriter, r *http.Request) {

	//解析模板
	t, err := template.ParseFiles("./template/html/hello.html")
	if err != nil {
		fmt.Printf("parse template failed, err: %v n", err)
	}
	//渲染模板
	t.Execute(w, "Hello Template")

}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>


<h1>{{.}}</h1>

</body>
</html>

在这里插入图片描述

1.2 解析结构体

package main

import (
	"fmt"
	"net/http"
	"text/template"
)

type User struct {
	Name string
	Age  int
}

func main() {

	http.HandleFunc("/hello", hello)
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Printf("HTTP server start failed, err :  %v", err)
		return
	}

}

func hello(w http.ResponseWriter, r *http.Request) {

	//解析模板
	t, err := template.ParseFiles("./template/html/hello.html")
	if err != nil {
		fmt.Printf("parse template failed, err: %v n", err)
	}
	//创建数据
	u1 := User{"Kobe", 18}
	u2 := User{"James", 18}
	rs := map[string]interface{}{
		"u1": u1,
		"u2": u2,
	}

	//渲染模板
	t.Execute(w, rs)
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>


<h1>姓名:{{.u1.Name}}   年龄:{{.u1.Age}}</h1>
<h1>姓名:{{.u2.Name}}   年龄:{{.u2.Age}}</h1>

</body>
</html>3  解析循环

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1qFvQAiZ-1665390828624)(go web.assets/image-20221010161716381.png)]

1.3 解析切片

package main

import (
	"fmt"
	"net/http"
	"text/template"
)

type User struct {
	Name string
	Age  int
}

func main() {

	http.HandleFunc("/hello", hello)
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Printf("HTTP server start failed, err :  %v", err)
		return
	}

}

func hello(w http.ResponseWriter, r *http.Request) {

	//解析模板
	t, err := template.ParseFiles("./template/html/hello.html")
	if err != nil {
		fmt.Printf("parse template failed, err: %v n", err)
	}
	//创建数据
	u1 := User{"Kobe", 18}
	u2 := User{"James", 18}
	users := []User{u1, u2}

	rs := map[string]interface{}{
		"users":  users,
		"counts": len(users),
	}

	//渲染模板
	t.Execute(w, rs)
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>

{{if  gt .counts  0}}
<p style="color: lightskyblue">展示数据:</p>
{{else}}
<p style="color: lightskyblue">没有数据:</p>
{{end}}


{{range $index,$user := .users}}
<h2 style="color: red"> index:{{$index}}, name:{{$user.Name}}, age:{{$user.Age}} </h2>
{{end}}


</body>
</html>

在这里插入图片描述

2 模板嵌套

我们可以在template中嵌套其他的template。这个template可以是单独的文件,也可以是通过define定义的template。

在这里插入图片描述

package main

import (
	"fmt"
	"net/http"
	"text/template"
)

type PageInfo struct {
	Title   string
	Content string
}

func main() {
	http.HandleFunc("/index", index)
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Printf("HTTP server start failed, err :  %v", err)
		return
	}
}

func index(w http.ResponseWriter, r *http.Request) {
	//定义模板,先模板
	t, _ := template.ParseFiles("./template/html/hello.html", "./template/tmpl/head_tmpl.html", "./template/tmpl/foot_tmpl.html")
	//数据
	data := make(map[string]string)
	data["body"] = "Hello GoLang"
	data["head"] = "COMMON HEAD"
	data["foot"] = "COMMON FOOT"
	//渲染
	_ = t.ExecuteTemplate(w, "hello.html", data)
}

hello.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>hello</title>
</head>
<body>


{{template "head_tmpl.html" . }}
{{.body}}
{{template "foot_tmpl.html" . }}


</body>
</html>

head_tmpl.html、foot_tmpl.html:

<div style="height: 200px;width: 100%;background: lightgreen;font-size: 20px;">
    {{.head}}
</div>

<div style="height: 200px;width: 100%;background: lightcoral;font-size: 20px;">
    {{.foot}}
</div>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tBvmfuxv-1665390828625)(go web.assets/image-20221010162221241.png)]

3 模板继承

根据官方文档的解释:block等价于define定义一个名为name的模板,并在”有需要”的地方执行这个模板,执行时将”.”设置为pipeline的值。 但应该注意,block的第一个动作是执行名为name的模板,如果不存在,则在此处自动定义这个模板,并执行这个临时定义的模板。换句话说,block可以认为是设置一个默认模板,即父类模板 例如:{{block “T1” .}} one {{end}}。它先找到T1模板,如果T1存在,则执行找到的T1,如果没找到T1,则临时定义一个模板{{define “T1”}} one {{end}},并执行它。 在很多网页中,大体上的布局都差不多,因此可以将布局封装为一个默认模板,以供其他模板调用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0LKMteX-1665390828625)(go web.assets/image-20221010162337728.png)]

package main

import (
	"fmt"
	"net/http"
	"text/template"
)

type PageInfo struct {
	Title   string
	Content string
}

func main() {
	http.HandleFunc("/index", index)
	http.HandleFunc("/product", product)
	err := http.ListenAndServe(":9000", nil)
	if err != nil {
		fmt.Printf("HTTP server start failed, err :  %v", err)
		return
	}
}

func product(w http.ResponseWriter, r *http.Request) {
	//定义模板,先模板
	t, _ := template.ParseFiles("./template/tmpl/base_tmpl.html", "./template/html/product.html")
	//渲染数据
	pageInfo := PageInfo{"product", "product content"}
	//渲染product
	_ = t.ExecuteTemplate(w, "product.html", map[string]interface{}{
		"pageInfo": pageInfo,
	})
}

func index(w http.ResponseWriter, r *http.Request) {
	//定义模板,先模板
	t, _ := template.ParseFiles("./template/tmpl/base_tmpl.html", "./template/html/index.html")
	//渲染数据
	pageInfo := PageInfo{"index", "index content"}
	//渲染index
	_ = t.ExecuteTemplate(w, "index.html", map[string]interface{}{
		"pageInfo": pageInfo,
	})
}

base_tmpl.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.pageInfo.Title}}</title>
</head>
<header style="height: 200px;width: 100%;background: lightgreen;font-size: 20px;">
    COMMON HEADER
</header>
<body>


<div>
    {{block "content" .}} {{end}}
</div>


</body>
<footer style="height: 200px;width: 100%;background: lightcoral;font-size: 20px;">
    COMMON FOOTER
</footer>
</html>

index.html:

{{/*继承模板*/}}
{{template "base_tmpl.html" .}}


{{/*重新定义模板*/}}
{{define "content"}}
    <h1>这是index页面</h1>

    <p> {{.pageInfo.Content}}</p>
{{end}}

product.html:

{{/*继承模板*/}}
{{template "base_tmpl.html" .}}


{{/*重新定义模板*/}}
{{define "content"}}
    <h1>这是product页面</h1>

    <p> {{.pageInfo.Content}}</p>
{{end}}

在这里插入图片描述
在这里插入图片描述

原文地址:https://blog.csdn.net/qq_34125999/article/details/127247394

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_51217.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注