本文缺少图片资源,完整文章在github仓库
来源
www.liwenzhou.com/posts/Go/go…
介绍
html/template
包完成了数据驱动的模板,用于生成可防止代码注入的安全的HTML内容。它提供了github和text/template
包相同的接口,Go言语中输出HTML的场景都应运用html/template
这个包。
模板与GitHub烘托数组c语言
在一些前后端不别离的Web架构中,咱们一般需求在后端将一些数据数组去重烘托到HTML文档中,从安全模式而完成动态的网页(网页的布局和款式大致一github直播渠道永久回家样,但展示的内容github敞数组指针开私库并不相同数组和链表的区别)效果。
咱们这儿说的模板可以理解数组去重为事前界说好的HTML文档文件Git,模板烘托的效果机制可以简略理解为github文本替换操作–运用相应的数据去替测验仪换HTML文档中测试仪事前准备好的符号数组词。
许多编程言语的Web结构中都运数组用各种模板引擎,比方Python言语中Flask结构中运用的jinja2模板引擎。
Go言语的模板引擎
Go言语内置了文本模板引擎text/template
和用于HTML文档的html/tempgithub永久回家地址la数组c语言te
。它们的效果机制可以简略归纳如下:
- 模板文件一般界说为
.tmpl
和GitHub.tpl
为后缀(也可以运用其他的后缀),有必要运用UTF8
编码。 - 模板文件中安全教育平台登录运用数组初始化
{{
和}}
包裹和标giti识需求传入的数据。 - 传给模板这样的数据就可以经过点号(
.
)来访问,假如数据是杂乱类型的数据,可以经过{ { .FieldName }}来访问它的字段。测试英文 - 除
{{
和}}
包裹的内容外,其他内容均不做修正原样输出。
模板引擎的运用
Go言语模板引擎的运用可以分为三部分:界说模板文件、解析模板文件和数组指针模板烘托.
界说安全工程师模板文测试英文件
其间,界说模板文件时需求咱们giti依照安全期计算器相关语法规则去编写,后文会详细介绍。
解析模板文件
上面界说好了模板文件之后,可以运用下面的常用办法去解析模板文件,得到模板目标:
func (t *Template) Parse(src string) (*Template, error)
func ParseFiles(filenames ...string) (*Template, error)
func ParseGlob(pattern string) (*Template, error)
当然,你也可以运用func N测验ew(name string) *Template
函数创立一个名为name
的模板,然后对其调用上面的办法去解析模板字符串或模板文件。
模板烘托
烘托模板简略来说便是运用数据去填充模板,当然实测试抑郁症的20道题际上或测试抑郁症的20道题许会杂乱许多。
func (t *Template) Execute(wr io.Writer, data interface{}) error
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error
根本示例
界说模板文件
咱们依照Go模板语法界说一安全个hello.tmpl
的模板文件,内容如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>hello</title>
</head>
<body>
<h1> hello golang</h1>
<h1>hello {{.}}</h1>
</body>
</html>
解析和烘托模板文件
然后咱们创立一个main.go
文件,在其间写下HTTP server端代码如下:
package main
import (
"fmt"
"html/template"
"net/http"
"os"
)
func sayHello(w http.ResponseWriter, r *http.Request) {
// 获取项目的绝对路径
wd, err := os.Getwd()
if err != nil {
fmt.Printf("get wd failed, err:%v n", wd)
return
}
fmt.Println("wd:", wd + "\lesson04\hello.tmpl")
// 解析指定文件生成模板目标
tmpl, err := template.ParseFiles( wd + "\lesson04\hello.tmpl")
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
// 运用给定数据烘托模板,并将成果写入w
tmpl.Execute(w, "沙河小王子")
}
func main() {
http.HandleFunc("/", sayHello)
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Println("HTTP server failed,err:", err)
return
}
}
将上面的main.go
文件编译履行,然后运用浏览器访问http://127.0.0.1:9090
就能看到页面上测试抑郁症的20道题显示了“Hello 沙河小王子”安全工程师。 这便是一个最简略的模板烘托的示例,Go言语模板引擎详细用法请往下阅读。+
得到运转成果
模板语法
{{.}}
模数组指针板语法都包含在{{
和}}
中间,其间{github下载{.}}
中的点表明当前测试仪对github中文官网网gitee页象。
当咱们传入一个结构github直播平台永久回家体目标时,咱们github可以依据.
来访问git教程结构体的对应字段。例数组初始化如:
package main
import (
"fmt"
"html/template"
"net/http"
"os"
)
//界说用户结构体
type User struct {
Name string
Gender string
Age int
}
func sayHello(w http.ResponseWriter, r *http.Request) {
// 获取项目的绝对路径
wd, err := os.Getwd()
if err != nil {
fmt.Printf("get wd failed, err:%v n", wd)
return
}
fmt.Println("wd:", wd + "\lesson05\hello.tmpl")
// 解析指定文件生成模板目标
tmpl, err := template.ParseFiles( wd + "\lesson05\hello.tmpl")
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
u1 := User{
Name: "小王子",
Gender: "男",
Age: 10,
}
// 运用给定数据烘托模板,并将成果写入w
tmpl.Execute(w, u1)
}
func main() {
http.HandleFunc("/", sayHello)
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Println("HTTP server failed,err:", err)
return
}
}
模板文件hello.tmpl
内容测验抑郁症如下:
<!DOCTYPE html>
<html lang="zh-CN">
<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>Hello</title>
</head>
<body>
<h1>名字: {{.Name}}</h1>
<h1>性别: {{.Gender}}</h1>
<h1>年龄: {{.Age}}</h1>
</body>
</html>
在浏览器输入安全教育平台登录入口如下网址
http://localhost:9090/sayHello
可以测验仪烘托出咱们结构体中的值
同理,当咱们传入的变量是map时,也可以在模板文件中经过.
依据key来取值。
// 选用一个map
m1 := map[string]interface{}{
"Name": "小王子",
"Age": 18,
"Gender": "男",
}
// 运用给定数据烘托模板,并将成果写入w
tmpl.Execute(w, m1)
假如咱们想把map 和数组去重 结构体都传递到前端,那么就需求在界说一个大的map来进行存储
// 选用结构体
u1 := User{
Name: "小王子",
Gender: "男",
Age: 10,
}
// 选用一个map
m1 := map[string]interface{}{
"Name": "小王子",
"Age": 18,
"Gender": "男",
}
m2 := map[string]interface{}{
"map": m1,
"user": u1,
}
注释
{{/* a comment */}}
注释,履行时会忽略。可以多行。注释不能嵌套,并且有必要紧贴分界符始止。
pipeli测验抑郁症ne
pip安全教育平台登录eline
是指产生数据的操作。比方{{.}}
、安全教育日{{.Name}}
等。Go的模板语法中支撑运用管道符号安全出产git教程法|
链接多个指令,用法和unix下的管道相似:|
前面的指令会将运算成果(或回来值)传递给后一个指令的最终一gitee个位置。测试仪
**留意:**并不是只要运用了|
才是pipeli测验抑github中文官网网页郁症ne。Go的模板语法中,github汤姆pipeline的
概念是传递数据,只要能产生数据的,都是pgit指令ipelin数组去重办法e
。
变量
咱们还安全期计算器可以在模板中声明变量,用来数组保存传入模板的数据或其他语句生成的成果。详细语法如下:
$obj := {{.}}
其间$obj
是变量的名字,gitee在后续的代码中就可以运用该变量了。
移除空格
有时分咱们在运用模板语法的时分会不可避免的引进一下空格或许换行符github汤姆,这样模板终究烘托出来的内容或许就和咱们想的不相同,这个时分可以运giticomfort是什么轮胎用{{-
语github下载法去除测试工程师模板内容左侧的一切空数组去重方法白符号,github官网数组的定义登陆入口 运用-}}
去githugithub汤姆b中文官网网页除模板内容右侧的一切空白符号。
例github中文社区如数组去重:
{{- .Name -}}
留意:-
要紧挨{{
和}}
,同时与模板值之间需求运用空格分隔。
条件判别
Go模板语法中的条件判别有以下几种:
{{if pipeline}} T1 {{end}}
{{if pipeline}} T1 {{else}} T0 {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
range
Go的模板语法中运用range
关键字进行遍历,有以下两种写法,其间pipeline
的值有必要是数组、切片、字典或许通道。
{{range pipeline}} T1 {{end}}
假如pipeline的值其长度为0,不会有任何输出
{{range pipeline}} T1 {{else}} T0 {{end}}
假如pipeline的值其长度为0,则会履行T0。
with
{{with pipeline}} T1 {{end}}
假如pipeline为empty不产生输出,不然将dot设为pipeline的值并履行T1。不修正外面的dot。
{{with pipeline}} T1 {{else}} T0 {{end}}
假如pipeline为empty,不改动dot并履行T0,不然dot设为pipeline的值并履行T1。
预界说函数
履行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字安全教育日典。一般不在模板内界说函数,而github是什么是运用Funcs办法增加函数到模板里。
预界说的全局函数如下:
and
函数回来它的第一个empty参数或许最终一个参数;
便是说"and x y"等价于"if x then y else x";一切参数都会履行;
or
回来第一个非empty参数或许最终一个参数;
亦即"or x y"等价于"if x then x else y";一切参数都会履行;
not
回来它的单个参数的布尔值的否定
len
回来它的参数的整数类型长度
index
履行成果为第一个参数以剩余的参数为索引/键指向的值;
如"index x 1 2 3"回来x[1][2][3]的值;每个被索引的主体有必要是数组、切片或许字典。
print
即fmt.Sprint
printf
即fmt.Sprintf
println
即fmt.Sprintln
html
回来与其参数的文本表明方法等效的转义HTML。
这个函数在html/template中不可用。
urlquery
以适合嵌入到网址查询中的方法回来其参数的文本表明的转义值。
这个函数在html/template中不可用。
js
回来与其参数的文本表明方法等效的转义JavaScript。
call
履行成果是调用第一个参数的回来值,该参数有必要是函数类型,其他参数作为调用该函数的参数;
如"call .X.Y 1 2"等价于go言语里的dot.X.Y(1, 2);
其间Y是函数类型的字段或许字典的值,或许其他相似状况;
call的第一个参数的履行成果有必要是函数类型的值(和预界说函数如print明显不同);
该函数类型值有必要有1到2个回来值,假如有2个则后一个有必要是error接口类型;
假如有2个回来值的办法回来的error非nil,模板履行会中止并回来给调用模板履行者该错误;
比较函数
布尔函数会将任何类型的零值视为假,其他视为真。
下面是界说为函数的二元比较运算的调集测验英文:
eq 假如arg1 == arg2则回来真
ne 假如arg1 != arg2则回来真
lt 假如arg1 < arg2则回来真
le 假如arg1 <= arg2则回来真
gt 假如arg1 > arg2则回来真
ge 假如arg1 >= arg2则回来真
为了简化多参数相数组指针等检测,eq(只要eq)可以接受2个或更多个参测试抑郁症数,它会将第一个参数和其他参数顺次比较,回来下式的成果:
{{eq arg1 arg2 arg3}}
比较函数只适用于根本类型(或重界说的根本类型,如测试抑郁症的20道题”type Celsius float3测试仪2”)。但是,整数和浮点数不能互相比较。
自界说函数
Go的模板支撑自界说函数。
package main
import (
"fmt"
"html/template"
"net/http"
"os"
)
/**
* @Description f1函数
* @Param
* @return
**/
func f1(w http.ResponseWriter, r *http.Request) {
// 界说模板
// 解析模板
// 获取项目的绝对路径
wd, err := os.Getwd()
if err != nil {
fmt.Printf("get wd failed, err:%v n", wd)
return
}
// 界说一个自界说函数
// 要么只要一个回来值,要么有两个回来值,第二个回来值有必要是error类型
kua := func(name string)(string, error) {
return name + "年轻又帅气!", nil
}
// 创立一个名字为f的模板目标。留意,这个名字一定要和模板的名字对应上
tmpl := template.New("hello.tmpl")
// 告诉模板引擎,我现在多了一个自界说的函数kua
tmpl.Funcs(template.FuncMap{
"kua": kua,
})
// 解析模板
_, err = tmpl.ParseFiles( wd + "\lesson06\hello.tmpl")
if err != nil {
fmt.Printf("parse template failed, err:%v n", err)
return
}
// 选用一个map
m1 := map[string]interface{}{
"Name": "小王子",
"Age": 18,
"Gender": "男",
}
// 烘托模板
tmpl.Execute(w, m1)
}
func main() {
http.HandleFunc("/hello", f1)
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Println("HTTP server failed,err:", err)
return
}
}
咱们可以在模giti板文件hello.tmpl
中依照如下方法运用咱们自界说的kua
函数了。
{{kua .Name}}
最终运转的成果
模板数组排序的嵌套te安全教育渠道作业登录mplate
咱们可以在template中嵌套其他的template。这个templategiti可测验手机是否被监控所以单独的文件,也可以是经过define
界说的template。
举个例子: t.tmpl
文件内容如下:
<!DOCTYPE html>
<html lang="zh-CN">
<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>tmpl test</title>
</head>
<body>
<h1>测验嵌套template语法</h1>
<hr>
{{template "ul.tmpl"}}
<hr>
{{template "ol.tmpl"}}
</body>
</html>
{{ define "ol.tmpl"}}
<ol>
<li>吃饭</li>
<li>睡觉</li>
<li>打豆豆</li>
</ol>
{{end}}
ul.tmpl
文件内Git容如下:
<ul>
<li>注释</li>
<li>日志</li>
<li>测验</li>
</ul>
咱们注册一个templDgitiemo
路由处理函数.
http.HandleFunc("/tmpl", tmplDemo)
t测数组初始化验测试用例mplDemo
函测验手机是否被监控数的详细内容如下:github官网
func tmplDemo(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseFiles("./t.tmpl", "./ul.tmpl")
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
user := UserInfo{
Name: "小王子",
Gender: "男",
Age: 18,
}
tmpl.Execute(w, user)
}
留意:在解析模板时,被嵌套的模板一定要安全工程师在gitee后面解析,例如上面的示例中t.tmpl
模板中嵌套了ul.tmpl
,所以ul.tmpl
要在t.tmpl
后进行安全教育平台登录入口解析。
block
{{block "name" pipeline}} T1 {{end}}
block
是界说模板{{defin测验手机是否被监控e "name"}} T1 {{end}}
和履行{{templatgi安全教育平台登录入口thub直播渠道永久回家e "name" pipeline}}
缩写,典型的用法是界说一组根模板,然后经过在安全教育日其间从头界说块模板进行自界说。
界说一个根模板temp测验仪lates/base.t测试mpl
,内容如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>Go Templates</title>
</head>
<body>
<div class="container-fluid">
{{block "content" . }}{{end}}
</div>
</body>
</html>
然后界说一个templates/index.tmpl
,”承继”base.tm数组的定义pl
:
{{template "base.tmpl"}}
{{define "content"}}
<div>Hello world!</div>
{{end}}
然后运用template.Pgiticomfort是什么轮胎aGitrseGlob
依照正GitHub则匹配规则解析模板文件,然后经过ExecuteTemplate
烘托指定的模板:
func index(w http.ResponseWriter, r *http.Request){
tmpl, err := template.ParseGlob("templates/*.tmpl")
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
err = tmpl.ExecuteTemplate(w, "index.tmpl", nil)
if err != nil {
fmt.Println("render template failed, err:", err)
return
}
}
假如咱们的模板名称抵触了,例如不同事务线下都界说了一个index.tmpl
模板测试工程师,咱们可以经过下面两种办法来处理。
- 在模板文件开头数组公式运用
{{dgithub下载efine 模板名}}
语句显式的为模g安全教育日iti板命名。 - 可以把模板文件存放在
templates
文件夹下面的不同目录中,然后运用安全出产法template.ParseGlob("temgithu安全工程师b敞开私库plates/**/*.tmp数组的定义l"测验工程师)
解析模板。
修正默许的标识符
Go标准库的模板引擎运用的花括号{{
和}}
作为标识,而许多前端结构(如数组排序Vue
和 AngularJS
)也运用{{
和}}
作为标识符,所以当咱们同时运用Go言语模板引擎和测试工程师以上前端结构时就测验手机是否被监控会出现抵触,这个时分咱们需求修正标识符,修正前端的或许修正Go言语的。这儿演示怎么修正Go言语模板引擎默许的标识符:
template.New("test").Delims("{[", "]}").ParseFiles("./t.tmpl")
最终咱们在烘托的时分
<!DOCTYPE html>
<html lang="zh-CN">
<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>自界说模板函数</title>
</head>
<body>
<h1>名字: {[.Name]}</h1>
<h1>性别: {[.Gender]}</h1>
<h1>年龄: {[.Age]}</h1>
</body>
</html>
最终运转成果,发github中文社区现数组排序也可以正常显示
text/tempgithub汤姆late与html/tegithub中文官网网页mpalte的差异
ht数组c言语ml/template
针对的是需求回来HTML内github汤姆容的场景,在模板烘托过程中会对一些有风险的内容进行转义,以此来防范跨站脚本进犯。
例如,我界说下面的模板文件:
<!DOCTYPE html>
<html lang="zh-CN">
<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>Hello</title>
</head>
<body>
{{.}}
</body>
</html>
这个时分传入一段JSgithub下载代码并运用html/template
去烘托该文件,测试手机是否被监控会在页面上测验显示出转义后的JS内容。 alert('嘿嘿嘿')
这便是html/template
为咱们做的事。
但是在某些github中文官网网页场景下,咱们假如相安全教育日信用户输入的内容,不想转义的话,可以自行编写一个safe函数,手动回来一个template.HTML
类型的内gitlab容。示例如下:
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)
}
}
这数组排序样咱们只需求github是什么在模板文件不需求转义的内容后面运用咱们界说好的safe函数就可以了。github永久回家地址
{{ . | safe }}