【JSON2WEB】03 go的模板包html/template的使用

Go text/template 是 Go 语言标准库中的一个模板引擎,用于生成文本输出。它使用类似于 HTML 的模板语言,可以将数据和模板结合起来,生成最终的文本输出。

Go html/template包实现了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容。
它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用html/template这个包。

1 使用方法

html/template 为go的内置包直接 import “html/template” 即可,模板引擎的使用一般三个步骤,定义,解析,渲染。
模板语法都包含在 {{和}} 中间,其中 {{.}} 中的点表示当前对象。对象可以是变量、内置变量、控制结构、内部函数、自定义函数,注释等等。

2 从Hello World开始

2.1 创建一个html模板文件

模板文件名为 hello,html,内容如下:

{{.}}

在这里插入图片描述

2.2 解析模板并输出到浏览器

// test3 project main.go
package mainimport ("net/http""html/template"
)func main() {http.HandleFunc("/", hello)println("打开浏览器试试 http://localhost:5217")err := http.ListenAndServe(":5217", nil)if err != nil {println("HTTP server start failed! err : ", err)return}
}// hello 函数把解析后的文件输出到html
func hello(w http.ResponseWriter, r *http.Request) {s := "Hello World!"t, _ := template.ParseFiles("hello.html")t.Execute(w, s)
}

运行一下:
在这里插入图片描述

浏览器查看:
在这里插入图片描述
是不是很简单啊。

3 一个综合使用的例子

这个例子包括解析结构体,map,内置变量,注释,内置函数,自定义函数等。

3.1 创建一个html模板

其实文件名叫啥都是,比如html.tmpl

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>golang html demo</title>
</head>
<body><div><p>王子:</p><p>Hello {{.m1.name}}</p><p>年龄: {{.m1.age}}</p><p>性别: {{.m1.gender}}</p><p>公主:</p>{{/* with 省略写法 */}}{{with .u1}}<p>Hello {{ .Name}}</p><p>年龄: {{ .Age}}</p><p>性别: {{ .Gender}}</p>{{end}}</div><div><p>内置变量:</p>{{/* 定义内置变量*/}}{{$i := 100}}{{$x := .u1.Age}}{{/* 在页面显示内置变量*/}}{{$i}}{{$x}}</div><div><p>内置函数:</p>{{/*内置函数*/}}{{$a := 0}}{{$b := 1}}{{or $a $b}}{{and $a $b}}{{len .m1}}<p>比较运算:</p>{{eq $a $b}}</div></body>
</html>

3.2 Go代码

// 模板只能传入一个变量,多个变量需要组合到 map里package mainimport ("fmt""html/template""net/http"
)type User struct {Name   stringGender stringAge    int
}func index(w http.ResponseWriter, r *http.Request) {// 解析模板t, err := template.ParseFiles("html.tmpl")if err != nil {fmt.Println("Parse template failed! err:", err)return}// 渲染模板u1 := User{Name:   "小公主",Gender: "女",Age:    16,}m1 := map[string]interface{}{"name":   "小皇子","gender": "男","age":    18,}err = t.Execute(w, map[string]interface{}{"u1": u1,"m1": m1,})if err != nil {fmt.Println("render template failed,err : ", err)return}}func diyifun(w http.ResponseWriter, r *http.Request) {// 自定义函数// 1 自定义函数变量wenfun := func(name string) (string, error) {return name + " 您今儿吃了吗?", nil}// 2 创建一个名称为diyfun的模板对象,要求名称跟文件名一样,扩展名也是t := template.New("diyfun.tmpl")// 3 在解析模板之前注册函数t.Funcs(template.FuncMap{"wen": wenfun,})// 4 解析模板_, err := t.ParseFiles("diyfun.tmpl")if err != nil {fmt.Println("Parsetemplate failed! err:", err)return}// 渲染模板t.Execute(w, "白龙马")
}func main() {http.HandleFunc("/index", index)http.HandleFunc("/diyifun", diyifun)println("打开浏览器试试 http://localhost:5217/index")err := http.ListenAndServe(":5217", nil)if err != nil {fmt.Println("HTTP server start failed! err : ", err)return}
}

3.3 打开浏览器看渲染效果

  • index 综合
    在这里插入图片描述

  • diyifun 自定义函数
    在这里插入图片描述

4 更复杂的嵌套模板

就是在一个模板中嵌套另外的一个模板。
在需要嵌套的地方
{{ template 模板名 . }}
其中,这个 . 是在模板中传递数据用的

4.1 先看看模板

  • Home.tmpl
<!DOCTYPE html>
<html lang="zh-CN">
<head><title>嵌套2个子模板</title>
</head>
<body><p>这是子模板1:</p>ul :<br>{{ template "tmp1.tmpl" . }}<hr><p>这是子模板1:</p>ol :<br>{{ template "tmp2.tmpl" . }}
</body>
</html>
  • tmp1.tmpl
<ul><li>{{ .name }}</li><li>{{ .sex }}</li>
</ul>
  • tmp2.tmpl
<ol><li>{{ .name }}</li><li>{{ .sex }}</li>
</ol>

4.2 主控程序

// test3 project main.go
package mainimport ("fmt""html/template""net/http"
)func main() {http.HandleFunc("/home", home)println("打开浏览器试试 http://localhost:5217/home")err := http.ListenAndServe(":5217", nil)if err != nil {println("HTTP server start failed! err : ", err)return}
}// hello 函数把解析后的文件输出到html
func home(w http.ResponseWriter, r *http.Request) {//	s := "Hello World!"t, err := template.ParseFiles("home.tmpl", "tmp1.tmpl", "tmp2.tmpl")if err != nil {fmt.Printf("parse file failed err := %v", err)}mp := map[string]interface{}{"name": "白龙马","sex":  "男",}err = t.Execute(w, mp)if err != nil {fmt.Printf("execute file failed err := %v", err)}
}

4.3 运行效果

在这里插入图片描述

5 block定义一个默认模板

Home.tmpl 修改一下,嵌入一个不存在的模板tmp3.tmpl,如果直接 {{ template “tmp3.tmpl” . }}嵌入编译时就会报错,用block定义一个默认模板就OK:

<!DOCTYPE html>
<html lang="zh-CN">
<head><title>嵌套2个子模板</title>
</head>
<body><p>这是子模板1:</p>ul :<br>{{ template "tmp1.tmpl" . }}<hr><p>这是子模板2:</p>ol :<br>{{ template "tmp2.tmpl" . }}<hr><p>这是子模板3:</p>default :<br>{{ block "tmp3.tmpl" . }}tmp3.tmpl 没找到,这是默认模板的内容{{end}}</body>
</html>

运行效果如下:
在这里插入图片描述
现在新建一个tmp3.tmpl的模板:

别搞错了,我才是Tmp3.tmpl
<br>
{{ .name}}
{{ .sex}}

模板解析采用统配符解析函数:
t, err := template.ParseGlob(“nest/*.tmpl”)

解析 nest目录下所有的*.tmpl文件
刷新一下浏览器,默认模板替换为了tml3.tmpl

在这里插入图片描述

6 还尝试了其它方法

比如条件渲染,循环结构等。

package mainimport ("fmt""html/template""net/http"
)type Book struct {Title     stringPublisher stringYear      int
}func main() {http.HandleFunc("/index2", index2)err := http.ListenAndServe(":5217", nil)if err != nil {fmt.Println("HTTP server start failed! err : ", err)return}}func index2(w http.ResponseWriter, r *http.Request) {// // 解析模板// t, err := template.ParseFiles("index.html")// if err != nil {// 	fmt.Println("Parse template failed! err:", err)// 	return// }// 字符串t1 := template.New("Template")t1, _ = t1.Parse("External variable has the value [{{.}}]\n")t1.Execute(w, "Amazing")// 结构体b := Book{"The CSound Book", "MIT Press", 2002}t1.Execute(w, b)// 结构体字段t2 := template.New("Template")t2, _ = t2.Parse("External variable Book has the values [Title: {{.Title}}, Publisher: {{.Publisher}}, Year: {{.Year}}]\n")t2.Execute(w, b)// 内部变量 $前缀t, _ := template.New("Template").Parse("{{$var:=2150}}Internal variable has the value [{{$var}}]\n")t.Execute(w, nil)// 条件渲染/*等于 eq(对应 ==):非等于 ne(对应 !=)小于 lt(对应 <)小于等于 le(对应 <=)大于 gt(对应 >)大于等于 ge(对应 >=)*/t, err := template.New("Template").Parse("{{if eq . `filler`}}This is filler...{{else}}It's something else...{{end}}\n")if err != nil {panic(err)}t.Execute(w, "filler")// 直接写入布尔变量,而不是比较语句。t, _ = template.New("Template").Parse("{{if .}}This is true.{{else}}This is false.{{end}}\n")t.Execute(w, false)// 循环遍历computerList := []string{"Arduino", "Raspberri Pi", "NVidia Jetson Nano"}t, err = template.New("Template").Parse("My favorite computers are:\n{{range .}}{{.}}\n{{end}}\n")if err != nil {panic(err)}t.Execute(w, computerList)// 有序列表dishesList := []string{"Enciladas con Pollo", "Hot&Spicy Pizza", "Spaghetti Bolognese"}t, err = template.New("Template").Parse("My favorite dishes are:\n{{range $index, $item:=.}}{{$index}}) {{$item}}\n{{end}}\n")if err != nil {panic(err)}t.Execute(w, dishesList)// 模板中使用函数//dishesList := []string{"Enciladas con Pollo", "Hot&Spicy Pizza", "Spaghetti Bolognese"}t, err = template.New("Template").Funcs(template.FuncMap{"add": add}).Parse("My favorite dishes are:\n{{range $index, $item:=.}}{{add $index 1}}) {{$item}}\n{{end}}\n")if err != nil {panic(err)}t.Execute(w, dishesList)//dishesList := []string{"Enciladas con Pollo", "Hot&Spicy Pizza", "Spaghetti Bolognese"}tmpl := "Index{{dl}}Dish\n{{range $index, $item:=.}}{{add $index 1}}{{dl}}{{$item}}\n{{end}}\n"funcMap := template.FuncMap{"add": add, "dl": delimiter(",")}t, _ = template.New("Template").Funcs(funcMap).Parse(tmpl)t.Execute(w, dishesList)
}// 模板中使用函数add
func add(a, b int) int {return a + b
}// 这只分割符
func delimiter(s string) func() string {return func() string {return s}
}

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/247719.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络·网络层

网络层 网络层提供的两种服务 争论&#xff1a; 网络层应该向运输层提供怎样的服务&#xff1f;面向连接还是无连接&#xff1f; 在计算机通信中&#xff0c;可靠交付应当由谁来负责&#xff1f;是网络还是端系统&#xff1f; 2 种观点&#xff1a; 面向连接的可靠交付。 无连…

macOS与Linux相互投屏的方法

很多人面对跨系统投屏都望而却步。其实只要找对方法&#xff0c;两台不同系统的电脑也可以相互投屏。 今天就来看看Linux系统和macOS系统如何相互投屏&#xff01; 第一步&#xff0c;将Linux系统电脑和macOS系统电脑连接同一网络。假设是macOS系统投屏到Linux系统&#xff0c;…

【数据分享】1929-2023年全球站点的逐年平均气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01;本次我们为大家带来的就是具体到气象监…

二手交易|校园二手交易小程序|基于微信小程序的闲置物品交易平台设计与实现(源码+数据库+文档)

校园二手交易小程序目录 目录 基于微信小程序的闲置物品交易平台设计与实现 一、前言 二、系统功能设计 三、系统实现 1、用户信息管理 2、商品信息管理 3、公告信息管理 4、论坛信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕…

C++类和对象引入以及类的介绍使用

文章目录 一、面向过程和面向对象的初步认识二、类的引入2.2 类的引入 三、类的访问限定符及封装3.3 访问限定符3.4 【面试题】C中struct和class的区别3.5 类的两种定义方式 四、封装【面试题】面向对象的三大特性 五、类的作用域六、类的实例化七、类对象模型7.1 类对象的存储…

《动手学深度学习(PyTorch版)》笔记4.1

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过。…

Python列表中的append功能及用法举例

Python列表中的append功能及用法举例 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;append()&#x1f333;&#x1f340;功能介绍&#x1f340;&#x1f340;语法&#x1f340;&#x1f340;示例&#x1f340;&#x1f340;注意事项&#x…

如何使用宝塔面板搭建MySQL 5.5数据库并实现公网远程连接

文章目录 前言1.Mysql服务安装2.创建数据库3.安装cpolar3.2 创建HTTP隧道 4.远程连接5.固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 宝塔面板的简易操作性,使得运维难度降低,简化了Linux命令行进行繁琐的配置,下面简单几步,通过宝塔面板cp…

SpringCloud-高级篇(十八)

前面我们已经实现了多级缓存架构&#xff0c;大大提高了查询商品的性能&#xff0c;缓存在提高性能的同时&#xff0c;也带来了一致性的问题&#xff0c;比如说数据库发生了修改&#xff0c;这个时候&#xff0c;如果缓存依然是旧的数据&#xff0c;两者就产生了不一致&#xf…

Cesium介绍及3DTiles数据加载时添加光照效果对比

一、Cesium简介 Cesium原意是化学元素铯&#xff0c;铯是制造原子钟的关键元素&#xff0c;通过命名强调了Cesium产品专注于基于时空数据的实时可视化应用。熟悉GIS开发领域的读者都知道&#xff0c;Cesium是一个用于创建3D地理空间应用程序的开源JavaScript库&#xff0c;它允…

RSTP的P/A机制

如图所示根桥S1和S2之间新添加了一条链路,在当前状态下S2的另外几个端口p2是Alternate端口,p3是指定端口且处于Forwarding状态,p4是边缘端口。新链路连接成功后,P/A机制协商过程如下。 1.P0和P1两个端口马上都先成为指定端口发送RS TBPDU。 2.S2的P1口收到更优的RST BPD…

C#颜色拾取器

1&#xff0c;目的&#xff1a; 获取屏幕上任意位置像素的色值。 2&#xff0c;知识点: 热键的注册与注销。 /// <summary>/// 热键注册/// </summary>/// <param name"hWnd">要定义热键的窗口的句柄 </param>/// <param name"id…

pygame学习(一)——pygame库的导包、初始化、窗口的设置、打印文字

导语 pygame是一个跨平台Python库(pygame news)&#xff0c;专门用来开发游戏。pygame主要为开发、设计2D电子游戏而生&#xff0c;提供图像模块&#xff08;image&#xff09;、声音模块&#xff08;mixer&#xff09;、输入/输出&#xff08;鼠标、键盘、显示屏&#xff09;…

05.领域驱动设计:认识领域事件,解耦微服务的关键

目录 1、概述 2、领域事件 2.1 如何识别领域事件 1.微服务内的领域事件 2.微服务之间的领域事件 3、领域事件总体架构 3.1 事件构建和发布 3.2 事件数据持久化 3.3 事件总线 (EventBus) 3.4 消息中间件 3.5 事件接收和处理 4、案例 5、总结 1、概述 在事件风暴&a…

容器和虚拟机的对比

容器和虚拟机的对比 容器和虚拟机在与硬件和底层操作系统交互的方式上有所不同 虚拟化 使多个操作系统能够同时在一个硬件平台上运行。 使用虚拟机监控程序将硬件分为多个虚拟硬件系统&#xff0c;从而允许多个操作系统并行运行。 需要一个完整的操作系统环境来支持该应用。…

Go语言grpc服务开发——Protocol Buffer

文章目录 一、Protocol Buffer简介二、Protocol Buffer编译器安装三、proto3语言指南四、序列化与反序列化五、引入grpc-gateway1、插件安装2、定义proto文件3、生成go文件4、实现Service服务5、gRPC服务启动方法6、gateway服务启动方法7、main函数启动8、验证 相关参考链接&am…

图片的安全防护方法

目录 一&#xff1a;图片加水印 二&#xff1a;访问地址权限控制 三&#xff1a;限制下载 四&#xff1a;CDN加速 一&#xff1a;图片加水印 1&#xff1a;在添加水印之前&#xff0c;要对图片进行必要的处理。例如调整亮度、对比度和锐度等&#xff0c;以提高水印的清晰度…

搜维尔科技:【简报】元宇宙数字人赛道,优秀作品《星云时报》赏析

AI 对人们来说是一种新产业&#xff0c;而人们对于它未来会面临的议题仍有许多疑虑&#xff0c;因此我们用新闻报导的方式列举一些有趣且具有可能性的标题&#xff0c;希望能让 大家了解 AI 在未来可能会带来什么问题&#xff0c;以及我们应该采取的态度。 学校&#xff1a; 新…

web前端之不一样的居中方式、解决tabBar选项卡居中问题、css支持嵌套、auto

MENU 前言htmlstyle效果 前言 这里不能使用justify-content: center;&#xff0c;因为在小屏幕上&#xff0c;这种方式无法显示最前面的两个tabBar。 html <div id"box" class"d_f o_a mt_50 mb_50 ml_20 mr_20"><div class"ws_n">…

SQL注入-sqli-labs-master第一关

实验环境&#xff1a; Nginx.1.15.11 MySQL&#xff1a;5.7.26 实验步骤&#xff1a; 1.第一步&#xff1a; 在id1后加入一个闭合符号&#xff0c;如果报错&#xff0c;再在后面加上 -- 将后面注释掉&#xff0c;如果不报错&#xff0c;则证明为字符型。 http://127.0.0.1/…