最近研究了Golang Template 模板引擎,发现它自身提供的能力比较弱,很多常用的功能都没有,比如字符串替换、判断,base64加解密等等。但是Golang Template给我们预留了自定义函数,也就是template.FuncMap,可以满足我们功能的扩展。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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)
	}

}

以上是一个Go语言 Template中的例子,自定义扩展了一个title函数,它的能力通过strings.Title实现。然后我们通过如下代码生成一个template.FuncMap:

1
2
3
4
funcMap := template.FuncMap{
		// The name "title" is what the function will be called in the template text.
		"title": strings.Title,
	}

有了funcMap就可以通过template的Funcs方法注册这个扩展的函数了,这样我们就可以在模板里使用它。

1
2
3
4
5
6
const templateText = `
Input: {{printf "%q" .}}
Output 0: {{title .}}
Output 1: {{title . | printf "%q"}}
Output 2: {{printf "%q" . | title}}
`

以上就是一个通过自定义函数增强Golang Template的例子,这样就可以扩展Golang Template的能力。

最开始的想法是通过Golang Template做一个开源项目,把常用的模板函数能力都实现了,但是又怕重复造轮子,所以就去Github上搜索有没有已经实现好的库,搜索了一圈没有找到(大家找到了记得告我我)。

没有找到就只能自己做了,在开始写之前,又想起来HUGO这个开源项目,我自己的博客就是用这个构建的。HUGO为了支持博客的自定义,所以内置了很多强大的模板函数,既然这样,可以把HUGO的这些模板函数抽取出来,进行修改和增强,这样就可以形成了一个日常使用的工具库了。

然后周末晚上,夜深人静的时候,着手准备,最终花了近4个小时的时间,抽取了一个beta版本。隔了几天,又在一个夜深人静的黑夜,完善了相关代码和文档,最终开源到了Github上。

开源库地址:https://github.com/flysnow-org/soha

开源库地址:https://github.com/flysnow-org/soha

这个库的使用非常简单,首先你需要导入这个库 import "github.com/flysnow-org/soha"。 然后通如下函数获取一个FuncMap

1
sohaFuncMap := soha.CreateFuncMap()

有了FuncMap就非常容易了,如果你使用内置的template,那么只需要调用Funcs方法即可。

1
tmpl, err := template.New("titleTest").Funcs(sohaFuncMap).Parse(templateText)

如果你使用的是gin这类Golang Web框架,那么只需要使用如下代码注册即可:

1
2
3
4
    router := gin.Default()
    
    sohaFuncMap := soha.CreateFuncMap()
    router.SetFuncMap(sohaFuncMap)

这里有一个Hello World,大家可以参考。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main

import (
	"github.com/flysnow-org/soha"
	"html/template"
	"log"
	"os"
)
func main() {

	sohaFuncMap := soha.CreateFuncMap()
	const templateText = `{{md5 .}}`

	tmpl, err := template.New("titleTest").Funcs(sohaFuncMap).Parse(templateText)
	if err != nil {
		log.Fatalf("parsing: %s", err)
	}

	err = tmpl.Execute(os.Stdout, 123456)
	if err != nil {
		log.Fatalf("execution: %s", err)
	}

}

SOHA 为Golang Template增强了五六十个函数,涉及到字符串、URL、转换、hash、base64、math、集合等方方面面,让你的Golang Web开发事半功倍。每个函数的说明和示例等请参考github repo库,都有详细的说明,中英文文档都有。

SOHA 因为从HUGO里抽取了代码,所以继续保留了HUGO的 Apache Licence。欢迎大家star、issue、pr等贡献,多多使用。

一切都是为了,不再996。

本文为原创文章,转载注明出处,欢迎扫码关注公众号flysnow_org或者网站asf https://www.flysnow.org/ ,第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「在看」,感谢支持。

扫码关注