【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 }}
目录
相关文章
|
XML JSON 数据格式
Gin 学习之绑定参数
Gin 学习之绑定参数
128 0
|
1月前
|
存储 大数据 Python
案例学Python:filter()函数的用法,高级!
`filter()`函数是Python中处理序列数据的强大工具,它允许我们高效地根据条件过滤元素。通过结合匿名函数、常规函数或直接利用Python的内置逻辑,`filter()`提供了灵活且高效的过滤机制,尤其在大数据处理和内存敏感的应用中展现出其价值。掌握 `filter()`的使用,不仅能提升代码的可读性和效率,还能更好地适应Python的函数式编程风格。
33 2
|
5月前
|
JSON 中间件 API
Gin框架笔记(一) Gin框架的安装与Hello World
Gin框架笔记(一) Gin框架的安装与Hello World
184 0
|
6月前
|
编译器 C++
【C++】模板进阶 -- 详解
【C++】模板进阶 -- 详解
|
6月前
|
机器学习/深度学习 存储 算法
C++ 模版函数介绍:介绍模版函数的基本概念、用法和作用
C++ 模版函数介绍:介绍模版函数的基本概念、用法和作用
65 1
2023-4-11-chrono库用法学习
2023-4-11-chrono库用法学习
71 0
|
6月前
|
SQL 开发框架 .NET
你知道Golang的模板怎么用吗?带你了解动态文本的生成!
你知道Golang的模板怎么用吗?带你了解动态文本的生成!
|
6月前
|
移动开发 JavaScript 小程序
【uniapp 小程序开发语法篇】资源引入 | 语法介绍 | UTS 语法支持(链接格式)
【uniapp 小程序开发语法篇】资源引入 | 语法介绍 | UTS 语法支持(链接格式)
350 0
|
缓存 编译器 C++
C++高级语法
● C++使用class定义一个类,使用struct定义一个结构体 struct的默认成员权限是public,class的默认成员权限是private,除此之外二者基本没有差别。
86 0
|
SQL 开发框架 安全
【Gin】初识Gin框架,模板基本语法
1.Gin介绍 Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧
589 1
【Gin】初识Gin框架,模板基本语法

相关实验场景

更多
下一篇
无影云桌面