golang template 库使用教程
By Hubert Chen at
Updated on
这个文章目前是用来查看各种关键字和函数如何使用的,需要的话可以看看 golang template 库入门教程 文章
文章里的描述可能与实际有出入,请参考官方文档 text/template - Go Packages
在我写 tplate 时,我发现网上能找到的 golang template 教程都很分散,不是很方便,于是打算写一篇文章留给自己用
运算符
逻辑运算符
| 关键字 | 使用方法 | 等价 go 语句 |
|---|---|---|
| and | and C1 C2 |
C1 && C2 |
| or | or C1 C2 |
C1 || C2 |
| not | not C1 |
!C1 |
比较运算符
| 关键字 | 使用方法 | 等价 go 语句 | 备注 |
|---|---|---|---|
| eq | eq C1 C2 |
C1 == C2 |
EQual |
| ne | ne C1 C2 |
C1 != C2 |
Not Equal |
| lt | lt C1 C2 |
C1 < C2 |
Less Than |
| le | le C1 C2 |
C1 <= C2 |
Less than or Equal |
| gt | gt C1 C2 |
C1 > C2 |
Greater Than |
| ge | ge C1 C2 |
C1 >= C2 |
Greater than or Equal |
eq 关键字可以接受多个参数,例如 eq C1 C2 C3,但等价的 go 语句其实是 C1 == C2 || C1 == C3
复杂条件式
如果要创建复杂的条件式,有时需要使用括号 () 将子条件包裹起来
| 条件式 | 等价 go 语句 |
|---|---|
and C1 (not C2) |
C1 && !C2 |
and (and (gt C1 1) (gt C2 1)) (ne C1 C2) |
(C1 > 1 && C2 > 1) && C1 != C2 |
eq C1 C2 C3 C4 |
C1 == C2 || C1 == C3 || C1 == C4 |
关键字
if else 条件判断
可以在模板中判断一些条件,来控制要执行的数据
{{ if .A }}
{{/* 符合 .A 条件时的内容 */}}
{{ else if .B }}
{{/* 不符合 .A 但符合 .B 条件时的内容 */}}
{{ else }}
{{/* 不符合以上全部条件时的内容 */}}
{{ end }}
range 遍历
使用 range 方法即可遍历数组、切片或 map 键值对,也可以在要遍历的对象为空时进行其他操作
{{ range .Slice }}
{{/* 此时 . 会指向循环中的数据 */}}
当前遍历的值: {{ . }}
{{ else }}
这个切片是空的
{{ end }}
在遍历中使用外部值
在 range 方法的作用域中,. 符号会指向当前遍历的数据,若要在循环中使用外部的值,需要添加 $ 前缀
{{/* 假设传入的数据中有 Slice 和 Value 这两个变量 */}}
这是 Value 的值: {{ .Value }}
{{ range .Slice }}
当前遍历的值: {{ . }}
循环外部的值: {{ $.Value }}
{{ end }}
获取索引或键名
在使用 range 方法时可以通过创建变量来获取数组、切片或 map 键值对的索引或键
{{ range $index, $data := .Slice }}
index 变量: {{ $index }}
data 变量: {{ $data }}
当前遍历的值: {{ . }}
{{ end }}
创建了变量后依然可以通过 . 来直接调用当前遍历的数据
index 获取单个元素
可以使用 index 方法来获取数组、切片或 map 键值对中的单个元素
{{ $item_0_in_slice := index .Slice 0 }}
切片中的第 0 个元素为 {{ $item_0_in_slice }}
{{ $item_abc_in_map := index .Map "abc" }}
map 键对值中的 abc 元素为 {{ $item_abc_in_map }}
break continue 控制循环
在使用 range 方法遍历内容时,可以像 go 代码的 for 循环一样使用 break 和 continue 控制接下来的操作
{{/* 假设 .Numbers 中的数据是 1,2,3,4,5,6,7,8,9,10 */}}
{{ range .Numbers }}
{{ if lt . 5 }}
数字小于 5: {{ . }}
{{ continue }}
{{ end }}
{{ if gt . 2 }}
正在退出循环
{{ break }}
{{ end }}
{{ end }}
现在在循环外
with 暂时修改 . 指向的数据
有时候只需要使用数据中的某个字段,可以用 with 命令来暂时修改 . 指向的数据
{{/* 假设传入的数据结构为 .Post.Date */}}
现在是 {{ .Post.Date.Year }} 年 {{ .Post.Date.Month }} 月 {{ .Post.Date.Day }} 日
{{ with .Post.Date }}
{{/* 此时 . 已经指向 .Post.Date,调用 .Year 同等于 .Post.Date.Year */}}
现在是 {{ .Year }} 年 {{ .Month }} 月 {{ .Day }} 日
{{ end }}
若要在 with 作用域中使用其他外部值,参考 在遍历中使用外部值
with 命令还可以像 if else 那样选择要使用的数据
{{ with .Update.Date }}
{{/* 此时 . 指向 .Update.Date */}}
更新时间 {{ .Year }} 年 {{ .Month }} 月 {{ .Day }} 日
{{ else with .Create.Date }}
{{/* 此时 . 指向 .Create.Date */}}
创建时间 {{ .Year }} 年 {{ .Month }} 月 {{ .Day }} 日
{{ else }}
{{/* 因为没有匹配上面的条件,此时 . 没有发生变化 */}}
未知时间
{{ end }}
define template 定义和调用模板
可以使用 define 命令来预先定义一个模板,再通过 template 命令来调用之前定义的模板
{{ define "A" }}
{{/* 模板 A 中的 . 为调用时传入的数据 */}}
在模板 A 中的数据是 {{ . }}
{{ end }}
正在调用模板 A 并传入 "text"
{{ template "A" "text" }}
block 重新定义模板并立即调用
block 命令其实是一个语法糖,它会定义一个模板并立即调用它
{{/* 首先定义一个名为 template 的模板,它会输出传入的数据 */}}
{{ define "template" }}
传入的数据为 {{ . }}
{{ end }}
{{/* 重新定义 template 模板并传入 . 来执行,它会先输出数据再接着提示语句 */}}
{{ block "template" . }}
{{ . }} 是传入的数据
{{ end }}
{{/* 同等于下方的代码,但需要注意:在一个模板中不允许定义另一个模板 */}}
{{ define "template" }}
{{ . }} 是传入的数据
{{ end }}
{{/* 调用重新定义后的 template 模板并传入 . 来执行*/}}
{{ template "template" . }}
为了方便替换使用,go 的 text/template 和 html/template 库中的模板是允许重复定义的,实际的模板为最后被解析的那个