Go --- html/template模板包的使用(一)

简介: Go --- html/template模板包的使用

简单使用

要使用模板需要分三个步骤,分别是定义、解析和渲染,下面咱一步一步来

  1. 定义
    创建一个.tmpl或是.tpl文件,在goland中第一次创建这种类型的文件他会让你选用什么文件的格式去提示这类文件,这时候选择 go template files。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>测试</title>
</head>
<body>
    {{ . }}<br>
    {{ .name}}<br>
    {{ .sex}}
</body>
</html>

其中{{ }} 是模板里的标识符,该标识符可能会与Vue中某些代码冲突,后面会提供修改默认标识符的方法,在表示符中的 . 代表着数据,这个数据是从后台传来的。

  1. 解析
t, err := template.ParseFiles("./test.tmpl")

将刚才定义的模板文件解析到程序中,上方调用的方法是解析多个文件

  1. 解析方法
// 解析多个文件
func ParseFiles(filenames ...string) (*Template, error) {
  return parseFiles(nil, readFileOS, filenames...)
}
// 通过正则表达式解析多个文件
func ParseGlob(pattern string) (*Template, error) {
  return parseGlob(nil, pattern)
}
// 类似于上面两种方法,但是是从文件系统fs读取,而不是主机操作系统的文件系统。
func ParseFS(fs fs.FS, patterns ...string) (*Template, error) {
  return parseFS(nil, fs, patterns)
}
  1. 渲染
mp := map[string]interface{}{
    "name": "张三",
    "sex": "男",
  }
  err = t.Execute(w, mp)

将数据渲染到刚解析的模板中

// 可以看出这个data是个空接口类型,也就意味着是什么值都可以传的
func (t *Template) Execute(wr io.Writer, data interface{}) error {
  if err := t.escape(); err != nil {
    return err
  }
  return t.text.Execute(wr, data)
}
  1. 另外一种渲染方法,指定模板文件进行渲染,适用于有好多解析文件在一起时使用
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
  tmpl, err := t.lookupAndEscapeTemplate(name)
  if err != nil {
    return err
  }
  return tmpl.text.Execute(wr, data)
}
package main
import (
  "fmt"
  "html/template"
  "net/http"
)
func sayHello(w http.ResponseWriter,r *http.Request)  {
  t, err := template.ParseFiles("./test.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)
  }
}
func main() {
  http.HandleFunc("/",sayHello)
  err := http.ListenAndServe(":9000", nil)
  if err != nil {
    fmt.Printf("listen address failed err = %v",err)
  }
}
  1. 注释
    注释使用的符号为{{/* */}},支持多行注释,如
{{/*
  注释内容
*/}}
  1. 变量的使用
    在模板中使用变量是利用 $ 符号
    赋值
{{ $obj := 数据 }}
  1. 声明变量之后就可以在模板文件中使用了。
    例子:
    test.tmpl
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>变量使用</title>
</head>
<body>
    MSG :{{ . }}<br>
    姓名 :{{ .Name }}<br>
    性别 : {{ .Sex }}<br>
{{/*    使用变量  */}}
    <div>
    {{ $num := "123" }}
    年岁 :{{ $num }}
    </div>
</body>
</html>
  1. main.go
package main
import (
  "fmt"
  "html/template"
  "net/http"
)
func sayHello(w http.ResponseWriter,r *http.Request)  {
  t, err := template.ParseFiles("./test.tmpl")
  if err != nil {
    fmt.Printf("parse file failed err := %v",err)
  }
  err = t.Execute(w, struct {
    Name string
    Sex  string
  }{
    Name: "张三",
    Sex: "女",
  })
  if err != nil {
    fmt.Printf("execute file failed err := %v",err)
  }
}
func main() {
  http.HandleFunc("/",sayHello)
  err := http.ListenAndServe(":9000", nil)
  if err != nil {
    fmt.Printf("listen address failed err = %v",err)
  }
}

这里要注意一点,就是当传给模板的数据为结构体时,根据go语言的特性,属性名小写的属性外界将获取不到值。

判断与清楚空白符操作

判断

在模板中的判断语句写法同go语言类似

{{ if [比较函数] 变量 [比较对象] }}
  如果为真要执行的语句
{{ end }}

如果是只有变量的话,就判断变量是否存在值,如果存在就执行。

也可以使用 if … else … 语句,或if … else if … 语句,如

{{ if [比较函数] 变量 [比较对象] }}
{{ else }}
{{ end }}
{{ if [比较函数] 变量 [比较对象] }}
{{ else if [比较函数] 变量 [比较对象]}}
{{ end }}

去空白字符

使用

清楚变量左右两侧的空白符号,当然也可以只清除一侧,只需要将不需要清除的一侧的 - 舍去
{{- -}}

例子:

test.tmpl

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>判断与清楚空白符操作</title>
</head>
<body>
    MSG :{{ . }}<br>
    姓名 :{{ .Name }}<br>
    性别 : {{ .Sex }}<br>
    {{ $num := .Age }}
    年龄 :{{ $num }}
{{/*    判断使用 注意,要先写条件之后跟上比较对象*/}}
{{/*   比较函数
eq   ==       eq可以进行多个值比较 如 eq n1 n2 n3 ,就会拿n1 分别跟n2,n3比较
ne   !=
lt   <
le   <=
gt   >
ge   >=
*/}}
    <div>
    {{ if lt $num 18 }}
        好好吃饭
    {{ else if ge $num 18 }}
        别在熬夜了
    {{end}}
    </div>
{{/* {{- -}} 取出空白符的符号使用*/}}
    {{ $num }} = {{ $num }}<br>
{{/*    取出空白符,让左侧或右侧能与其他的文本贴贴*/}}
    {{ $num -}} = {{- $num }}
</body>
</html>

main.go

package main
import (
  "fmt"
  "html/template"
  "net/http"
  "os"
  "path/filepath"
)
func sayHello(w http.ResponseWriter,r *http.Request)  {
  // ./ 代表项目路径
  t, err := template.ParseFiles("./test.tmpl")
  if err != nil {
    fmt.Printf("parse file failed err := %v",err)
  }
  err = t.Execute(w, struct {
    Name string
    Sex  string
    Age  int
  }{
    Name: "                 张三  ",
    Sex: "女",
    Age: 20,
  })
  if err != nil {
    fmt.Printf("execute file failed err := %v",err)
  }
}
func main() {
  http.HandleFunc("/",sayHello)
  root := filepath.Dir(os.Args[0])
  fmt.Println(root)
  err := http.ListenAndServe(":9000", nil)
  if err != nil {
    fmt.Printf("listen address failed err = %v",err)
  }
}

循环、with和与预定义函数的使用

循环

使用range关键字进行遍历

这个变量只能是数组、切片、map或者通道
{{ range 变量 }}
{{ end }}
{{ range $index,$valuse = 变量 }}
{{ end }}

range中也可以使用else语句,如果所遍历的这个变量长度为0,则执行else语句

{{ range 变量 }}
{{ else }}
{{ end }}

with

with的作用为重新定义 . 所代表的数据,这个重新定义有一个范围,只有在范围内 . 才代表with重新定义的那个数据

{{ with 变量 }}
在这中间 . 都将被替换为变量的数据
{{ end }}

当赋值的变量为空时,可以使用 else 语句来检测 .有没有被重新赋值

{{ with 变量 }}
{{ else }}
如果变量为空则执行这里的语句
{{ end }}

预定义函数

模板中的预定义函数有:

and
    函数返回它的第一个empty参数或者最后一个参数;
    就是说"and x y"等价于"if x then y else x";所有参数都会执行;
or
    返回第一个非empty参数或者最后一个参数;
    亦即"or x y"等价于"if x then x else y";所有参数都会执行;
not
    返回它的单个参数的布尔值的否定
len
    返回它的参数的整数类型长度
index
    执行结果为第一个参数以剩下的参数为索引/键指向的值;
    如"index x 1 2 3"返回x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。
print
    即fmt.Sprint
printf
    即fmt.Sprintf
println
    即fmt.Sprintln
html
    返回与其参数的文本表示形式等效的转义HTML。
    这个函数在html/template中不可用。
urlquery
    以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。
    这个函数在html/template中不可用。
js
    返回与其参数的文本表示形式等效的转义JavaScript。
call
    执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;
    如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2);
    其中Y是函数类型的字段或者字典的值,或者其他类似情况;
    call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同);
    该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
    如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;

例子:

test.tmpl

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title>循环,with和预定义函数的使用</title>
</head>
<body>
{{/* 循环 */}}
    {{ range $index,$v1 := . }}
    下标:{{ $index }}
    姓名:{{ $v1 }}
        <br>
    {{ end }}
<hr>
{{/* with 更改点的值*/}}
    开始时:{{ . }}<br>
    {{ with "斗地主研讨会"}}
        转换后:{{ . }}
    {{ end }}
<hr>
{{/* 预定义函数 */}}
{{/*
and
    函数返回它的第一个empty参数或者最后一个参数;
    就是说"and x y"等价于"if x then y else x";所有参数都会执行;
or
    返回第一个非empty参数或者最后一个参数;
    亦即"or x y"等价于"if x then x else y";所有参数都会执行;
not
    返回它的单个参数的布尔值的否定
len
    返回它的参数的整数类型长度
index
    执行结果为第一个参数以剩下的参数为索引/键指向的值;
    如"index x 1 2 3"返回x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。
print
    即fmt.Sprint
printf
    即fmt.Sprintf
println
    即fmt.Sprintln
html
    返回与其参数的文本表示形式等效的转义HTML。
    这个函数在html/template中不可用。
urlquery
    以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。
    这个函数在html/template中不可用。
js
    返回与其参数的文本表示形式等效的转义JavaScript。
call
    执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;
    如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2);
    其中Y是函数类型的字段或者字典的值,或者其他类似情况;
    call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同);
    该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
    如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;
*/}}
    研讨会人数:{{ len . }}
</body>
</html>

main.go

package main
import (
  "fmt"
  "html/template"
  "net/http"
  "os"
  "path/filepath"
)
func sayHello(w http.ResponseWriter,r *http.Request)  {
  // ./ 代表项目路径
  t, err := template.ParseFiles("./test.tmpl")
  if err != nil {
    fmt.Printf("parse file failed err := %v",err)
  }
  strings := []string{"张安","潘凤","李翔"}
  err = t.Execute(w,strings)
  if err != nil {
    fmt.Printf("execute file failed err := %v",err)
  }
}
func main() {
  http.HandleFunc("/",sayHello)
  root := filepath.Dir(os.Args[0])
  fmt.Println(root)
  err := http.ListenAndServe(":9000", nil)
  if err != nil {
    fmt.Printf("listen address failed err = %v",err)
  }
}


相关文章
|
5月前
|
Go 开发者
Go语言包的组织与导入 -《Go语言实战指南》
本章详细介绍了Go语言中的包(Package)概念及其使用方法。包是实现代码模块化、复用性和可维护性的核心单位,内容涵盖包的基本定义、命名规则、组织结构以及导入方式。通过示例说明了如何创建和调用包,并深入讲解了`go.mod`文件对包路径的管理。此外,还提供了多种导入技巧,如别名导入、匿名导入等,帮助开发者优化代码结构与可读性。最后以表格形式总结了关键点,便于快速回顾和应用。
263 61
|
1月前
|
Java 编译器 Go
【Golang】(1)Go的运行流程步骤与包的概念
初次上手Go语言!先来了解它的运行流程吧! 在Go中对包的概念又有怎样不同的见解呢?
129 4
|
4月前
|
JSON 中间件 Go
Go语言实战指南 —— Go中的反射机制:reflect 包使用
Go语言中的反射机制通过`reflect`包实现,允许程序在运行时动态检查变量类型、获取或设置值、调用方法等。它适用于初中级开发者深入理解Go的动态能力,帮助构建通用工具、中间件和ORM系统等。
300 63
|
3月前
|
缓存 监控 安全
告别缓存击穿!Go 语言中的防并发神器:singleflight 包深度解析
在高并发场景中,多个请求同时访问同一资源易导致缓存击穿、数据库压力过大。Go 语言提供的 `singleflight` 包可将相同 key 的请求合并,仅执行一次实际操作,其余请求共享结果,有效降低系统负载。本文详解其原理、实现及典型应用场景,并附示例代码,助你掌握高并发优化技巧。
294 0
|
6月前
|
Go 持续交付 开发者
Go语言包与模块(module)的基本使用-《Go语言实战指南》
本章深入讲解Go语言中的包(Package)和模块(Module)概念。包是代码组织的最小单位,每个`.go`文件属于一个包,通过`import`实现复用;主程序包需命名为`main`。模块是Go 1.11引入的依赖管理机制,支持自动版本管理和私有/远程仓库,无需依赖GOPATH。通过实际示例,如自定义包`mathutil`和第三方模块`gin`的引入,展示其使用方法。常用命令包括`go mod init`、`go mod tidy`等,帮助开发者高效管理项目依赖。最后总结,包负责功能划分,模块实现现代化依赖管理,提升团队协作效率。
278 15
|
5月前
|
前端开发
个人征信PDF无痕修改软件,个人征信模板可编辑,个人征信报告p图神器【js+html+css仅供学习用途】
这是一款信用知识学习系统,旨在帮助用户了解征信基本概念、信用评分计算原理及信用行为影响。系统通过模拟数据生成信用报告,涵盖还款记录
|
10月前
html5+svg太空人404动画模板源码
html5+svg太空人404动画模板源码
142 17
|
11月前
|
Linux Go iOS开发
怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev
本文介绍了如何在 VSCode 中禁用点击 Go 包名时自动打开浏览器跳转到 pkg.go.dev 的功能。通过将 gopls 的 `ui.navigation.importShortcut` 设置为 &quot;Definition&quot;,可以实现仅跳转到定义处而不打开链接。具体操作步骤包括:打开设置、搜索 gopls、编辑 settings.json 文件并保存更改,最后重启 VSCode 使设置生效。
443 8
怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev
|
10月前
|
Go 数据库
Go语言中的包(package)是如何组织的?
在Go语言中,包是代码组织和管理的基本单元,用于集合相关函数、类型和变量,便于复用和维护。包通过目录结构、文件命名、初始化函数(`init`)及导出规则来管理命名空间和依赖关系。合理的包组织能提高代码的可读性、可维护性和可复用性,减少耦合度。例如,`stringutils`包提供字符串处理函数,主程序导入使用这些函数,使代码结构清晰易懂。
370 11

热门文章

最新文章

下一篇
oss云网关配置