Gin渲染

HTML渲染

【示例1】

首先定义一个存放模板文件的 templates文件夹,然后在其内部按照业务分别定义一个 posts 文件夹和一个 users 文件夹。
在这里插入图片描述

posts/index.tmpl

{{define "posts/index.tmpl"}}
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>posts/index</title>
</head>
<body>{{.title}}
</body>
</html>
{{end}}

users/index.tmpl

{{define "users/index.tmpl"}}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>users/index</title>
</head>
<body>{{.title}}
</body>
</html>
{{end}}

main.go

Gin框架中使用 LoadHTMLGlob() 或者 LoadHTMLFiles() 方法进行HTML模板渲染。

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()// r.LoadHTMLFiles("templates/index.tmpl", "templates/users/index.tmpl") // 模板解析r.LoadHTMLGlob("templates/**/*") // 从templates4目录及其所有子目录中加载所有的文件r.GET("/posts/index", func(c *gin.Context) {// HTTP请求c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{ // 模板渲染"title": "posts/index.tmpl",})})r.GET("/users/index", func(c *gin.Context) {// HTTP请求c.HTML(http.StatusOK, "users/index.tmpl", gin.H{ // 模板渲染"title": "users/index.tmpl",})})r.Run(":9090") // 启动server
}

效果

在这里插入图片描述

在这里插入图片描述

【示例2】

main.go

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.LoadHTMLFiles("./index.tmpl") // 模板解析r.GET("/index", func(c *gin.Context) {// HTTP请求c.HTML(http.StatusOK, "index.tmpl", gin.H{ // 模板渲染"title": "liwenzhou.com",})})r.Run(":9090") // 启动server
}

index.tmpl

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>posts/index</title>
</head>
<body>
{{.title}}
</body>
</html>

效果

在这里插入图片描述

自定义模板函数

定义一个不转义相应内容的 safe 模板函数

main.go

package mainimport ("github.com/gin-gonic/gin""html/template""net/http"
)func main() {r := gin.Default()// gin框架中给模板添加自定义函数r.SetFuncMap(template.FuncMap{"safe": func(str string) template.HTML {return template.HTML(str)},})r.LoadHTMLGlob("templates/**/*") // 从templates4目录及其所有子目录中加载所有的文件r.GET("/users/index", func(c *gin.Context) {// HTTP请求c.HTML(http.StatusOK, "users/index.tmpl", gin.H{ // 模板渲染"title": "<a href='https://liwenzhou.com'>李文周的博客</a>",})})r.Run(":9090") // 启动server
}

users/index.tmpl

{{define "users/index.tmpl"}}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>users/index</title></head><body>{{.title | safe}}</body></html>
{{end}}

效果

在这里插入图片描述

静态文件处理

当渲染的HTML文件中引用了静态文件时,只需要按照以下方式在渲染页面前调用 gin.Static 方法即可。

main.go

package mainimport ("github.com/gin-gonic/gin""html/template""net/http"
)// 静态文件: html页面上用到的样式文件 。css js文件 图片
func main() {r := gin.Default()// 加载静态文件r.Static("/xxx", "./statics")// gin框架中给模板添加自定义函数r.SetFuncMap(template.FuncMap{"safe": func(str string) template.HTML {return template.HTML(str)},})r.LoadHTMLGlob("templates/**/*") // 从templates4目录及其所有子目录中加载所有的文件r.GET("/users/index", func(c *gin.Context) {// HTTP请求c.HTML(http.StatusOK, "users/index.tmpl", gin.H{ // 模板渲染"title": "<a href='https://liwenzhou.com'>李文周的博客</a>",})})r.Run(":9090") // 启动server
}

users/index.tmpl

{{define "users/index.tmpl"}}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><link rel="stylesheet" href="/xxx/index.css"><title>users/index</title></head><body>{{.title | safe}}</body></html>
{{end}}

index.css

body {background-color: cadetblue;
}

效果

在这里插入图片描述

使用模板继承

Gin框架默认都是使用单模板,如果需要使用 block template 功能,可以通过 "github.com/gin-contrib/multitemplate" 库实现,具体示例如下:

首先,假设项目目录下的templates文件夹下有以下模板文件,其中 home.tmplindex.tmpl 继承了 base.tmpl

templates
├── includes
│   ├── home.tmpl
│   └── index.tmpl
├── layouts
│   └── base.tmpl
└── scripts.tmpl

定义一个 loadTemplates 函数

func loadTemplates(templatesDir string) multitemplate.Renderer {r := multitemplate.NewRenderer()layouts, err := filepath.Glob(templatesDir + "/layouts/*.tmpl")if err != nil {panic(err.Error())}includes, err := filepath.Glob(templatesDir + "/includes/*.tmpl")if err != nil {panic(err.Error())}// 为layouts/和includes/目录生成 templates mapfor _, include := range includes {layoutCopy := make([]string, len(layouts))copy(layoutCopy, layouts)files := append(layoutCopy, include)r.AddFromFiles(filepath.Base(include), files...)}return r
}

main 函数

func indexFunc(c *gin.Context){c.HTML(http.StatusOK, "index.tmpl", nil)
}func homeFunc(c *gin.Context){c.HTML(http.StatusOK, "home.tmpl", nil)
}func main(){r := gin.Default()r.HTMLRender = loadTemplates("./templates")r.GET("/index", indexFunc)r.GET("/home", homeFunc)r.Run()
}

补充文件路径处理

关于模板文件和静态文件的路径,需要根据公司/项目的要求进行设置。可以使用下面的函数获取当前执行程序的路径。

func getCurrentPath() string {if ex, err := os.Executable(); err == nil {return filepath.Dir(ex)}return "./"
}

JSON渲染

方法1:使用map

main.go1 :map

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.GET("/json", func(c *gin.Context) {data := map[string]interface{}{"name":    "小王子","message": "hello world!","age":     18,}c.JSON(http.StatusOK, data)})r.Run(":9090")
}

main.go2:gin.H

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()r.GET("/json", func(c *gin.Context) {data := gin.H{"name": "小王子", "message": "hello world!", "age": 18}c.JSON(http.StatusOK, data)})r.Run(":9090")
}

效果

在这里插入图片描述

方法2: 结构体

main,go

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()type msg struct {Name    stringMessage stringAge     int}r.GET("/another_json", func(c *gin.Context) {data := msg{"小王子","Hello golang!",18,}c.JSON(http.StatusOK, data)})r.Run(":9090")
}

效果

在这里插入图片描述

使用tag

package mainimport ("github.com/gin-gonic/gin""net/http"
)func main() {r := gin.Default()type msg struct {// 灵活使用tag来对结构体字段做定制化操作Name    string `json:"name"`Message stringAge     int}r.GET("/another_json", func(c *gin.Context) {data := msg{"小王子","Hello golang!",18,}c.JSON(http.StatusOK, data)})r.Run(":9090")
}

在这里插入图片描述

XML渲染

注意需要使用具名的结构体类型。

func main() {r := gin.Default()// gin.H 是map[string]interface{}的缩写r.GET("/someXML", func(c *gin.Context) {// 方式一:自己拼接JSONc.XML(http.StatusOK, gin.H{"message": "Hello world!"})})r.GET("/moreXML", func(c *gin.Context) {// 方法二:使用结构体type MessageRecord struct {Name    stringMessage stringAge     int}var msg MessageRecordmsg.Name = "小王子"msg.Message = "Hello world!"msg.Age = 18c.XML(http.StatusOK, msg)})r.Run(":8080")
}

YMAL渲染

r.GET("/someYAML", func(c *gin.Context) {c.YAML(http.StatusOK, gin.H{"message": "ok", "status": http.StatusOK})
})

protobuf渲染

r.GET("/someProtoBuf", func(c *gin.Context) {reps := []int64{int64(1), int64(2)}label := "test"// protobuf 的具体定义写在 testdata/protoexample 文件中。data := &protoexample.Test{Label: &label,Reps:  reps,}// 请注意,数据在响应中变为二进制数据// 将输出被 protoexample.Test protobuf 序列化了的数据c.ProtoBuf(http.StatusOK, data)
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shell指令及笔试题

一&#xff1a;linux基本指令考察 创建文件&#xff0c;直接在本目录的上级目录下创建一个名为dir1的文件夹&#xff0c;并在dir1文件夹下创建一个名为file1的文件 答&#xff1a;本目录的上级目录下创建一个名为dir1的文件:mkdir ../dir1 在dir1文件夹下创建一个名为file1的…

【SQL】百题计划:SQL内置函数“LENGTH“的使用

【SQL】百题计划-20240912 方法一&#xff1a; Select tweet_id from Tweets where LENGTH(content) > 15;– 方法二&#xff1a; Select tweet_id from Tweets where CHAR_LENGTH(content)> 15;

初始c++:入门基础(完结)

打字不易&#xff0c;留个赞再走吧~~~ 目录 一函数重载二引用1 引⽤的概念和定义2引⽤的特性3引⽤的使⽤三inline四nullptr 一函数重载 C⽀持在同⼀作⽤域中出现同名函数&#xff0c;但是要求这些同名函数的形参不同&#xff0c;可以是参数个数不同或者 类型不同。这样C函数调⽤…

HTB-Blue(永恒之蓝漏洞复现)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天给大家讲解Blue靶机 渗透过程 信息搜集 服务器开放了smb服务&#xff0c;漏洞探测显示 具有ms17_010(永恒之蓝漏洞) 利用永恒之蓝 搜索永恒之蓝漏洞 use使用永恒之蓝漏洞 rhost //对方主机 lhost //回连主机 …

一种简单的过某宝验证码的方式(仅做学习使用)

开篇 今天介绍一种简单的过某宝验证码的方式&#xff0c;用的是自动化&#xff0c;这样对不会js逆向的小白非常友好&#xff0c;只需要用到selenium框架就能轻松过某宝验证码&#xff0c;即模拟人的操作对滑块进行滑动。 但是首先还是需要训练验证码和标题 训练前&#xff1a…

心觉:成功学就像一把刀,有什么作用关键在于使用者(二)

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作174/1000天 上一篇文章讲了成功学到底是个啥 是如何起作用的 为什么有些人觉得没有用&#xff1f; 今天我们再展开来剖析一下这…

openssl 生成多域名 多IP 的数字证书

openssl.cnf 文件内容&#xff1a; [req] default_bits 2048 distinguished_name req_distinguished_name copy_extensions copy req_extensions req_ext x509_extensions v3_req prompt no [req_distinguished_name] countryName CN stateOrProvinceName GuangDong l…

Electron 安装包 asar 解压定位问题实战

背景 在开发 Electron 过程中&#xff0c;我们想知道 Electron 打包的最终形态是什么样的&#xff0c;以便我们能更好的理解 Electron 打包的过程&#xff0c;以及逆向来快速追踪一些问题&#xff0c;例如下面这个报错&#xff0c;以前这类报错都是靠猜&#xff0c;现在则可以…

使用 VSCode 在 Python 中创建项目环境

了解如何管理 Python 项目的不同环境&#xff0c;欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 介绍 创建数据科学项目非常简单。如今&#xff0c;有了众多资源&#xff0c;您只需选择开发工具并启动项目即可。 除了多个人工智能机…

JDBC 编程

目录 JDBC 是什么 JDBC 的工作原理 JDBC 的使用 引入驱动 使用 常用接口和类 Connection Statement ResultSet 使用总结 JDBC 是什么 JDBC&#xff08;Java Database Connectivity&#xff09;&#xff1a;Java数据库连接&#xff0c;是一种用于执行 SQL 语句的Java…

git学习【持续更新中。。。】

git学习【持续更新中。。。】 文章目录 git学习【持续更新中。。。】一、Git基本操作1.创建本地仓库2.配置本地仓库1.局部配置2.全局配置 3.认识工作区、暂存区、版本库4.添加文件5.修改文件6.版本回退7.撤销修改8.删除文件 二、Git分支管理1.理解分支2.创建、切换、合并分支3.…

AI 时代,大模型产业落地的八大思考

引言 在人工智能领域&#xff0c;大模型技术正逐渐成为推动行业进步的关键力量。随着技术的发展&#xff0c;大模型不仅在学术界引起了广泛的关注&#xff0c;也在产业界展现出巨大的应用潜力。然而&#xff0c;如何将这些强大的模型有效地应用到实际产业中&#xff0c;仍然是…

解决:Vue 中 debugger 不生效

目录 1&#xff0c;问题2&#xff0c;解决2.1&#xff0c;修改 webpack 配置2.2&#xff0c;修改浏览器设置 1&#xff0c;问题 在 Vue 项目中&#xff0c;可以使用 debugger 在浏览器中开启调试。但有时却不生效。 2&#xff0c;解决 2.1&#xff0c;修改 webpack 配置 通…

MySQL权限控制(DCL)

我的mysql里面的一些数据库和一些表 基本语法 1.查询权限 show grants for 用户名主机名;例子1&#xff1a;查询权限 show grants for heima%;2.授予权限 grant 权限列表 on 数据库名.表名 to 用户名主机名;例子2&#xff1a; 授予权限 grant all on itcast.* to heima%;…

Android Studio Menu制作

文章目录 一、创建菜单在Activity上新建onCreateOptionsMenu新建menu目录及资源文件新建Menu一级菜单在Activity上加载Menu测试效果 二、菜单点击事件 一、创建菜单 在Activity上新建onCreateOptionsMenu Overridepublic boolean onCreateOptionsMenu(Menu menu) {return supe…

Pytest配置文件pytest.ini如何编写生成日志文件?

1、新建pytest.ini文件 [pytest] log_clitrue log_leveLNOTSET log_format %(asctime)s %(levelname)s %(message)s %(filename)s %(funcName)s %(lineno)d log_date_format %Y-%m-%d %H:%M:%Slog_file ./logdata/log.log log_file_level info log_file_format %(asctime…

深入探究HTTP网络协议栈:互联网通信的基石

在我们日常使用互联网的过程中&#xff0c;HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;扮演着至关重要的角色。无论是浏览网页、下载文件&#xff0c;还是进行在线购物&#xff0c;HTTP协议都在背后默默地支持着这些操作。今天&#x…

数据结构与算法——顺序表期末复习五大经典题型

目录 一&#xff1a;顺序表-移除元素 二&#xff1a;顺序表-删除有序数组中的重复项 三&#xff1a;顺序表-合并两个有序数组 四&#xff1a;顺序表-旋转数组 五&#xff1a;顺序表-数组形式的整数加法 一&#xff1a;顺序表-移除元素 题型链接&#xff1a;27. 移除元素 -…

玖逸云黑系统源码 v1.3.0全解无后门 +搭建教程

功能带有卡密生成和添加黑名单等&#xff0c;反正功能也不是很多具体的自己看程序截图即可。 搭建教程 完成 1.我们先添加一个站点 2.PHP选择7.3 3.上传源码解压 4.导入数据库 5.配置数据库信息config.php 源码下载&#xff1a;https://download.csdn.net/download/m0_6…

10年408考研真题-数据结构

23.[2010统考真题]若元素 a,b,c,d,e,f 依次进栈&#xff0c;允许进栈、退栈操作交替进行&#xff0c;但不允许连续3次进行退栈操作&#xff0c;不可能得到的出栈序列是(D)。 A.dcebfa B.cbdaef C.bcaefd D.afedcb 解析&#xff1a;直接看D选项&#xff0c…