最近在看gin,在模版引擎这块被卡克啦----伟大的强啊。今天就来分享一下gin的模版引擎渲染。
一 初始化
func Run(engine *gin.Engine) {
//设置模版位置
//engine.LoadHTMLGlob("./web/views/**/*")
group := engine.Group("/web")
engine.HTMLRender = loadTemplates("./web/views", []string{"admin", "member"})
//engine.Static("/resources", "./web")
//配置web服务 添加middleware
m.UsemiddlewareFor(group)
.....
上面是按照group进行了一个简易的初始化,关键是是loadTemplates这个函数,下面我们看是如何处理的
func loadTemplates(templatesDir string, categories []string) multitemplate.Renderer {
r := multitemplate.NewRenderer()
for _, category := range categories {
layouts, err := filepath.Glob(templatesDir + "/layouts/" + category + "-*.html")
if err != nil {
panic(err.Error())
}
includes, err := filepath.Glob(templatesDir + "/includes/" + category + "/*.html")
if err != nil {
panic(err.Error())
}
// Generate our templates map from our layouts/ and includes/ directories
for _, include := range includes {
layoutCopy := make([]string, len(layouts))
copy(layoutCopy, layouts)
files := append(layoutCopy, include)
r.AddFromFiles(category+TemplateJoin+filepath.Base(include), files...)
}
}
return r
}
在讲解之前我们需要先说明一个基础:gin的模版引擎是按照基于某一个自定的模版,然后其余相关按照模版进行填充渲染的…
例如下图中我们是基于admin-base.html做为模板,然后关联的admin下的category功能页面则基于此进行填充渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="referrer" content="never">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
{{template "head" .}}
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
{{template "head-script" .}}
</head>
<body>
{{template "content" .}}
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdn.bootcss.com/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</body>
</html>
上文中的代码定义了模版,其中将其拆分为head head-script以及content部分,这样后续的子模版渲染时基于此,进行填充 head head-sript和content就可。我们接下来看一个category实例
{{define "head"}}
{{end}}
{{define "content"}}
<div class="container">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark align-items-start">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav row align-items-start justify-content-between">
{{range .Result}}
<li class="nav-item active">
<a role="button" class="btn nav-item nav-link active" href="/{{.Id}}.html">{{.Name}}</a>
</li>
{{end}}
</ul>
</div>
</nav>
<div class="row align-items-start justify-content-between">
{{range .Result}}
<div class="card" style="width: 15rem;">
<img class="card-img-top"
src="http://i0.hdslb.com/bfs/archive/4dfaec064e0de989eef9057f9ce06f038c930002.jpg"
alt="Card image cap">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk
of the card's content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
{{end}}
</div>
</div>
{{end}}
实例中我们分别基于admin模版填充了
{{define "head"}}
{{end}}
{{define "content"}}
正文部分
{{end}}
二引擎使用
粗略看了一下我们来看看基本语法 :所有的都一{{ }}开头 {{end}}结束
for循环
{{range .list}}
渲染的事件
{{ }}
当然了也可更加详情
{{$index, $value:= range .list }}
{{end}}
ifelse
{
{if .A}}
{{else}}
{{end}}
三根据web权限进行划分
文章开头我们就是了按照分类进行划分,然后渲染到不同的模版中,那么gin是如何来确定模版的(看下图):
图示是我们基于划分之后渲染debug截图,我们看到gin采用map的方式来存取我们所有的模版文件。接着我们点开查看
gin将母版和子模版结合起来,完成一个render。na么我们怎么来划分比较好呢?lz目前采用如下划分方式
母版单独放置,子模版单独放置,根据母版与子版映射关联:
1 母版前缀子版
2 前缀作为子版文件夹名称
3 母版@子版名称作为key来拿取对应渲染模版信息 context.HTML(http.StatusOK, "admin"+TemplateJoin+"topic.html", result)