Go包text/template语法解析
包模板实现了用于生成文本输出的数据驱动模板。
模板内的数据会用{{}}包裹,{{ action }}其中的内容称为action.
action主要分为俩类内容:
- 数据的值
- 控制语句
{{ . }} .代表传入的数据 {{ .title }} 使用传入的title变量
语法介绍
{{/* comment */}} 注释
{{- content -}} 去掉俩边的空格
{{ pipeline }} 输出普通文本
{{ if pipeline }} xxx {{ else if pipeline }} xxx {{ end }} if条件语句
{{ range pipeline }} xxx {{ end }} 简单的循环语句
{{ range pipeline }} xxx {{ else }} xxx {{ end }} 条件循环语句
{{ range $index, $value := pipeline }} xxx {{ end }} 普通的循环语句
{{ define "name" }} 模板 {{ end }} 给模板命名
{{ template "name" }} 引用模板,配合define使用,可以完成模板部分的复用吧
{{ template "name" pipeline }} 条件引用模板
{{ block "name" pipeline }} 自定义模板内容 {{ end }} 使用模板name, 如果没有就使用自定义的模板内容
{{ with pipeline }} 模板1 {{ else }} 模板2 {{ end }} 一个新的上下文,如果条件不为空就模板1,否则模板2
比较运算符
eq 返回 arg1 == arg2 的布尔值
ne 返回 arg1 != arg2 的布尔值
lt 返回 arg1 < arg2 的布尔值
le 返回 arg1 <= arg2 的布尔值
gt 返回 arg1 > arg2 的布尔值
ge 返回 arg1 >= arg2 的布尔值
变量
定义变量: {{ $var = pipeline }}
变量的作用域:模板开始定义的变量作用域在整个模板,模板中块内定义的变量作用域在块内
函数
自定义函数接口:func (t *Template) Funcs(funcMap FuncMap) *Template
全局内置函数
and
{{ and .x .y .z }} xyz全部为true,返回最后一个值(z),如果任意一个为fasle,则返回它
or
{{ or .x .y .z }} xyz任意一个值为true则返回它,全为false则返回最后一个值
call
{{ call .fn .y .z } 调用fn函数传入yz参数,如果结果error不为nil, 则fatal
html 返回转义后的 HTML 字符串,这个函数不能在 html/template 中使用。
js 返回转义后的 JavaScript 字符串。
index 在第一个参数是 array、slice、map 时使用,返回对应下标的值。
index x 1 2 3 等于 x[1][2][3]。
len 返回复合类型的长度。
not 返回布尔类型参数的相反值。
print 等于 fmt.Sprint。
printf 等于 fmt.Sprintf。
println 等于 fmt.Sprintln。
urlquery 对字符串进行 url Query 转义,不能在 html/template 包中使用。
模板解析和执行
解析
引入模板,不存在就报错
func Must(t *Template, err error) *Template
从字符串new模板
func New(name string) *Template
从文件系统中查找符合匹配规则的模板
func ParseFS(fsys fs.FS, patterns ...string) (*Template, error)
加载指定的多个模板文件
func ParseFiles(filenames ...string) (*Template, error)
加载符合匹配条件的模板
func ParseGlob(pattern string) (*Template, error)
执行
//传入模板参数,执行模板,打印输出
err := tmpl.Execute(os.Stdout, "no data needed")
if err != nil {
log.Fatalf("execution failed: %s", err)
}
//当有加载了很多模板的时候,可以指定要执行的模板名称(T2),传入参数,执行模板,打印输出
err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed")
if err != nil {
log.Fatalf("execution failed: %s", err)
}
加载匹配的所有的模板
//go:embed tpl/*
templateDir embed.FS
var patternTmpl = []string{
"tpl/migrate/*.tpl",
"tpl/*.tpl",
}
tmpl := template.Must(template.ParseFS(templateDir,patternTmpl...))
name := "create,tpl"
data := "User"
if err := tmpl.ExecuteTemplate(b, name, data); err != nil {
log.Printf("execute template %q: %w", tmpl.Name, err)
}
在模板内使用自定义函数 funcMap
package main
import (
"log"
"os"
"strings"
"text/template"
)
func main() {
// First we create a FuncMap with which to register the function.
funcMap := template.FuncMap{
// The name "title" is what the function will be called in the template text.
"title": strings.Title,
}
// A simple template definition to test our function.
// We print the input text several ways:
// - the original
// - title-cased
// - title-cased and then printed with %q
// - printed with %q and then title-cased.
const templateText = `
Input: {{printf "%q" .}}
Output 0: {{title .}}
Output 1: {{title . | printf "%q"}}
Output 2: {{printf "%q" . | title}}
`
// Create a template, add the function map, and parse the text.
tmpl, err := template.New("titleTest").Funcs(funcMap).Parse(templateText)
if err != nil {
log.Fatalf("parsing: %s", err)
}
// Run the template to verify the output.
err = tmpl.Execute(os.Stdout, "the go programming language")
if err != nil {
log.Fatalf("execution: %s", err)
}
}