网站专业优化公司,现在创业什么行业最好,做网站的术语,全国新闻Gin的HTML模板配置 1 #xff09;单一目录的配置 配置模板目录#xff0c;在与main.go同级下, 新建目录#xff0c;下面二选一#xff0c;仅作举例, 这里选择 tpls templatestpls 在 tpls 目录下新建 news.html !-- 最简单的 --
h1News Page/h1单一目录的配置 配置模板目录在与main.go同级下, 新建目录下面二选一仅作举例, 这里选择 tpls templatestpls 在 tpls 目录下新建 news.html !-- 最简单的 --
h1News Page/h1h3标题{{.title}}/h3
p内容{{.content}}/p注意这里加上define和end头尾也可以{{ define news.html }}
h1News Page/h1h3标题{{.title}}/h3
p内容{{.content}}/p
{{ end }}应用程序示例中配置 r.LoadHTMLGlob(tpls/*) 通配设定r.LoadHTMLFiles(tpls/news.html) 逐个指定多个在字符串中用,分隔
程序示例
package mainimport (net/httpgithub.com/gin-gonic/gin
)var statusOK http.StatusOKfunc main() {// 创建一个默认的路由引擎r : gin.Default()// 配置模板的文件r.LoadHTMLGlob(tpls/*)// r.LoadHTMLFiles(tpls/news.html) // 逐个指定多个需要使用逗号分隔// 根路由r.GET(/, func(c *gin.Context) {c.String(statusOK, Welcome to %v, Home Page)})r.GET(/news, func(c *gin.Context) {c.HTML(statusOK, news.html, gin.H{title: 新闻标题,content: 这是详细的新闻内容,})})r.Run()
}2 多目录配置 配置模板目录在与main.go同级下, 新建目录 tpls, 在内部再创建两个目录: web, admin tpls/webtpls/admin 新建 tpls/admin/news.html {{ define admin/news.html }}h1News Page/h1h3标题{{.title}}/h3
p内容{{.content}}/p{{ end }}这里内容和之前保持一致, 但要注意上下的定义如果不添加会出现 Error #01: html/template: admin/news.html is undefined 的错误这里的 define 和 end 非常重要define 配置的路径是匹配c.HTML 中的第二个参数 应用程序示例中配置 r.LoadHTMLGlob(tpls/**/*) 通配设定r.LoadHTMLFiles(tpls/admin/news.html) 逐个指定多个在字符串中用,分隔
程序示例
package mainimport (net/httpgithub.com/gin-gonic/gin
)var statusOK http.StatusOKfunc main() {// 创建一个默认的路由引擎r : gin.Default()// 配置模板的文件r.LoadHTMLGlob(tpls/**/*)// r.LoadHTMLFiles(tpls/admin/news.html) // 逐个指定多个需要使用逗号分隔// 根路由r.GET(/, func(c *gin.Context) {c.String(statusOK, Welcome to %v, Home Page)})r.GET(/admin/news, func(c *gin.Context) {c.HTML(statusOK, admin/news.html, gin.H{title: 新闻标题,content: 这是详细的新闻内容,})})r.Run()
}3 多层复杂目录配置 首先看下设定的结构 yourGinProject/ ······························· 根目录├── go.mod ·································· go mod 文件├── go.sum ·································· go sum 文件├── main.go ································· main 文件└── tpls ····································· html模板目录├── a│ └── b│ └── c│ └── d│ └── e│ └── news.html├── admin│ └── news.html│└── news.htmltpls/news.html {{ define news.html }}h1News Page/h1h3标题{{.title}}/h3
p内容{{.content}}/p{{ end }}tpls/admin/news.html {{ define admin/news.html }}h1News Page/h1h3标题{{.title}}/h3
p内容{{.content}}/p{{ end }}tpls/a/b/c/d/e/news.html {{ define a/b/c/d/e/news.html }}h1News Page/h1h3标题{{.title}}/h3
p内容{{.content}}/p{{ end }}注意各个 news.html 的define设定
程序示例
package mainimport (net/httpgithub.com/gin-gonic/gin
)var statusOK http.StatusOKfunc main() {// 创建一个默认的路由引擎r : gin.Default()// 配置模板的文件r.LoadHTMLGlob(tpls/**/**/**/**/**/*)// 根路由r.GET(/, func(c *gin.Context) {c.String(statusOK, Welcome to %v, Home Page)})// 这个配置和紧挨着下面的配置一致只是路由自己设定了一个简洁版的r.GET(/x/news, func(c *gin.Context) {c.HTML(statusOK, a/b/c/d/e/news.html, gin.H{title: 新闻标题,content: 这是详细的新闻内容,})})// 多层路由同上r.GET(/a/b/c/d/e/news, func(c *gin.Context) {c.HTML(statusOK, a/b/c/d/e/news.html, gin.H{title: 新闻标题,content: 这是详细的新闻内容,})})// 二级r.GET(/admin/news, func(c *gin.Context) {// r.LoadHTMLGlob(tpls/**/*) // 这里会 panic 报错r.LoadHTMLFiles(tpls/admin/news.html) // 这里正常可以访问权重会大于顶部的全局配置c.HTML(statusOK, admin/news.html, gin.H{title: 新闻标题,content: 这是详细的新闻内容,})})// 一级r.GET(/news, func(c *gin.Context) {// r.LoadHTMLGlob(tpls/*) // 这里会 panic 报错r.LoadHTMLFiles(tpls/news.html) // 这里正常可以访问权重会大于顶部的全局配置c.HTML(statusOK, news.html, gin.H{title: 新闻标题,content: 这是详细的新闻内容,})})r.Run()
}可以看到在单个路由中r.LoadHTMLFiles 配置的用处了所以以上就比较麻烦一般而言在一开始设计模板的时候就要约定好规则特殊的设定只能应用于特殊的场景下
Gin的HTML模板语法 1 基本渲染
主程序
package mainimport (net/httpgithub.com/gin-gonic/gin
)var statusOK http.StatusOKtype User struct {Id intName stringHobby string
}func main() {// 创建一个默认的路由引擎r : gin.Default()// 配置模板的文件r.LoadHTMLGlob(tpls/*)// 根路由r.GET(/, func(c *gin.Context) {c.String(statusOK, Welcome to %v, Home Page)})r.GET(/user, func(c *gin.Context) {c.HTML(statusOK, user.html, User{Id: 1,Name: Wang , // 注意这里有2个空格Hobby: swimming,})})r.Run()
}html模板
{{ define user.html }}h1User Page/h1h3用户Id{{.Id}}/h3
!-- 下面这种也是注释 --
{{/* 这里是姓名本身数据存在空格但是这个去空格的方式无法去除 */}}
h3用户姓名{{- .Name -}}/h3
h3用户爱好{{.Hobby}}/h3{{ $xId : .Id }}h3演示变量: {{- $xId -}} /h3{{ end }}{{ .x }} x是属性基于这种方式来输出数据{{/* 这里是注释 */}} 注意 /* 和 */ 紧贴着 {{ 和 }}可以多行不可嵌套{{ $xId : .Id }} 单独设定变量, 变量名只能使用一个 ${{- $xId -}} 这种去除空格只能去除周围的空格无法去除属性内包含的空格且-紧贴{{和}}同时与模板值之间需要使用空格分隔
效果图 2 ) 比较, 判断, range, with
主程序
package mainimport (net/httpgithub.com/gin-gonic/gin
)type Article struct {Title stringContent string
}var statusOK http.StatusOKfunc main() {r : gin.Default()//加载模板 放在配置路由上面r.LoadHTMLGlob(tpls/**/*)//前台r.GET(/, func(c *gin.Context) {c.HTML(statusOK, web/index.html, gin.H{title: 首页,msg: 我是msg,score: 89,hobby: []string{吃饭, 睡觉, 写代码},newsList: []interface{}{Article{Title: 新闻标题1,Content: 新闻详情1,},Article{Title: 新闻标题2,Content: 新闻详情2,},},testSlice: []string{},news: Article{Title: 新闻标题,Content: 新闻内容,},})})r.Run()
}html模板
{{ define web/index.html }}h2title变量展示: {{.title}}/h2!-- 定义变量 --
{{$t : .title}}!-- 这里展示 title --
h4这里通过变量再次展现title: {{$t}}
/h4!-- 条件判断 --
h4这里基于判断展示是否及格/h4
{{if ge .score 60}}p及格/p
{{else}}p不及格/p
{{end}}h4这里基于判断更加细度展示成绩/h4{{if gt .score 90}}p优秀/p
{{else if gt .score 80}}p良好/p
{{else if gt .score 60}}p及格/p
{{else}}p不及格/p
{{end}}!-- 循环遍历数据 --
h3下面用range开始遍历 hobby 数组/h3
ul{{range $key,$value:.hobby}}li{{$key}}----{{$value}}/li{{end}}
/ulh3下面用range开始遍历 新闻 数组/h3
ul{{range $key,$value:.newsList}}li{{$key}}----{{$value.Title}}---{{$value.Content}}/li{{end}}
/ulh3下面用range遍历中空数组场景的展示/h3
ul{{range $key,$value:.testSlice}}li{{$key}}----{{$value}}/li{{else}}li数组中没有数据/li{{end}}
/ul!-- with 解构结构体 --
h3不使用 with 结构属性/h3
p{{.news.Title}}/p
p{{.news.Content}}/ph3使用 with 结构属性/h3
{{with .news}}p{{.Title}}/pp{{.Content}}/p
{{end}}{{ end }}关于比较函数中的一些注意事项 eq 如果 arg1 arg2 则返回真ne 如果 arg1 ! arg2 则返回真lt 如果 arg1 arg2 则返回真le 如果 arg1 arg2 则返回真gt 如果 arg1 arg2 则返回真ge 如果 arg1 arg2 则返回真
效果图 3 高阶用法预定义函数自定义模板函数嵌套模板
首先看下设定的结构yourGinProject/ ······························· 根目录├── go.mod ·································· go mod 文件├── go.sum ·································· go sum 文件├── main.go ································· main 文件└── tpls ····································· html模板目录├── web│ └── index.html└── common└── page_header.html└── page_footer.html主程序
package mainimport (html/templatenet/httptimegithub.com/gin-gonic/gin
)type Article struct {Title stringContent string
}var statusOK http.StatusOK//时间戳转换成日期
func UnixToTime(timestamp int) string {t : time.Unix(int64(timestamp), 0)return t.Format(2006-01-02 15:04:05) // 这个是按照这个时间来进行格式化, 必须是这个时间点, 据说是go诞生之日
}func Println(str1 string, str2 string) string {return str1 ---- str2
}func main() {// 创建一个默认的路由引擎r : gin.Default()//自定义模板函数, 注意要把这个函数放在加载模板前r.SetFuncMap(template.FuncMap{UnixToTime: UnixToTime,Println: Println,})//加载模板 放在配置路由上面r.LoadHTMLGlob(tpls/**/*)// 前台r.GET(/, func(c *gin.Context) {c.HTML(statusOK, web/index.html, gin.H{title: 首页,titleEn: homePage,msg: demo,date: 1708344953,})})r.Run()
}web/index.html模板
{{ define web/index.html }}!-- 这里定义通用头部 --{{template common/page_header.html .}}h3下面演示: 预定义函数/h3!-- 预定义函数 --{{ len .title }}br /{{ len .titleEn }}!-- 自定义模板函数 --h3下面演示: 自定义模板函数/h3{{.date}}br /br /{{UnixToTime .date}}brbr{{Println .title .msg}}!-- 这里定义通用尾部 --{{template common/page_footer.html .}}{{ end }}common/page_header.html模板
{{ define common/page_header.html }}h3我是一个公共的标题---{{.title}}/h3
{{end}}common/page_footer.html模板
{{ define common/page_footer.html }}h3我是一个公共的底部/h3
{{end}}在 预定义函数 中执行模板时函数从两个函数字典中查找 首先是模板函数字典然后是全局函数字典。一般不在模板内定义函数而是使用 Funcs 方法添加函数到模板里 预定义的全局函数如下 and 函数返回它的第一个 empty 参数或者最后一个参数就是说and x y等价于if x then y else x所有参数都会执行 or 返回第一个非 empty 参数或者最后一个参数亦即or x y等价于if x then x else y所有参数都会执行 not 返回它的单个参数的布尔值的否定 len 返回它的参数的整数类型长度 index 执行结果为第一个参数以剩下的参数为索引/键指向的值如index x 1 2 3返回 x[1][2][3]的值每个被索引的主体必须是数组、切片或者字典 print 即 fmt.Sprint printf 即 fmt.Sprintf println 即 fmt.Sprintln html 返回与其参数的文本表示形式等效的转义 HTML这个函数在 html/template 中不可用 urlquery 以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值这个函数在 html/template 中不可用 js 返回与其参数的文本表示形式等效的转义 JavaScript call 执行结果是调用第一个参数的返回值该参数必须是函数类型其余参数作为调用该函 数的参数如call .X.Y 1 2等价于 go 语言里的 dot.X.Y(1, 2)其中 Y 是函数类型的字段或者字典的值或者其他类似情况call 的第一个参数的执行结果必须是函数类型的值和预定义函数如 print 明显不同该函数类型值必须有 1 到 2 个返回值如果有 2 个则后一个必须是 error 接口类型如果有 2 个返回值的方法返回的 error 非 nil模板执行会中断并返回给调用模板执行者该错误 在自定义模板函数中比如定义了 formatDate 方法有两种用法 {{.now | formatDate}} 或{{formatDate .now }} 在嵌套 template中注意最后的点.
效果图 静态文件服务器的配置 这块比较简单
主程序
package mainimport (net/httpgithub.com/gin-gonic/gin
)var statusOK http.StatusOKfunc main() {// 创建一个默认的路由引擎r : gin.Default()//配置静态web目录 第一个参数表示路由, 第二个参数表示映射的目录r.Static(/static, ./static)// 前台r.GET(/, func(c *gin.Context) {c.String(statusOK, Welcome to %v, Home Page)})r.Run()
}这样就设定好了在与 main.go 同级新建 static/images 目录添加 mysql-logo.svg 图片访问该图片: http://localhost:8080/static/images/mysql-logo.svg其他的如css, js 这类也同样适用这时候静态文件服务器就搭建好了