【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}
}
运行结果:
相关文章:

【JSON2WEB】03 go的模板包html/template的使用
Go text/template 是 Go 语言标准库中的一个模板引擎,用于生成文本输出。它使用类似于 HTML 的模板语言,可以将数据和模板结合起来,生成最终的文本输出。 Go html/template包实现了数据驱动的模板,用于生成可防止代码注入的安全的…...

3 JS类型 值和变量
计算机对value进行操作。 value有不同的类型。每种语言都有其自身的类型集合。编程语言的类型集是该编程语言的基本特性。 value需要保存一个变量中。 变量的工作机制是变成语言的另一个基本特性。 3.1概述和定义 JS类型分为: 原始类型和对象类型。 原始类型&am…...

【Android】实现简易购物车功能(附源码)
先上结果: 代码: 首先引入图片加载: implementation com.github.bumptech.glide:glide:4.15.1配置权限清单: <!-- 网络权限 --><uses-permission android:name"android.permission.INTERNET"/><uses…...

使用Excel计算--任务完成总工作日时间段
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 引言 计算任务完成时间周期,和计算金钱一样,是一个比较细致严谨的工作。 通常,我们可能以为,完成周期形如: 任务完成周期 任务结束时间 - 任务开始时间 但是…...

.NET高级面试指南专题一【委托和事件】
在C#中,委托(Delegate)和事件(Event)是两个重要的概念,它们通常用于实现事件驱动编程和回调机制。 委托定义: 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个…...

基于springboot+vue的在线教育系统(前后端分离)
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…...

54-函数的3种定义,函数的4种调用:函数模式调用,方法模式调用,构造函数模式调用,apply call bind调用
一.函数的3种定义 1.函数的声明定义:具有声明提升 <script>//函数声明定义function fn(){}</script> 2.函数的表达式定义 <script>//匿名式表达式var fn = function(){}//命名式表达式var fn1 = function a(){}</script> 3.构造函数定义 var 变量…...

[C#]winform部署yolov5实例分割模型onnx
【官方框架地址】 https://github.com/ultralytics/yolov5 【算法介绍】 YOLOv5实例分割是目标检测算法的一个变种,主要用于识别和分割图像中的多个物体。它是在YOLOv5的基础上,通过添加一个实例分割模块来实现的。 在实例分割中,算法不仅…...

C++核心编程:类和对象 笔记
4.类和对象 C面向对象的三大特性为:封装,继承,多态C认为万事万物都皆为对象,对象上有其属性和行为 例如: 人可以作为对象,属性有姓名、年龄、身高、体重...,行为有走、跑、跳、说话...车可以作为对象,属性有轮胎、方向盘、车灯…...

机器学习实验3——支持向量机分类鸢尾花
文章目录 🧡🧡实验内容🧡🧡🧡🧡数据预处理🧡🧡代码认识数据相关性分析径向可视化各个特征之间的关系图 🧡🧡支持向量机SVM求解🧡🧡直觉…...

R语言【taxlist】——clean():移除孤立的记录
Package taxlist version 0.2.4 Description 对于 taxlist 类对象的操作可能会产生独立的条目。clean() 方法就是用来删除这样的条目,并恢复 taxlist 对象的一致性。 Usage clean(object, ...)## S4 method for signature taxlist clean(object, times 2, ...) A…...

CentOS 7.9 OS Kernel Update 3.10 to 4.19
date: 2024-01-18, 2024-01-26 原 OS Kernel 3.10 升级至 4.19 1.检查默认内核 检查 vmlinuz 版本 [rootlocalhost ~]# grubby --default-kernel /boot/vmlinuz-3.10.0-1160.105.1.el7.x86_64 [rootlocalhost ~]#检查 Linux 内核版本 [rootlocalhost ~]# uname -a Linux loc…...

k8s---安全机制
k8s的安全机制,分布式集群管理工具,就是容器编排。安全机制的核心:APIserver。为整个集群内部通信的中介,也是外控控制的入口。所有的机制都是围绕apiserver来进行设计: 请求api资源: 1、认证 2、鉴权 …...

GitHub 一周热点汇总第7期(2024/01/21-01/27)
GitHub一周热点汇总第7期 (2024/01/21-01/27) ,梳理每周热门的GitHub项目,离春节越来越近了,不知道大家都买好回家的票没有,希望大家都能顺利买到票,一起来看看这周的项目吧。 #1 rustdesk 项目名称:rust…...

kotlin data clas 数据类
data class 介绍 kotlin 中 data class 是一种持有数据的特殊类 编译器自动从主构造函数中声明的所有属性导出以下成员: .equals()/.hashCode() 对 .toString() 格式是 "User(nameJohn, age42)" .componentN() 函数 按声明顺序对应于所有属性。…...

Java基础知识-异常
资料来自黑马程序员 异常 异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是: 异常 :指的是程序在执行过程中,出现的非正常的情况,…...

跟着cherno手搓游戏引擎【12】渲染context和首个三角形
渲染上下文: 目的:修改WindowsWindow的结构,把glad抽离出来 WindowsWindow.h:新建m_Context #pragma once #include "YOTO/Window.h" #include <YOTO/Renderer/GraphicsContext.h> #include<GLFW/glfw3.h> #include…...

MybatisPlus二级映射和关联对象ResultMap
文章目录 一、业务背景1. 数据库表结构2. 需求 二、使用映射直接得到指定结构三、其他文件1. Mapper2. Service3. Controller 四、概念理解一级映射二级映射聚合 五、标签使用1. \<collection\> 标签2. \<association\> 标签 在我们的教程中,我们设计了…...

低代码开发业务在AIGC时代的应用
随着人工智能和图形计算能力的快速发展,低代码开发平台在AIGC(人工智能,物联网,大数据和云计算)时代中扮演着至关重要的角色。本文将介绍低代码开发业务的概念和优势,探讨其在AIGC时代的应用及其对传统软件…...

惠普1536dnf MFP报52扫描仪错误维修
如果您使用的惠普HP LaserJet 1536dnf MFP打印机可能会遇到“52扫描仪错误”的提示。这个错误可能会阻止你使用打印机的扫描功能。在这里,我将提供一些有用的解决方法来帮助大家去解决这个问题。-----吴中函 故障描述: 一台某单位正在使用的惠普HP LaserJet 1536dnf MFP黑白…...

【MIdjourney】五个特殊物体关键词
1.碳酸(Carbonate) 这一词语的本意是指包含碳(C)、氧(O)和氢(H)元素的化合物。而在MIdjourney中添加该词汇会使得生成的图片具有水滴效果且富有动态感。 2.灯丝(Filament) Filament效果可能包括更逼真的…...

2024/1/27 备战蓝桥杯 1
目录 求和 0求和 - 蓝桥云课 (lanqiao.cn) 成绩分析 0成绩分析 - 蓝桥云课 (lanqiao.cn) 合法日期 0合法日期 - 蓝桥云课 (lanqiao.cn) 时间加法 0时间加法 - 蓝桥云课 (lanqiao.cn) 扫雷 0扫雷 - 蓝桥云课 (lanqiao.cn) 大写 0大写 - 蓝桥云课 (lanqiao.cn) 标题…...

初学数据结构:Java对象的比较
目录 1. PriorityQueue中插入对象2. 元素的比较2.1 基本类型的比较2.2 对象比较的问题 3. 对象的比较3.1 基于Comparable接口类的比较3.2 基于比较器比较3.3 三种方式对比 4. 集合框架中PriorityQueue的比较方式5. 使用PriorityQueue创建大小堆,解决TOPK问题 【本节…...

mac 10.15.7 Unity 2021.3.14 XCode 12.4 -> Unity IOS 自动安装 Cocoapods 失败解决方法
自己这两天在用Unity开发IOS时,遇到了安装Cocoapods失败的问题,记录一下问题及解决方法,便于自己后续查看,以及有相同遭遇的人查看 发生场景:打开 unity,触发自动安装 Cocoapods -> 安装失败(…...

Elasticsearch 中使用MustNot等同于不登录遇到的坑
1、在写关键词推荐时,需要把当前文章过滤掉,不能再推荐自己的文章,所以再es中需要用到 MustNot属性查询 /// <summary> /// 服务中心es检索 /// </summary> /// <param name="input"></param> /// <returns></…...

java抽象工厂实战与总结
文章目录 一、工厂模式(三种)1.简单工厂模式1.1 概念:1.2 使用场景:1.3 模型图解:1.4 伪代码: 2.工厂方法模式2.1 概念:2.2 使用场景:2.3 模型图解:2.4 伪代码 3.抽象工厂…...

Compose | UI组件(六) | 选择框
文章目录 前言Checkbox 复选框的含义Checkbox 复选框的使用Switch 单选框的含义Switch 单选框的使用Slider 滑竿组件的含义Slider 滑竿组件的使用 总结 前言 随着移动端的技术不断更新迭代,Compose也运用的越来越广泛,很多人都开始学习Compose 本文主要…...

C++拷贝构造函数、赋值学习整理:
拷贝构造函数: 概念: 构造函数的第一个参数,是类本身的const引用(一般情况下没有其他参数,少数情况:其他参数必须有默认值!)称此类构造函数为拷贝构造函数 特征: 1&am…...

[亲测源码]ps软件网页版在线使用 PS网站程序源码 photoshop网页版源码 网页版的ps软件源码
在线PS作图修图网页版PHP网站源码,PHP在线照片图片处理PS网站程序源码photoshop网页版。 有很多朋友们都是在用PS作图的,众所周知在使用和学习PS时是需要下载软件的,Photoshop软件对电脑配置也是有一定要求的,今天就为大家带来一…...

前端大厂面试题探索编辑部——第二期
目录 题目 单选题1 题解 关于TCP 关于UDP 单选题2 题解 A选项的HTTP是否是无状态协议 B选项的HTTP支持的方法 C选项的关于HTTP的状态码 D选项HTTP协议的传输格式 题目 单选题1 1.以下哪个描述是关于 TCP 和 UDP 的区别() A. TCP 是无连接的…...