golang中template包的简单实用


今天看了一段golang的代码,其中有个文本输出是使用了html/template,由于之前老是遗忘这个包是如何使用的,这次查看了下,就记录下简单的使用方法。

使用环境

看这个包的名字,我的感觉就是它是在html中使用的或者是服务器跟前端交互中展现、渲染页面使用的。 在查看了官网后看到一句话说是:

It provides the same interface as package text/template and should be used instead of text/template whenever the output is HTML

它提供了与text/template一样的接口,也就是说text/template这个包能做的那么它也能做,可以作为html页面的渲染展示,也可以作为普通文本的输出使用。

使用方式

通过一个小代码来解释一下吧:

var (
        httpTemplate = `
        
     will come
        
        `
    )
    
    type TestData struct {
        AppName template.HTML
    }
    
    func main() {
        datas := make([]TestData, 0)
        datas = append(datas, TestData{AppName: "zk"})
        datas = append(datas, TestData{AppName: "zkp"})
        datas = append(datas, TestData{AppName: "zkc"})
        t := template.New("top")
        t.Funcs(template.FuncMap{"trim": func(s template.HTML) template.HTML {
            return template.HTML(strings.Repeat(string(s), 4))
        }})
        template.Must(t.Parse(httpTemplate))
        err := t.Execute(os.Stdout, datas)
        if err != nil {
            panic(err)
        }
    }

上面这段代码只有一个很简单的输出内容,就是输出TestData这个结构体的AppName这个字段。这里的httpTemplate字符串是一个模板渲染的语法。这个稍后解释,先看看模板的使用方法,首先通过new这个方法创建一个模板实例t,类型为*template,这个t有很多的方法,下面看看它其中的三个比较重要的方法,第一个就是Parse方法,它解析了需要进行渲染的字符串,我个人的理解是它起到了一个类似于编译的作用,编译了模板语法写成了语句,这里就是httpTemplate这个字符串语句。编译好了之后当然就是执行了,Execute方法就是执行这个编译过后的语句,方法有两个参数,一个是需要把最终结果输出到哪里,还有一个是语句参数的值。之后就会在参数一的地方输出执行后的结果了。template.Must这个方法是保证我们在编译语句的时候出错了就立刻引发panic异常。而t.Funcs这个方法在看过语句之后在来解释,现在可以完全忽略它。

模板语法

现在看看模板语句,也就是httpTemplate这个字符串,双大括号是区分模板代码(里面的变量由Execute执行时传入的)和HTML或者正常文本的分隔符(可通过template包提供的Delims方法修改),括号里面可以显示输出的数据,或者是控制语句,比如if判断或者range循环等。跟在range后面的必须是一个array,slice或者map类型变量,这点跟golang的循环中range后面的类型一样,但是在语句中只是一个点“.”并看不出来是什么类型,那这个点代表了什么?这里就要和上面的程序代码结合起来了,我们在Execute的时候传进去第二个参数datas,很明显datas这个变量是个slice类型的,忽略“| trim”,我们可以把这个语句翻译成

for _,v:=range datas{
        fmt.Println(v.AppName+"will come")  
    }

.AppName不需要解释也知道是代表什么了吧,就是TestData这个结构体里的变量。那么输出结果就很明显了。

现在回到之前被忽略了的地方,遭受冷落心里总归是不爽的,那么现在我们就用极大的热情看看它们吧。 首先看看语句里面被忽略的| trim,要是使用过linux或者类unix的操作系统的人肯定第一反应就是匿名管道,这里我们也可以把它认为就是个匿名管道,那么管道的左边是数据的输入,右边是操作左边流入的数据的程序。左边的.AppName不用解释了,它将把值往|中流入,那么操作这个数据流的程序找来找去只看到了trim这个东西了,操作数据流的方法就是它了,我们程序中的方法无外乎两种,一种就是包自带的,还有就是自己实现的。那么包中没有trim这个方法,那就要写个方法实现它了。如何实现,我们就要看代码中之前被我们忽略的地方了,哎,它都等不及要表现一下了。没做就是

t.Funcs(template.FuncMap{"trim": func(s template.HTML) template.HTML {
    return template.HTML(strings.Repeat(string(s), 4))
}})

t.Funcs方法有个FuncMap类型的参数,这个具体可以查看文档,FuncMap是个map类型type FuncMap map[string]interface{},顾名思义,这个方法的功能就是用来函数映射的,将一个字符串映射到一个函数中去,函数的输入参数就是管道左边的数据流变量值,函数的输出参数就是对数据流处理过后的结果。那么``我们可以把它看作是:

func trim(s template.HTML) template.HTML{
        return template.HTML(strings.Repeat(string(s),4))
    }
    fmt.Println(trim(AppName))

执行的结果: 执行结果


非专业娱乐型程序员。
Published under (CC) BY-NC-SA in categories 技术  tagged with golang