以下是一些go语言模板引擎的一些简单知识和使用
重要!!!:
模板在写动态页面的网站的时候,我们常常将不变的部分提出成为模板,可变部分通过后端程序的渲染来生成动态网页, golang也支持模板渲染。
【1】模板内内嵌的语法支持,全部需要加 {{}} 来标记。
【2】在模板文件内, . 代表了当前位置的上下文:
(1)在非循环体内,. 就代表了后端传过来的上下文
(2)在循环体中,. 就代表了循环的上下文,访问当前迭代的元素,意思是切片的话,循环里就是指数组的单个元素
【3】在模板文件内, $
.代表了模板根级的上下文
【4】在模板文件内,$有两种用法:第一种,代表了当前迭代的索引值
例子:
{{ range $index, $element := .Items }}
Index: {{ $index }}, Element: {{ $element }}
{{ end }}
第二种:在模板中定义和赋值变量:这个之后会讲到
{{ $variable := .SomeValue }}
后续的模板代码中使用 $variable来表示.SomeValue
简单示例
前端
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Gin模板引擎示例title>
head>
<body>
<h1>Hello, {{.Name}}!h1>
body>
html>
后端
{{.Name}}实际就是获取了map中name字段的值package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// 加载模板文件
r.LoadHTMLGlob("templates/*")
// 定义路由
r.GET("/hello", func(c *gin.Context) {
// 渲染模板,并传递数据
c.HTML(200, "index.html", gin.H{
"Name": "Gin User",
//注意!:gin.H{"title": "Hello Gin"}实际是map[string]interface{},通过用{{.Name}}实际就是获取了map中name字段的值,.就是上下文中gin.H传过来的数据;
})
})
// 启动应用
r.Run(":8080")
}
1. 字符串:{{ “abc啦啦啦”}} 输出 abc啦啦啦
2. 原始字符串:用转义字符{ {`啦啦啦` } } { { `a` } } 不会转义 输出 啦啦啦a
3. 字节类型:{ { 'a' } } ---> 97 会转义 输出 97
4. 打印:
打印 :字符串: { { print "abc李总辉" } } 输出:abc李总辉
nil类型:{ { print nil } } 输出:
演示:
讲到了$的第二个作用,变量的定义
Title
变量的定义:
{{$name := "马士兵888"}}
变量的使用:
{{$name}}
//最后会输出: 李总辉888
支持最简单的bool类型和字符串类型的判断:
当.condition为bool类型的时候,则为true表示执行,当.condition为string类型的时候,则非空表示执行。
{{if .Condition}}
{{/* 如果条件为真,执行此处的内容 */}}
{{else}}
{{/* 如果条件为假,执行此处的内容 */}}
{{end}}
刚刚最开始也演示过
{{range .Items}}
{{.}} {{/* 输出当前迭代的元素 */}}
{{end}}
(用到的时候再去看吧)
not 非
and 与
or 或
eq 等于
ne 不等于
lt 小于 (less than)
le 小于等于
gt 大于
ge 大于等于
其实就是提供的一个简便的写法:,用于创建一个新的局部作用域
使用起来很简单
{{with .Value}}
{{/* 在这个作用域内,可以直接访问 .Value ,就是说把.Value变成了.来操作*/}}
{{end}}
比如:
原写法:
Name: {{.Person.Name}}
Age: {{.Person.Age}}
使用with
{{with .Person}}
Name: {{.Name}}
Age: {{.Age}}
{{end}}
【1】print 打印字符串
【2】printf 按照格式化的字符串输出
格式:参照:Go中:fmt.Sprintf
PS : 具体的格式参照GO中格式:https://studygolang.com/pkgdoc
【3】len 返回对应类型的长度(map, slice, array, string, chan)
【4】管道传递符: |
函数中使用管道传递过来的数值
【5】括号提高优先级别:()`
进阶示例:
后端
func Hello1(context *gin.Context){
//定义数据:
age := 19
arr := []int{33,66,99}
//将age 和arr放入map中:
map_data := map[string]interface{}{
"age" : age,
"arr" : arr,
}
//获取路径中的参数值:
context.HTML(200,"demo01/hello.html",map_data)
将定义的数据(age和arr)传递给HTML模板,然后使用Gin框架将渲染后的HTML作为HTTP响应发送给客户端。在hello.html模板中使用age和arr的值来动态生成页面内容。
前端
<body>
{{.age}
{{range .arr}}
{{.}}
{{$.age}}
{{end}}
<br>
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
{{/*$i,$v 从 后端传过来的map_data这个上下文中获取数据 */}}
{{range $i,$v := .arr}}
{{$i}}
{{$v}}
{{end}}
</body>
后端
{{/*获取后端传过来的map_data中的内容:*/}}
{{/* . 当前的上下文,后端传过来的map_data这个上下文*/}}
{{.age}}
{{/*. 当前的上下文,后端传过来的map_data这个上下文*/}}
{{range .arr}}
{{/*. 上下文指的就是.arr这个上下文,指的就是遍历的每一个元素*/}}
{{.}}
{{/*在循环内部想获取根级上下文中的age的话,就需要使用$.来获取 (map_data这个上下文)*/}}
{{$.age}}
{{end}}
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
{{/*$i,$v 从 后端传过来的map_data这个上下文中获取数据 */}}
{{range $i,$v := .arr}}
{{$i}}
{{$v}}
{{end}}
为什么会有嵌套呢?他的作用其实还是很大的,主要用于在基础模版上充当更改部分模板的功能;
示例:
后端
// main.go
package main
import (
"html/template"
"net/http"
"github.com/gin-gonic/gin"
)
var templates *template.Template
func init() {
// 解析所有模板文件
templates = template.Must(template.ParseGlob("templates/*.html"))
}
func main() {
router := gin.Default()
// 基础路由
router.GET("/", func(c *gin.Context) {
// 渲染 index.html,不需要嵌套其他模板
renderTemplate(c, "index.html", gin.H{"Title": "Home", "Content": "Welcome to the home page"})
})
// 带有模板嵌套的路由
router.GET("/about", func(c *gin.Context) {
// 渲染 base.html,并在 content 块中嵌套 about.html
renderTemplate(c, "base.html", gin.H{"Title": "About", "Content": "about.html"})
})
router.Run(":8080")
}
func renderTemplate(c *gin.Context, tmpl string, data gin.H) {
// 执行模板渲染
err := templates.ExecuteTemplate(c.Writer, tmpl, data)
if err != nil {
// 处理错误
c.AbortWithError(http.StatusInternalServerError, err)
}
}
// 路由渲染的是 "index.html" 模板,而 /about 路由渲染的是 "base.html" 模板,并在 content 块中嵌套了 "about.html" 模板。
前端:三个文件
------------templates/base.html-----------
{{.Title}}
{{ template "content" . }}
-------------- templates/index.html--------------
{{ define "content" }}
{{.Title}}
{{.Content}}
{{ end }}
---------templates/about.html------------
{{ define "content" }}
{{.Title}}
This is the content of the about page.
{{ end }}
模板文件之间通过 {{ template "content" . }}
来实现了模板嵌套。
基础模板 “base.html” 定义了一个 content
块,子模板通过定义同名的块来覆盖或扩展基础模板中的内容。
啥意思呢?其实就是**base.html
充当了一个基础布局模板,而 index.html
和 about.html
分别充当了具体页面的内容模板。通过模板嵌套,可以轻松地在不同页面之间共享基础布局,提高模板的复用性。**
模板继承是一种模板组织方式,通过它,你可以创建一个包含通用结构和样式的基础模板,并在此基础上创建具体内容的子模板。子模板可以覆盖或扩展基础模板中的块,从而实现灵活的页面结构和外观定制。
在模板继承中,通常有两个主要角色:
案例:
----------base.html----------
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Default Title{% endblock %}title>
head>
<body>
<div id="content">
{% block content %}{% endblock %}
div>
body>
html>
-------------child.html-------------
{% extends "base.html" %}
{% block title %}Child Title{% endblock %}
{% block content %}
<h1>Welcome to the child pageh1>
<p>This is the content of the child page.p>
{% endblock %}
子模板 `child.html` 使用了 `{% extends "base.html" %}` 来声明继承自 `base.html`,然后通过 `{% block title %}...{% endblock %}` 和 `{% block content %}...{% endblock %}` 来定义或覆盖基础模板中的块。
后端:
package main
import (
"html/template"
"net/http"
"github.com/gin-gonic/gin"
)
var templates *template.Template
func init() {
// 解析所有模板文件
templates = template.Must(template.ParseGlob("templates/*.html"))
}
func main() {
// 创建Gin引擎
router := gin.Default()
// 子模板路由
router.GET("/child", func(c *gin.Context) {
// 渲染 child.html
renderTemplate(c, "child.html", nil)
})
// 启动服务器
router.Run(":8080")
}
func renderTemplate(c *gin.Context, tmpl string, data interface{}) {
// 执行模板渲染
err := templates.ExecuteTemplate(c.Writer, tmpl, data)
if err != nil {
// 处理错误
c.AbortWithError(http.StatusInternalServerError, err)
}
}
原文链自:https://lz.chatallshop.top/?p=156