Go 从零开始(五)模板文件
用 template 标准库构建模板。
模板语法默认全部包含在定界符双花括号 “”{{ }}“” 中。
下面介绍的没有举例的语法,在最后的实例中可以看到。
一、模板常用语法
1、{{ . }}
括号中的点,表示当前对象。
给模板传入结构体或 map 时,用点语法访问对应的数据。
2、with 关键词
with 后面加上点语句,用 end 结尾。
当点语句为空时,with 这一块不会输出。
with 块内的 {{ . }} 代表 with 后面的点语句获取的内容。
with 后面的语句,可以用管道符 “|” 连接多条语句,用法和 Linux 中的管道符类似。
3、注释
{{/* 这是一个注释 */}}
注释不能嵌套,且必须紧贴边界符花括号。
4、移除空格
{{- .Name -}}
{{- 移除左侧所有空格
-}} 移除右侧所有空格
必须紧贴边界符。
5、条件判断
{{if ...}} T1 {{end}}
{{if ...}} T1 {{else}} T0 {{end}}
{{if ...}} T1 {{else if ...}} T0 {{end}}
6、循环遍历
{{range ...}} T1 {{end}}
如果遍历长度为 0,则不会输出
{{range pipeline}} T1 {{else}} T0 {{end}}
如果遍历长度为 0,则会执行 T0。
二、template 标准库常用操作
1、初始化模板
html := "<html><head></head><body><h2>Hello</h2></body></html>"
tmpl, err := template.New("create-form").Parse(html)
html 是模板标签字符串
2、引入 html 文件
tmpl, err := template.New("create-form").ParseFiles("filename.gohtml")
这里将 html 文件的后缀名命名为 gohtml,其他后缀名也不会影响正常运行。
3、修改默认边界符
tmpl, err := template.New("create-form").Delims("{[", "]}").ParseFiles("filename.gohtml")
4、把动态数据塞给模板
data := ArticlesFormData{
Title: title,
Body: body,
URL: storeURL,
Errors: errors,
}
tmpl, err := template.New("create-form").Parse(html)
if err != nil {
panic(err)
}
err = tmpl.Execute(w, data)
if err != nil {
panic(err)
}
三、完善上一篇博文中的 store 方法,供参考。
func articlesStoreHandler(w http.ResponseWriter, r *http.Request) {
title := r.PostFormValue("title")
body := r.PostFormValue("body")
errors := make(map[string]string)
if title == "" {
errors["title"] = "标题不能为空"
} else if utf8.RuneCountInString(title) < 3 || utf8.RuneCountInString(title) > 40 {
errors["title"] = "标题长度需介于 3-40"
}
if body == "" {
errors["body"] = "内容不能为空"
} else if utf8.RuneCountInString(body) < 10 {
errors["body"] = "内容长度需大于或等于 10 个字节"
}
if len(errors) == 0 {
fmt.Fprintf(w, "title: %v <br>", title)
fmt.Fprintf(w, "body: %v <br>", body)
} else {
html := `
<!DOCTYPE html>
<html lang="en">
<head>
<title>创建文章 —— 我的技术博客</title>
<style type="text/css">.error {color: red;}</style>
</head>
<body>
<form action="{{ .URL }}" method="post">
<p><input type="text" name="title" value="{{ .Title }}"></p>
{{ with .Errors.title }}
<p class="error">{{ . }}</p>
{{ end }}
<p><textarea name="body" cols="30" rows="10">{{ .Body }}</textarea></p>
{{ with .Errors.body }}
<p class="error">{{ . }}</p>
{{ end }}
<p><button type="submit">提交</button></p>
</form>
</body>
</html>
`
storeURL, _ := router.Get("articles.store").URL()
data := ArticlesFormData{
Title: title,
Body: body,
URL: storeURL,
Errors: errors,
}
tmpl, err := template.New("create-form").Parse(html)
if err != nil {
panic(err)
}
err = tmpl.Execute(w, data)
if err != nil {
panic(err)
}
}
}