内容简介:我们可以定义模板字符串,然后载入并解析渲染:模板文件,建议为每个模板文件显式的定义模板名称:
从字符串载入模板
我们可以定义模板字符串,然后载入并解析渲染:
template.New(tplName string).Parse(tpl string)
// 从字符串模板构建
tplStr := `
{{ .Name }} {{ .Age }}
`
// if parse failed Must will render a panic error
tpl := template.Must(template.New("tplName").Parse(tplStr))
tpl.Execute(os.Stdout, map[string]interface{}{Name: "big_cat", Age: 29})
从文件载入模板
模板语法
模板文件,建议为每个模板文件显式的定义模板名称: {{ define "tplName" }}
,否则会因模板对象名与模板名不一致,无法解析(条件分支很多,不如按一种标准写法实现),另展示一些基本的模板语法。
-
使用
{{ define "tplName" }}定义模板名 -
使用
{{ template "tplName" . }}引入其他模板 -
使用
.访问当前数据域:比如range里使用.访问的其实是循环项的数据域 -
使用
$.访问绝对顶层数据域
views/header.html
{{ define "header" }}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ .PageTitle }}</title>
</head>
{{ end }}
views/footer.html
{{ define "footer" }}
</html>
{{ end }}
views/index/index.html
{{ define "index/index" }}
{{/*引用其他模板 注意后面的 . */}}
{{ template "header" . }}
<body>
<div>
hello, {{ .Name }}, age {{ .Age }}
</div>
</body>
{{ template "footer" . }}
{{ end }}
views/news/index.html
{{ define "news/index" }}
{{ template "header" . }}
<body>
{{/* 页面变量定义 */}}
{{ $pageTitle := "news title" }}
{{ $pageTitleLen := len $pageTitle }}
{{/* 长度 > 4 才输出 eq ne gt lt ge le */}}
{{ if gt $pageTitleLen 4 }}
<h4>{{ $pageTitle }}</h4>
{{ end }}
{{ $c1 := gt 4 3}}
{{ $c2 := lt 2 3 }}
{{/*and or not 条件必须为标量值 不能是逻辑表达式 如果需要逻辑表达式请先求值*/}}
{{ if and $c1 $c2 }}
<h4>1 == 1 3 > 2 4 < 5</h4>
{{ end }}
<div>
<ul>
{{ range .List }}
{{ $title := .Title }}
{{/* .Title 上下文变量调用 func param1 param2 方法/函数调用 $.根节点变量调用 */}}
<li>{{ $title }} -- {{ .CreatedAt.Format "2006-01-02 15:04:05" }} -- Author {{ $.Author }}</li>
{{end}}
</ul>
{{/* !empty Total 才输出*/}}
{{ with .Total }}
<div>总数:{{ . }}</div>
{{ end }}
</div>
</body>
{{ template "footer" . }}
{{ end }}
template.ParseFiles
手动定义需要载入的模板文件,解析后制定需要渲染的模板名 news/index
。
// 从模板文件构建
tpl := template.Must(
template.ParseFiles(
"views/index/index.html",
"views/news/index.html",
"views/header.html",
"views/footer.html",
),
)
// render template with tplName index
_ = tpl.ExecuteTemplate(
os.Stdout,
"index/index",
map[string]interface{}{
PageTitle: "首页",
Name: "big_cat",
Age: 29,
},
)
// render template with tplName index
_ = tpl.ExecuteTemplate(
os.Stdout,
"news/index",
map[string]interface{}{
"PageTitle": "新闻",
"List": []struct {
Title string
CreatedAt time.Time
}{
{Title: "this is golang views/template example", CreatedAt: time.Now()},
{Title: "to be honest, i don't very like this raw engine", CreatedAt: time.Now()},
},
"Total": 1,
"Author": "big_cat",
},
)
template.ParseGlob
手动的指定每一个模板文件,在一些场景下难免难以满足需求,我们可以使用通配符正则匹配载入。
1、正则不应包含文件夹,否则会因文件夹被作为视图载入无法解析而报错
// 从模板文件构建
tpl := template.Must(template.ParseGlob("views/*.html"))
template.Must(tpl.ParseGlob("views/*/*.html"))
// render template with tplName index
// render template with tplName index
_ = tpl.ExecuteTemplate(
os.Stdout,
"index/index",
map[string]interface{}{
PageTitle: "首页",
Name: "big_cat",
Age: 29,
},
)
// render template with tplName index
_ = tpl.ExecuteTemplate(
os.Stdout,
"news/index",
map[string]interface{}{
"PageTitle": "新闻",
"List": []struct {
Title string
CreatedAt time.Time
}{
{Title: "this is golang views/template example", CreatedAt: time.Now()},
{Title: "to be honest, i don't very like this raw engine", CreatedAt: time.Now()},
},
"Total": 1,
"Author": "big_cat",
},
)
Web服务器
结合模板库和 Gin
实现一个可以使用模板渲染并返回 html
页面的 web
服务。
package main
import (
"html/template"
"log"
"net/http"
"time"
)
var (
htmlTplEngine *template.Template
htmlTplEngineErr error
)
func init() {
// 初始化模板引擎 并加载各层级的模板文件
// 注意 views/* 不会对子目录递归处理 且会将子目录匹配 作为模板处理造成解析错误
// 若存在与模板文件同级的子目录时 应指定模板文件扩展名来防止目录被作为模板文件处理
// 然后通过 view/*/*.html 来加载 view 下的各子目录中的模板文件
htmlTplEngine = template.New("htmlTplEngine")
// 模板根目录下的模板文件 一些公共文件
_, htmlTplEngineErr = htmlTplEngine.ParseGlob("views/*.html")
if nil != htmlTplEngineErr {
log.Panic(htmlTplEngineErr.Error())
}
// 其他子目录下的模板文件
_, htmlTplEngineErr = htmlTplEngine.ParseGlob("views/*/*.html")
if nil != htmlTplEngineErr {
log.Panic(htmlTplEngineErr.Error())
}
}
// index
func IndexHandler(w http.ResponseWriter, r *http.Request) {
_ = htmlTplEngine.ExecuteTemplate(
w,
"index/index",
map[string]interface{}{"PageTitle": "首页", "Name": "sqrt_cat", "Age": 25},
)
}
// news
func NewsHandler(w http.ResponseWriter, r *http.Request) {
_ = htmlTplEngine.ExecuteTemplate(
w,
"news/index",
map[string]interface{}{
"PageTitle": "新闻",
"List": []struct {
Title string
CreatedAt time.Time
}{
{Title: "this is golang views/template example", CreatedAt: time.Now()},
{Title: "to be honest, i don't very like this raw engine", CreatedAt: time.Now()},
},
"Total": 1,
"Author": "big_cat",
},
)
}
func main() {
http.HandleFunc("/", IndexHandler)
http.HandleFunc("/index", IndexHandler)
http.HandleFunc("/news", NewsHandler)
serverErr := http.ListenAndServe(":8085", nil)
if nil != serverErr {
log.Panic(serverErr.Error())
}
}
注意
:模板对象是有名字属性的, template.New("tplName")
,如果没有显示的定义名字,则会使用第一个被载入的视图文件的 baseName
做默认名,比如我们使用 template.ParseFiles/template.ParseGlob
直接生成模板对象时,没有指定模板对象名,则会使用第一个被载入的文件,比如 views/index/index.html
的 baseName
即 index.html
做默认名,而后如果 tplObj.Execute
方法执行渲染时,会去查找名为 index.html
的模板,所以常用的还是 tplObj.ExecuteTemplate
自己指定要渲染的模板名,省的一团乱。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- C++模板得实例化
- 网站模板 | 现代时尚创新创意投资组合HTML5模板设计
- ReportLibrary 报表模板库新增 21 张报表模板,加入报表导出功能!
- ReportLibrary 报表模板库新增 21 张报表模板,加入报表导出功能!
- 工具集核心教程 | 第五篇: 利用Velocity模板引擎生成模板代码
- Word 模板引擎 poi-tl V1.3.0 发布,新增模板语法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Domain-Driven Design
Eric Evans / Addison-Wesley Professional / 2003-8-30 / USD 74.99
"Eric Evans has written a fantastic book on how you can make the design of your software match your mental model of the problem domain you are addressing. "His book is very compatible with XP. It is n......一起来看看 《Domain-Driven Design》 这本书的介绍吧!