Go模板引擎 模版函数

Go模板引擎为我们提供了函数机制,方面我们在处理模板时执行一些特定的功能,例如格式化输出内容、字母大小写转换等等。

 

1. 函数调用语法

语法格式:

functionName [Argument...]

Argument 参数是可选的,如果有多个参数,参数直接用空格分隔。

函数调用范例:

{{html "<h1>www.codebaoku.com</h1>"}}

运行输出结果:

<h1>www.codebaoku.com</h1>

html 函数的作用是对输入参数进行 html 转义处理,html 标签都转义了。

多个函数参数的例子:

{{printf "%d - %s" 100 "www.codebaoku.com"}}

printf 函数主要用于格式化输出字符串,是 fmt.Sprintf 函数的别名,用法跟 fmt.Sprintf 函数一样,区别就是模板函数的参数用空格隔开, 这里为 printf 输入了3个参数。
下面是输出:

100 - www.codebaoku.com

 

2. 内置模板函数

Go模板引擎预先定义了一些函数,我们可以直接在模板中进行函数调用,下面介绍常用的内置函数。

1)关系运算和逻辑运算函数

在模板引擎中关系运算(==、<、<=、>、>=、!=)和逻辑运算(and、or、not)都封装成函数形式,也就是说我们需要通过函数调用的方式进行关系运算和逻辑运算。

下面是关系运算函数:

函数名 函数调用格式 对应关系运算 说明
eqeq arg1 arg2arg1 == arg2arg1等于arg2则返回true
nene arg1 arg2arg1 != arg2arg1不等于arg2则返回true
ltlt arg1 arg2arg1 < arg2arg1小于arg2则返回true
lele arg1 arg2arg1 <= arg2arg1小于等于arg2则返回true
gtgt arg1 arg2arg1 > arg2arg1大于arg2则返回true
gege arg1 arg2arg1 >= arg2arg1大于等于arg2则返回true

下面是逻辑运算函数:

函数名 函数调用格式 对应逻辑运算 说明
andand 表达式1 表达式2表达式1 && 表达式2表达式1和表达式2都为真的时候返回true
oror 表达式1 表达式2表达式1 || 表达式2表达式1和表达式2其中一个为真的时候返回true
notnot 表达式!表达式表达式为false则返回true, 反之返回false

提示: 关系运算和逻辑运算函数通常跟if语句一起使用。

例子:

{{$x := 100}}

//等价于$x == 100
{{if eq $x 100}}
...代码...
{{end}}

//等价于$x < 100
{{if lt $x 500}}
...代码...
{{end}}

//等价于$x >= 100
{{if ge $x 500}}
...代码...
{{end}}

//等价于$x > 50 && $x < 200
//这里调用了and函数和gt、lt三个函数, gt和lt函数的结果作为and的参数,gt和lt函数调用分别用括号包括起来
{{if and (gt $x 50) (lt $x 200)}}
...代码...
{{end}}

{{$y := 200}}

//等价于$x > 100 || $y > 100
{{if or (gt $x 100) (gt $y 100)}}
...代码...
{{end}}

2)html函数

对html内容进行转义处理,前面的例子已经介绍。

3)len函数

用于计算数组大小。
例子:

数组大小: {{len .}}

假如传入的模板参数是一个数组:

//模板参数定义如下
a := []int{1,2,3,4}

输出:

数组大小: 4

4)printf函数

主要用于格式化字符串,是 go fmt.Sprintf 函数的别名,前面的例子已经介绍。

5)urlquery函数

主要用于url编码。
例子:

/search?keyword={{urlquery "搜索关键词"}}

输出:

/search?keyword=%E6%90%9C%E7%B4%A2%E5%85%B3%E9%94%AE%E8%AF%8D

 

3. pipeline

pipeline 翻译过来可以称为管道或者流水线, pipeline 运算的作用是将多个函数调用或者值串起来,从左往右执行,左边执行的结果会传递给右边,形成一个任务流水。

pipeline运算符:| (竖线)

语法格式:

command1 | command2 | command3 ... 

command 可以是一个值,也可以是一个函数。

例子1:

{{"<h1>www.codebaoku.com</h1>" | html}}

这里意思就是将第一个字符串值传递给html函数。

输出:

<h1>www.codebaoku.com</h1>

例子2:

{{"关键词" | html | urlquery}}

这个例子就是先将 "关键词" 传递给html函数转义下html标签,然后在将html执行结果传递给urlquery函数进行url编码。

输出:

%E5%85%B3%E9%94%AE%E8%AF%8D

提示: 如果函数有多个参数,pipeline运算会将值传递给函数的最后一个参数, 例如: {{100 | printf "value=%d"}}, 这里将100传递给printf函数的最后一个参数。

 

4. 自定义模板函数

内置的模板函数使用有限,我们可以自己定义模板函数。

下面代码展示如何自定义模板函数:

// 第一步,我们先创建FuncMap, 然后注册我们要定义的函数
// FuncMap是一个map类型
funcMap := template.FuncMap{
    // "toupper" 就是我们在模板中可以调用的函数名,
    //  strings.ToUpper就是我们要注册的函数,
    // 他的作用是将小写字母转成大写字母,这里我们直接将golang自带的函数注入进去。
    // 当然你也可以自己写一个函数
    "toupper": strings.ToUpper,
}

// 这里定义个模板代码
const templateText = `
自定义函数调用例子:{{"abcdef" | toupper}}
`

// 创建一个template对象,模板名字为test,
// 然后调用Funcs注册我们定义的模板函数,
// 然后调用Parse加载templateText模板代码。
tmpl, err := template.New("test").Funcs(funcMap).Parse(templateText)
if err != nil {
    log.Fatalf("解析模板失败: %s", err)
}

// 渲染模板
err = tmpl.Execute(os.Stdout, "")
if err != nil {
    log.Fatalf("渲染模板失败: %s", err)
}

输出:

自定义函数调用例子:ABCDEF

在实际项目中,我们不可能只有一个模板,一般来说都有很多个模板,而且这些模板也会共享一些公共的模板,这些公共的模板我们都可以定义成子模板,在需要的时候调用子模板,就可以将子模板的内容嵌入当前模板中。调用子模板语法:{{template "子模板名字" 参数}}。