【Gin】模板的高级用法

简介: 这样我们只需要在模板文件不需要转义的内容后面使用我们定义好的safe函数就可以了。{{ . | safe }}


1.自定义函数


Go的模板支持自定义函数


func tmpFuc(w http.ResponseWriter, r *http.Request) {
  // 自定义一个函数kua,第二个返回值必须是error类型
  kua := func(name string) (string, error) {
    return name + "very nice!", nil
  }
  // 解析模板
  // 当前路径下的tmpl
  // 创建一个模板对象
  t := template.New("tem.tmpl")
  // 告诉模板引擎,现在多了一个自定义函数kua
  t.Funcs(template.FuncMap{
    "kua": kua,
  })
  // 进行解析
  _, err := t.ParseFiles("./tem.tmpl")
  if err != nil {
    fmt.Println("ParseFiles failed error:%v", err)
    return
  }
  // 渲染模板
  name := "dahe"
  err = t.Execute(w, name)
  if err != nil {
    fmt.Println("tmpl Execute failed err=%v", err)
  }
}


模板使用自定义函数:


{{kua .}}
-------------------------------
输出:dahevery nice!


2.嵌套模板


我们可以在template中嵌套其他的template。这个template可以是单独的文件,也可以是通过define定义的template。


func tmpFuc(w http.ResponseWriter, r *http.Request) {
  // 解析模板,主模板在前,包含模板在后
  t, err := template.ParseFiles("./tem.tmpl", "./ul.tmpl")
  if err != nil {
    fmt.Println("parse template failed , err=%v", err)
    return
  }
  name := "dahe"
  // 渲染模板
  t.Execute(w, name)
}


主模板:


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>hint</title>
</head>
<body>
{{template "ol.tmpl"}}
{{template "ul.tmpl"}}
<p>你好啊,{{.}}</p>
{{/* 通过define自定义一个模板 */}}
{{define "ol.tmpl"}}
    <ol>
        <li>java</li>
        <li>c++</li>
        <li>go</li>
    </ol>
{{end}}
</body>
</html>


外部嵌套的ul.tmpl:


<ul>
    <li>注释</li>
    <li>日志</li>
    <li>测试</li>
</ul>


浏览器输出如下:



3.block


block是定义模板{{define "name"}} T1 {{end}}和执行{{template "name" pipeline}}缩写,典型的用法是定义一组根模板,然后通过在其中重新定义块模板进行自定义。

模板页面:


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>block</title>
</head>
<body>
<h1>欢迎来到迷你抖音哦</h1>
<p>{{block "content" .}}{{end}}</p>
</body>
</html>


继承A:


{{/*继承根模板*/}}
{{template "base.tmpl" .}}
{{/*重新定义块模板*/}}
{{define "content"}}
    <p>这是home页面</p>
    <p>{{.}}</p>
{{end}}


继承B:


{{/*继承根模板*/}}
{{template "base.tmpl" .}}
{{/*重新定义块模板*/}}
{{define "content"}}
    <p>这是index页面</p>
    <p>{{.}}</p>
{{end}}


浏览器输出:




4.修改默认的标识符


Go标准库的模板引擎使用的花括号{{和}}作为标识,而许多前端框架(如Vue和 AngularJS)也使用{{和}}作为标识符,所以当我们同时使用Go语言模板引擎和以上前端框架时就会出现冲突,这个时候我们需要修改标识符,修改前端的或者修改Go语言的。这里演示如何修改Go语言模板引擎默认的标识符:


template.New("test").Delims("{[", "]}").ParseFiles("./t.tmpl")


例子:后端


func index(w http.ResponseWriter, r *http.Request) {
  t, err := template.New("./templates/hint.tmpl").
    Delims("{[", "]}").
    ParseFiles("./templates/hint.tmpl")
  if err != nil {
    fmt.Println("parse template failed , err = %v", err)
    return
  }
  msg := "imustctf"
  t.ExecuteTemplate(w, "hint.tmpl", msg)
}


模板文件:


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>修改模板的默认标识符</title>
</head>
<body>
<h1>欢迎来到迷你抖音哦</h1>
<p>{[.]}</p>
</body>
</html>



5.text/template与html/tempalte的区别


html/template针对的是需要返回HTML内容的场景,在模板渲染过程中会对一些有风险的内容进行转义,以此来防范跨站脚本攻击。

传入一段JS代码并使用html/template去渲染该文件,会在页面上显示出转义后的JS内容。不会出现弹窗, <script>alert('嘿嘿嘿')</script>。 这就是html/template为我们做的事。

但是在某些场景下,我们如果相信用户输入的内容,不想转义的话,可以自行编写一个safe函数,手动返回一个template.HTML类型的内容。示例如下:


func xss(w http.ResponseWriter, r *http.Request){
  tmpl,err := template.New("xss.tmpl").Funcs(template.FuncMap{
    "safe": func(s string)template.HTML {
      return template.HTML(s)
    },
  }).ParseFiles("./xss.tmpl")
  if err != nil {
    fmt.Println("create template failed, err:", err)
    return
  }
  jsStr := `<script>alert('嘿嘿嘿')</script>`
  err = tmpl.Execute(w, jsStr)
  if err != nil {
    fmt.Println(err)
  }
}


这样我们只需要在模板文件不需要转义的内容后面使用我们定义好的safe函数就可以了。


{{ . | safe }}
目录
相关文章
|
中间件 Go 数据库
Go开发者必读:Gin框架的实战技巧与最佳实践
在当今快速发展的互联网时代,Web开发的需求日益增长。Go语言以其简洁、高效、并发性强的特点,成为了开发者们的首选。而在Go语言的众多Web框架中,Gin无疑是其中的佼佼者。本文将深入探讨Gin框架的特性、优势以及如何利用Gin构建高性能的Web应用。
|
存储 关系型数据库 MySQL
Mysql - 如何决定用 datetime、timestamp、int 哪种类型存储时间戳?
Mysql - 如何决定用 datetime、timestamp、int 哪种类型存储时间戳?
3158 0
|
NoSQL 数据可视化 关系型数据库
推荐几个好用的redis可视化工具
推荐几个好用的redis可视化工具
16274 1
|
存储 缓存 Oracle
|
10月前
|
缓存 监控 前端开发
优化 Flutter 应用启动速度的策略,涵盖理解启动过程、资源加载优化、减少初始化工作、界面布局优化、异步初始化、预加载关键数据、性能监控与分析等方面
本文探讨了优化 Flutter 应用启动速度的策略,涵盖理解启动过程、资源加载优化、减少初始化工作、界面布局优化、异步初始化、预加载关键数据、性能监控与分析等方面,并通过案例分析展示了具体措施和效果,强调了持续优化的重要性及未来优化方向。
410 10
|
12月前
|
JavaScript 前端开发 数据安全/隐私保护
混淆指定js文件
【9月更文挑战第26天】JavaScript 混淆旨在保护代码知识产权、减小文件体积和提高安全性。方法包括变量名和函数名混淆、代码压缩、控制流平坦化及字符串加密。常用工具如 UglifyJS 和 JScrambler 可实现这些功能。然而,混淆可能带来兼容性和调试困难等问题,需谨慎使用并确保法律合规。
181 5
|
NoSQL Redis
蓝易云 - redis报错WRONGTYPE Operation against a key holding the wrong kind of value
解决这个问题的方法是检查你的代码,确保你对每个键使用的命令与该键的类型匹配。你可以使用 `TYPE`命令来确定一个键的类型。例如,`TYPE mykey`将返回 `mykey`的类型。
432 3
|
存储 缓存 NoSQL
Gin 应用多实例部署session问题、session参数与刷新
【8月更文挑战第7天】在Gin应用多实例部署中,传统基于内存的Session存储会导致数据不一致或丢失。需采用如数据库或Redis存储、及Session同步机制确保一致性。示例代码展示了使用Redis存储Session的过程。合理选择方案对保证系统稳定和用户体验至关重要。
163 0
|
人工智能 自然语言处理
还在因AI检测头疼?尝试一下 AI Humanize
AI Humanize是一款将AI文本转化为人性化、难以检测的高质量内容的工具。它提供基础和高级模型,支持多语言,如英语、中文等,并能在多种AI检测器中通过。训练于大量人类语料库,AI Humanize的&quot;Humanize AI LLM&quot;模型确保生成自然、流畅的文本,增强可读性和原创性,同时保持用户友好界面。适用于各领域的用户提升内容质量。[AI Humanize](https://aihumanize.io/)**
还在因AI检测头疼?尝试一下 AI Humanize
|
SQL 开发框架 安全
【Gin】初识Gin框架,模板基本语法
1.Gin介绍 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧
796 1
【Gin】初识Gin框架,模板基本语法