- 服务端渲染
Golang为模板操作提供了丰富的支持,嵌套模板、导入函数、表示变量、迭代数据等都很简单。若需要比CSV数据格式更复杂的电脑关系,模板可能是一个不错的解决方案。模板的另一个 应用是网站的页面渲染。
Golang内置text/template
和html/template
两个模板库,html/template
库为HTML提供了完整的支持,包括普通变量渲染、列表渲染、对象渲染等。
text/template
是Golang标准库,实现数据驱动模板以生成文本输出,可理解为一组文本按照特定格式嵌套动态嵌入另一组文本中。可用来开发代码生成器。
text/template
包是数据驱动的文本输出模板,即在编写好的模板中填充数据。一般而言,模板使用流程分为三个步骤:定义模板、解析模板、数据驱动模板。
$ vim main.go
package main
import (
"os"
"text/template"
)
func main() {
//创建模板
id := 100
tmpl, err := template.New("tplname").Parse("id = {{.}}")
if err != nil {
panic(err)
}
//模板合并输出
err = tmpl.Execute(os.Stdout, id)
if err != nil {
panic(err)
}
}
$ go run main.go
id = 100
Action
-
{{.}}
中.
点号表示传入模板的数据,数据不同渲染不同。 -
.
点可代表Golang的任何类型,比如Struct、Map等。 -
{{
和}}
包裹的内容统称为Actions
模板的输入文本是任何格式的UTF-8编码文本,,action
可分为两种:
- 数据求值(data evaluations)
action
数据求值的结果会直接复制到模板中 - 控制结构(control structures)
action
控制结构和Golang程序类似,也是条件语句、循环语句、变量、函数调用等...
将模板成功解析后可安全地在并发环境中使用,若输出到同一个io.Writer
数据可能会重叠,不能保证并发执行的先后顺序。
template.New
func New(name string) *Template
template.New()
创建名为name
的模板
package main
import (
"os"
"text/template"
)
func main() {
//模板变量
type User struct {
Id int
Name string
}
user := User{100, "admin"}
//创建模板
tplname := "user"
tmpl := template.New(tplname)
//解析模板
text := "id = {{.Id}} name = {{.Name}}"
tpl, err := tmpl.Parse(text)
if err != nil {
panic(err)
}
//渲染输出
err = tpl.Execute(os.Stdout, user)
if err != nil {
panic(err)
}
}
$ go run main.go
id = 100 name = admin
template.Parse
func (t *Template) Parse(text string) (*Template, error)
template.Parse()
方法将字符串text
解析为模板,嵌套定义的模板会关联到最顶层t
。
template.Parse()
可以多次调用,但只有第一次调用可以包含空格、注释、模板定义之外的文本。若后续调用解析后仍剩余文本会引发错误、返回nil
、丢弃剩余文本。若解析得到的模板已有相关联的同名模板则会覆盖原模板。
template.ParseFiles
ParseFiles
方法接收 一个字符串,字符串的内容是一个模板文件的路径,可为绝对路径或相对路径。
解析模板文件
$ vim view/default.html
id = {{.Id}} name = {{.Name}}
解析模板文件
$ vim main.go
package main
import (
"os"
"text/template"
)
func main() {
//模板变量
type User struct {
Id int
Name string
}
user := User{100, "admin"}
//创建模板
tmpl, err := template.ParseFiles("./view/default.html")
if err != nil {
panic(err)
}
//模板合并输出
err = tmpl.Execute(os.Stdout, user)
if err != nil {
panic(err)
}
}
$ go run main.go
id = 100 name = admin
template.ExecuteTemplate
多模板时指定模板
package main
import (
"os"
"text/template"
)
func main() {
//模板变量
type User struct {
Id int
Name string
}
user := User{100, "admin"}
//创建模板
tplname := "tplname"
tmpl := template.New(tplname)
//解析模板
text := "id = {{.Id}} name = {{.Name}}"
tpl, err := tmpl.Parse(text)
if err != nil {
panic(err)
}
//渲染输出
err = tpl.ExecuteTemplate(os.Stdout, tplname, user)
if err != nil {
panic(err)
}
}
template.Execute
template.Execute()
方法将解析好的模板应用到data
,并将输出写入wr
。若执行时出现错误则会停止执行,但 有可能已经写入部分数据,模板可以安全的并发执行。
func (t *Template) Execute(wr io.Writer, data interface{}) (err error)
输出到指定文件
package main
import (
"os"
"text/template"
)
func main() {
//模板变量
type User struct {
Id int
Name string
}
user := User{100, "admin"}
//创建模板
tplname := "tplname"
tmpl := template.New(tplname)
//解析模板
text := "id = {{.Id}} name = {{.Name}}"
tpl, err := tmpl.Parse(text)
if err != nil {
panic(err)
}
//输出文件
file, err := os.OpenFile("./public/tpl.txt", os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
panic(err)
}
//渲染输出
err = tpl.Execute(file, user)
if err != nil {
panic(err)
}
}
读取模板文件解析后输出到指定位置
package main
import (
"os"
"text/template"
)
func main() {
//模板变量
type User struct {
Id int
Name string
}
user := User{100, "admin"}
//解析模板
tplFile := "./view/default.html"
tpl, err := template.ParseFiles(tplFile)
if err != nil {
panic(err)
}
//输出文件
outFile := "./runtime/view/default.html"
file, err := os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
panic(err)
}
//渲染输出
err = tpl.Execute(file, user)
if err != nil {
panic(err)
}
}
网友评论