HTML 模板渲染
下面是使用 Gin 框架在 Go 语言中进行 HTML 模板渲染的四个示例。每个示例都包含了必要的注释来解释代码的作用。
示例1:基本模板渲染
package mainimport ("github.com/html" title=gin>gin-gonic/html" title=gin>gin""net/http"
)func main() {r := html" title=gin>gin.Default()// 加载HTML模板文件r.LoadHTMLGlob("templates/*")// 定义一个简单的路由处理函数,渲染HTML模板r.GET("/greet", func(c *html" title=gin>gin.Context) {// 渲染 "greet.html" 模板,并传递一些数据给模板c.HTML(http.StatusOK, "greet.html", html" title=gin>gin.H{"title": "Greeting Page","message": "Hello, welcome to the Greeting page!",})})// 启动HTTP服务,默认监听0.0.0.0:8080r.Run()
}
templates/greet.html
文件内容如下:
html"><!DOCTYPE html>
<html>
<head><title>{{.title}}</title>
</head>
<body><h1>{{.message}}</h1>
</body>
</html>
示例2:带有参数的模板渲染
package mainimport ("github.com/html" title=gin>gin-gonic/html" title=gin>gin""net/http"
)func main() {r := html" title=gin>gin.Default()// 加载HTML模板文件r.LoadHTMLGlob("templates/*")// 定义一个带参数的路由处理函数,渲染HTML模板r.GET("/user/:name", func(c *html" title=gin>gin.Context) {// 获取URL路径中的参数userName := c.Param("name")// 渲染 "profile.html" 模板,并传递用户名称给模板c.HTML(http.StatusOK, "profile.html", html" title=gin>gin.H{"title": "User Profile","name": userName,})})// 启动HTTP服务,默认监听0.0.0.0:8080r.Run()
}
templates/profile.html
文件内容如下:
html"><!DOCTYPE html>
<html>
<head><title>{{.title}}</title>
</head>
<body><h1>Welcome {{.name}}!</h1>
</body>
</html>
示例3:多模板文件渲染
package mainimport ("github.com/html" title=gin>gin-gonic/html" title=gin>gin""net/http"
)func main() {r := html" title=gin>gin.Default()// 加载HTML模板文件夹下的所有模板文件r.LoadHTMLGlob("templates/*")// 定义一个路由处理函数,渲染多个模板文件r.GET("/dashboard", func(c *html" title=gin>gin.Context) {// 渲染 "header.html" 和 "content.html" 模板文件c.HTML(http.StatusOK, "header", html" title=gin>gin.H{"title": "Dashboard",})})// 启动HTTP服务,默认监听0.0.0.0:8080r.Run()
}
templates/dashboard.html
文件内容如下:
html">{{define "header"}}
<!DOCTYPE html>
<html>
<head><title>{{.title}}</title>
</head>
<body><header><h1>Header Section</h1></header>
{{end}}{{define "content"}}
<main><p>This is the content section of the dashboard.</p>
</main>
{{end}}{{define "footer"}}
<footer><p>Footer Section</p>
</footer>
</body>
</html>
{{end}}
请注意,dashboard.html
中定义了三个模板部分(header
, content
, footer
),它们可以在主模板中被调用。
示例4:模板继承和局部模板
package mainimport ("github.com/html" title=gin>gin-gonic/html" title=gin>gin""net/http"
)func main() {r := html" title=gin>gin.Default()// 加载HTML模板文件夹下的所有模板文件r.LoadHTMLGlob("templates/*")// 定义一个路由处理函数,渲染主模板并包含局部模板r.GET("/blog", func(c *html" title=gin>gin.Context) {// 渲染 "base.html" 主模板,并传递数据给模板c.HTML(http.StatusOK, "base.html", html" title=gin>gin.H{"title": "Blog Page","posts": []string{"Post 1", "Post 2", "Post 3"},})})// 启动HTTP服务,默认监听0.0.0.0:8080r.Run()
}
templates/base.html
文件内容如下:
html"><!DOCTYPE html>
<html>
<head><title>{{.title}}</title>
</head>
<body><header><h1>{{.title}}</h1></header><div id="content">{{template "postList" .}}</div>
</body>
</html>
templates/postlist.html
文件内容如下:
html">{{define "postList"}}
<ul>{{range .posts}}<li>{{.}}</li>{{end}}
</ul>
{{end}}
在这个例子中,base.html
是主模板,而 postlist.html
包含了一个局部模板,它会在主模板中被引用。通过这种方式,可以实现模板的复用和继承,从而简化页面结构和维护工作。
html" title=gin>gin__233">html" title=gin>gin 模板基本语法
Gin 框架使用 Go 的标准库 html/template
来处理模板,因此 Gin 模板的基本语法与 Go 的模板语法相同。以下是 Gin 模板的一些基本语法和特性:
变量插值
在模板中插入变量的值,可以使用双大括号 {{}}
包围变量名。
html"><p>Hello, {{.Name}}!</p>
.
表示当前上下文的数据结构。- 如果传递给模板的是一个 map 或 struct,则可以通过点符号访问其字段或键。
当然,下面是一个使用 Gin 框架和 Go 的 html/template
进行变量插值的简单示例。这个例子展示了如何将数据从 Go 代码传递到 HTML 模板,并在模板中正确显示这些数据。
示例:变量插值
Go 文件(main.go
)
package mainimport ("github.com/html" title=gin>gin-gonic/html" title=gin>gin""net/http""time"
)// 定义一个结构体来表示用户信息
type User struct {Name stringEmail stringJoinDate time.Time
}func main() {// 创建默认的 Gin 路由器r := html" title=gin>gin.Default()// 加载HTML模板文件r.LoadHTMLGlob("templates/*")// 定义一个路由处理函数,渲染HTML模板并传递用户数据r.GET("/user", func(c *html" title=gin>gin.Context) {// 创建一个用户实例user := User{Name: "Alice",Email: "alice@example.com",JoinDate: time.Now(),}// 渲染 "user.html" 模板,并传递用户数据给模板c.HTML(http.StatusOK, "user.html", html" title=gin>gin.H{"title": "User Profile","user": user,})})// 启动HTTP服务,默认监听0.0.0.0:8080r.Run()
}
html_298">HTML 模板文件(templates/user.html
)
html"><!DOCTYPE html>
<html>
<head><title>{{.title}}</title> <!-- 使用 .title 变量设置页面标题 -->
</head>
<body><h1>User Profile</h1><!-- 使用 .user.Name 和 .user.Email 插入用户名称和电子邮件 --><p>Name: {{.user.Name}}</p><p>Email: {{.user.Email}}</p><!-- 格式化并插入用户的加入日期 --><p>Joined on: {{.user.JoinDate.Format "2006-01-02"}}</p><!-- 如果你想确保输出是安全的HTML(例如包含标签),可以使用 template.HTML 类型 --></body>
</html>
代码注释解释
-
Go 文件 (
main.go
)User
结构体定义了用户信息的字段。r.LoadHTMLGlob("templates/*")
用于加载所有位于templates/
目录下的HTML模板文件。- 在
/user
路由处理函数中,创建了一个User
实例,并通过c.HTML()
方法将此实例以及页面标题一起传递给模板。 html" title=gin>gin.H{}
是一个快捷方式来创建一个 map,用于存储传递给模板的数据。
-
HTML 模板文件 (
templates/user.html
)- 使用
{{.title}}
来插入来自 Go 代码中的页面标题。 - 使用
{{.user.Name}}
和{{.user.Email}}
来插入用户的名字和邮箱地址。 - 使用
.user.JoinDate.Format "2006-01-02"
来格式化时间戳为可读的日期格式。 - 注释部分展示了如何使用
template.HTML
来输出原始HTML内容,但需要注意这可能带来安全风险,因此只有在确定内容是安全的情况下才应使用。
- 使用
通过这种方式,你可以在 Go 代码和 HTML 模板之间传递数据,并且利用 Go 的模板引擎来进行动态内容生成。
函数调用
可以在模板中调用函数,并且可以将结果直接插入到 HTML 中。
html"><p>The result is: {{add 1 2}}</p>
- 在上面的例子中,
add
是一个自定义函数,它接收两个参数并返回它们的和。
条件语句
可以使用 if
和 else
进行条件判断。
html">{{if .IsAdmin}}<p>Welcome Admin!</p>
{{else}}<p>Welcome User!</p>
{{end}}
- 支持
if
、else if
和else
结构。
下面是一个使用 Gin 框架和 Go 的 html/template
进行条件语句处理的简单示例。这个例子展示了如何在模板中根据传递的数据执行不同的逻辑分支。
示例:条件语句
Go 文件(main.go
)
package mainimport ("github.com/html" title=gin>gin-gonic/html" title=gin>gin""net/http"
)// 定义一个结构体来表示用户信息
type User struct {Name stringIsAdmin bool
}func main() {// 创建默认的 Gin 路由器r := html" title=gin>gin.Default()// 加载HTML模板文件r.LoadHTMLGlob("templates/*")// 定义一个路由处理函数,渲染HTML模板并传递用户数据r.GET("/user", func(c *html" title=gin>gin.Context) {// 创建两个不同权限级别的用户实例user1 := User{Name: "Alice",IsAdmin: true,}user2 := User{Name: "Bob",IsAdmin: false,}// 根据查询参数 'name' 来决定传递哪个用户实例给模板name := c.Query("name")var user Userif name == "Alice" {user = user1} else {user = user2}// 渲染 "profile.html" 模板,并传递用户数据给模板c.HTML(http.StatusOK, "profile.html", html" title=gin>gin.H{"title": "User Profile","user": user,})})// 启动HTTP服务,默认监听0.0.0.0:8080r.Run()
}
html_427">HTML 模板文件(templates/profile.html
)
html"><!DOCTYPE html>
<html>
<head><title>{{.title}}</title> <!-- 使用 .title 变量设置页面标题 -->
</head>
<body><h1>User Profile</h1><!-- 插入用户名 --><p>Name: {{.user.Name}}</p><!-- 使用 if-else 语句来判断用户是否为管理员 -->{{if .user.IsAdmin}}<p>Welcome Admin!</p><p>You have administrative privileges.</p>{{else}}<p>Welcome User!</p><p>You do not have administrative privileges.</p>{{end}}<!-- 你还可以添加更多的逻辑分支,例如 elseif --><!-- {{if .user.IsAdmin}}<p>Welcome Admin!</p>{{else if .user.IsModerator}}<p>Welcome Moderator!</p>{{else}}<p>Welcome User!</p>{{end}}-->
</body>
</html>
代码注释解释
-
Go 文件 (
main.go
)User
结构体定义了用户信息的字段,包括名字和是否是管理员。- 在
/user
路由处理函数中,创建了两个不同权限级别的User
实例 (user1
和user2
)。 - 根据 URL 查询参数
name
的值选择要传递给模板的用户实例。 - 使用
c.HTML()
方法将选定的用户实例以及页面标题一起传递给模板。
-
HTML 模板文件 (
templates/profile.html
)- 使用
{{.title}}
来插入来自 Go 代码中的页面标题。 - 使用
{{.user.Name}}
来插入用户的名称。 - 使用
{{if .user.IsAdmin}} ... {{else}} ... {{end}}
来进行条件判断:- 如果用户是管理员,则显示欢迎管理员的消息;
- 否则,显示普通用户的欢迎消息。
- 注释部分展示了如何使用
if-else if-else
语句来进行多分支逻辑判断,虽然在这个例子中没有用到IsModerator
字段,但这是为了展示更复杂的条件逻辑。
- 使用
通过这种方式,你可以在 Go 代码和 HTML 模板之间传递数据,并且利用 Go 的模板引擎来进行动态内容生成,同时可以根据条件改变页面内容。
循环
可以使用 range
对数组、切片、map 等进行迭代。
html"><ul>{{range .Items}}<li>{{.}}</li>{{end}}
</ul>
.
在range
内部表示当前迭代项。
下面是一个使用 Gin 框架和 Go 的 html/template
进行循环语句处理的简单示例。这个例子展示了如何在模板中遍历一个列表,并根据列表中的数据动态生成 HTML 内容。
示例:循环语句
Go 文件(main.go
)
package mainimport ("github.com/html" title=gin>gin-gonic/html" title=gin>gin""net/http"
)// 定义一个结构体来表示项目信息
type Project struct {Name stringStatus string
}func main() {// 创建默认的 Gin 路由器r := html" title=gin>gin.Default()// 加载HTML模板文件r.LoadHTMLGlob("templates/*")// 定义一个路由处理函数,渲染HTML模板并传递项目列表数据r.GET("/projects", func(c *html" title=gin>gin.Context) {// 创建一些项目实例projects := []Project{{Name: "Project Alpha", Status: "Active"},{Name: "Project Beta", Status: "Completed"},{Name: "Project Gamma", Status: "Pending"},}// 渲染 "projects.html" 模板,并传递项目列表给模板c.HTML(http.StatusOK, "projects.html", html" title=gin>gin.H{"title": "Project List","projects": projects,})})// 启动HTTP服务,默认监听0.0.0.0:8080r.Run()
}
HTML 模板文件(templates/projects.html
)
html"><!DOCTYPE html>
<html>
<head><title>{{.title}}</title> <!-- 使用 .title 变量设置页面标题 -->
</head>
<body><h1>Project List</h1><!-- 使用 range 语句遍历项目列表 --><ul>{{range .projects}}<li><strong>{{.Name}}</strong> - Status: {{.Status}}<!-- 根据项目状态添加不同类名或显示不同图标 -->{{if eq .Status "Active"}}<span class="badge badge-success">Active</span>{{else if eq .Status "Completed"}}<span class="badge badge-primary">Completed</span>{{else}}<span class="badge badge-warning">Pending</span>{{end}}</li>{{end}}</ul>
</body>
</html>
代码注释解释
-
Go 文件 (
main.go
)Project
结构体定义了项目信息的字段,包括名称和状态。- 在
/projects
路由处理函数中,创建了一个包含多个项目的切片projects
。 - 使用
c.HTML()
方法将项目列表以及页面标题一起传递给模板。
-
HTML 模板文件 (
templates/projects.html
)- 使用
{{.title}}
来插入来自 Go 代码中的页面标题。 - 使用
{{range .projects}} ... {{end}}
来遍历从 Go 代码传递过来的projects
切片。- 对于每个项目,使用
{{.Name}}
和{{.Status}}
插入项目名称和状态。 - 使用嵌套的条件语句
{{if eq .Status "Active"}} ... {{else if eq .Status "Completed"}} ... {{else}} ... {{end}}
根据项目的状态来决定显示的内容或样式。
- 对于每个项目,使用
{{range}}
循环会为每个项目生成一个<li>
元素,从而动态地构建一个无序列表。
- 使用
通过这种方式,你可以在 Go 代码和 HTML 模板之间传递数据,并且利用 Go 的模板引擎来进行动态内容生成,同时可以根据循环中的数据动态改变页面内容。这种方法非常适合用于展示列表、表格或其他需要重复元素的界面。
模板继承与包含
定义模板块
可以定义多个模板块,然后在主模板中引用它们。
html">{{define "header"}}
<header><h1>Site Header</h1>
</header>
{{end}}{{define "content"}}
<main><p>Main content goes here.</p>
</main>
{{end}}{{define "footer"}}
<footer><p>Site Footer</p>
</footer>
{{end}}
引用模板块
在主模板中引用之前定义的模板块。
html"><!DOCTYPE html>
<html>
<head><title>Page Title</title>
</head>
<body>{{template "header" .}}{{template "content" .}}{{template "footer" .}}
</body>
</html>
转义输出
Go 的 html/template
会自动转义输出以防止 XSS(跨站脚本攻击)。
html"><p>User input: {{.UserInput}}</p>
- 如果
.UserInput
包含 HTML 标签或特殊字符,这些内容会被转义,从而安全地显示为纯文本。
原始HTML输出
如果确实需要输出原始 HTML,可以使用 template.HTML
类型。
data := html" title=gin>gin.H{"RawHTML": template.HTML("<strong>Bold Text</strong>"),
}
html"><div>{{.RawHTML}}</div>
- 注意,只有当你确定内容是安全的时候才应该这样做,因为这可能会带来安全风险。
注释
模板中也可以包含注释,这些注释不会出现在最终的 HTML 输出中。
html">{{/* This is a comment and will not be rendered */}}
自定义函数
你还可以注册自定义函数,以便在模板中使用。
func init() {html" title=gin>gin.Template.FuncMap = template.FuncMap{"formatAsDate": formatAsDate,}
}func formatAsDate(t time.Time) string {return t.Format("2006-01-02")
}
html"><p>Date: {{formatAsDate .CreatedAt}}</p>
以上就是 Gin 模板的基本语法和一些常用的功能。通过这些功能,你可以创建动态且安全的 HTML 页面。
html" title=gin>gin 模板基本语法 循环语句 1个示例 代码需要注释