Go标准库http/template

简介: Go标准库http/template

关于html/template

       html/template中实现了数据驱动的模板,与text/template具有相同的接口。前者用于输出THTML,或者用户text。通过关于html/template包可以有效防止代码注入,破坏HTML的内容。

模板与渲染有什么作用呢?

在前端和后端分离的Web项目中,我们经常要将后端的数据应用在前端的HTML页面中。那通过发送响应报文,然后前端去修改不就好了。设想每次都去修改的话,是不是特别的不方便。所以模板渲染的作用就显而易见了。比如,很多HTML页面的布局都差不多,但是需要展示的数据却不相同,这时候我们就可以通过模板的方式动态的更新HTML页面中的数据。(如何去调用这些数据,其实无非就是通过某种规定的语法去获取数据)

注:在大多数的web框架中都支持模板引擎

模板是什么呢?就是HTML文件而已

渲染时什么呢?就是用后台的数据(此时此刻我想在HTML页面中展示的数据)去替换HTML模板中的有模板语法规定的地方,从而将数据实时的显示在模板文件中。

Go模板引擎的相关规定

1.模板文件必须使用utf-8编码方式,文件后缀名最好使用 .tmpl 后者 .tpl (当然使用.html也可以)

2.模板文件中通过 {{}} 来表示需要获取的内容。(也可以自己定义)

3.通过 . 获取数据 .fieldName来获取结构体中的字段

GO模板引擎的使用

       GO模板引擎的使用分为三个步骤:定义模板、解析模板、渲染模板

定义模板:

       定义模板就是用一些规定的语法规则去写HTML文件

  • 语法规则

       1.语法规则(语句)都要写在{{XXX}}中【XXX为语法规则】

       2.{{.}} 中的 . 表示传过来的内容

       3.{{/* XXXX */}}中的 /*  */表示注释,可以多行,不能嵌套,必需紧跟着{{和}}

       4.GO模板中可以使用  | 来链接多个命令,前面的命令会将运算结果传递给后一个命令

       5. 变量,通过$来定义变量

       6.去掉前后空格{{- XXX  -}}   -必须紧贴  {{  和   }}

       7.条件判断

{{if 条件}}内容1{{end}}
{{if 条件}}内容1{{else}}内容2{{end}}
{{if 条件1}}内容1{{else if 条件2}}}内容2{{end}}
{{if 条件1}}内容1{{else if 条件2}}}内容2{{else}}内容3{{end}}

      8.range(遍历)   遍历的对象必须是数组、切片、字段典、通道

{{range pipeline}} 内容 {{end}}
{{range pipeline}} 内容1 {{else}} 内容2{{end}}

       9.with

{{with pipeline}} T1 {{end}}
{{with pipeline}} T1 {{else}}T2{{end}}

注:执行模板时,一般先从函数模板字典查找,然后再从全局函数字典中查找。不建议在模板内定义函数,而是将函数添加到模板函数中。    

 10.预定义全局函数(大概来了解下,需要用的时候再回来查)

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,模板执行会中断并返回给调用模板执行者该错误;

       11.比较函数(布尔函数)

               注1:布尔函数会将任何类型的零值视为false,非零值视为true

               注2:只有相同类型可以相互比较

eq      如果arg1 == arg2则返回真
ne      如果arg1 != arg2则返回真
lt      如果arg1 < arg2则返回真
le      如果arg1 <= arg2则返回真
gt      如果arg1 > arg2则返回真
ge      如果arg1 >= arg2则返回真

       12.自定义函数

       Go支持自定义模板函数,并且自定义函数一般不写在模板文件中(即不写在{{}}中)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>干饭小白</title>
    </head>
    <body>
        {{tmpFunc .}}
    </body>
</html>
package main
import (
  "fmt"
  "html/template"
  "io/ioutil"
  "net/http"
)
//测试:模板函数自定义函数
func MyHandler(w http.ResponseWriter, r *http.Request) {
  //读取模板文件中的内容
  temByte, err := ioutil.ReadFile("./index.tmpl")
  if err != nil {
    fmt.Println("read tmpl err=", err)
    return
  }
  //自定义一个模板函数   我们为了方便定义一个匿名函数
  tmpFunc := func(arg string) string {
    return arg + "love you"
  }
  //创建一个模板实例
  tem := template.New("index")
  //添加自定义函数  map[key]interface{}-->key方便在模板函数中找到函数入口
  tmp2 := tem.Funcs(template.FuncMap{"tmpFunc": tmpFunc})
  //解析模板(解析模板函数中的内容)
  tmp2, err = tmp2.Parse(string(temByte))
  if err != nil {
    fmt.Println("Parse err=", err)
    return
  }
  //执行模板
  tmp2.Execute(w, "chen")
}
func main() {
  http.HandleFunc("/", MyHandler)
  http.ListenAndServe(":9090", nil)
}

       13.嵌套template

               GO模板支持在一个模板文件中嵌套另一个模板文件

               支持直接在同一个文件中:

               {{define  "待嵌套文件名"}}

                       XXXXX

               {{end}}

package main
import (
  "fmt"
  "html/template"
  "net/http"
)
type User struct {
  Id       int
  Name     string
  Password string
}
func temHandler(w http.ResponseWriter, r *http.Request) {
  //定义模板
  //解析模板
  temp, err := template.ParseFiles("t1.tmpl", "t2.tmpl")
  if err != nil {
    fmt.Println("模板解析失败")
    return
  }
  //执行模板
  //搞个结构体吧
  u := &User{
    Id:   22,
    Name: "干饭小白",
  }
  temp.Execute(w, u)
}
func main() {
  http.HandleFunc("/temp", temHandler)
  http.ListenAndServe(":9090", nil)
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>干饭小白</title>
</head>
<body>
<h2>嵌套模板t2</h2>
<hr>
{{.Name}}
<!-- define嵌套  -->
<h3>define嵌套</h3>
{{template "t3.tmpl"}}
<hr>
<!-- 跨文件嵌套  -->
<h3>跨文件嵌套</h3>
{{template "t2.tmpl"}}
</body>
</html>
{{define "t3.tmpl"}}
<ol>
    <li>吃饭</li>
    <li>干饭</li>
    <li>睡觉</li>
</ol>
{{end}}
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>干饭小白</title>
</head>
<body>
   <P>
       我就喜欢干饭,哇哇哇哇
   </P>
</body>
</html>

14.block(用于买吧继承)

        定义一个根模板base.tmpl

package main
import (
  "fmt"
  "html/template"
  "net/http"
)
func blockHandle(w http.ResponseWriter, r *http.Request) {
  //定义模板
  //解析模板
  tem, err := template.ParseGlob(".//*.tmpl")
  if err != nil {
    fmt.Println("template.ParseFiles err=", err)
    return
  }
  //执行模板
  tem.ExecuteTemplate(w, "login.tmpl", "宠妻狂魔")
}
func main() {
  http.HandleFunc("/block", blockHandle)
  http.ListenAndServe(":9090", nil)
}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>干饭小白</title>
        <style>
            #dd{
                color: aqua;
            }
        </style>
    </head>
    <body>
    <h2>模板继承 父</h2>
    <div class="dd">
        {{block "con1" .}}{{end}}
    </div>
    </body>
</html>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>干饭小白</title>
</head>
<body>
<h2>模板继承 子</h2>
<hr>
<div>
    {{template "base.tmpl"}}
    <div>
        {{define "con1"}}
            HELLO
        {{end}}
    </div>
</div>
</body>
</html>

15.修改默认的标识符{{ }}

            在实际的项目开发中,有时候会用到其它的一些框架,这时候可能会与{{}}冲突。

            GO提供了让我们直接定义标识符。《在解析模板之前可以定义》

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

解析模板:

       方法1:直接使用默认的模板template

func (t *Template) Parse(src string) (*Template, error)
func ParseFiles(filenames ...string) (*Template, error)
func ParseGlob(pattern string) (*Template, error)

       方法2:创建自己的模板

               func New(name string) *Template

渲染模板:

       渲染模板就是用数据去填充模板的内容

func (t *Template) Execute(wr io.Writer, data interface{}) error
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error
相关文章
|
16天前
|
安全 Go
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第24天】Go语言标准库中的`text/template`包用于动态生成HTML和文本,但不熟悉其用法可能导致错误。本文探讨了三个常见问题:1) 忽视模板执行错误,应确保正确处理错误;2) 忽视模板安全,应使用`html/template`包防止XSS攻击;3) 模板结构不合理,应合理组织模板以提高可维护性。理解并运用这些最佳实践,能提升Go语言模板编程的效率和安全性,助力构建稳健的Web应用。
22 0
|
21天前
|
数据采集 存储 Go
使用Go语言和chromedp库下载Instagram图片:简易指南
Go语言爬虫示例使用chromedp库下载Instagram图片,关键步骤包括设置代理IP、创建带代理的浏览器上下文及执行任务,如导航至用户页面、截图并存储图片。代码中新增`analyzeAndStoreImage`函数对图片进行分析和分类后存储。注意Instagram的反爬策略可能需要代码适时调整。
使用Go语言和chromedp库下载Instagram图片:简易指南
|
12天前
|
运维 监控 Go
Golang深入浅出之-Go语言中的日志记录:log与logrus库
【4月更文挑战第27天】本文比较了Go语言中标准库`log`与第三方库`logrus`的日志功能。`log`简单但不支持日志级别配置和多样化格式,而`logrus`提供更丰富的功能,如日志级别控制、自定义格式和钩子。文章指出了使用`logrus`时可能遇到的问题,如全局logger滥用、日志级别设置不当和过度依赖字段,并给出了避免错误的建议,强调理解日志级别、合理利用结构化日志、模块化日志管理和定期审查日志配置的重要性。通过这些实践,开发者能提高应用监控和故障排查能力。
88 1
|
12天前
|
安全 Go
Golang深入浅出之-Go语言标准库中的文件读写:io/ioutil包
【4月更文挑战第27天】Go语言的`io/ioutil`包提供简单文件读写,适合小文件操作。本文聚焦`ReadFile`和`WriteFile`函数,讨论错误处理、文件权限、大文件处理和编码问题。避免错误的关键在于检查错误、设置合适权限、采用流式读写及处理编码。遵循这些最佳实践能提升代码稳定性。
21 0
|
13天前
|
安全 Go 网络安全
【Go语言专栏】Go语言中的HTTPS与TLS配置
【4月更文挑战第30天】本文介绍了在Go语言中配置HTTPS服务器和处理TLS证书的方法。首先,TLS证书由证书颁发机构(CA)颁发,用于验证服务器身份和加密通信。接着,展示了如何使用`crypto/tls`包加载自签名证书启动HTTPS服务器。在生产环境中,通常使用CA签名的证书,这需要获取证书链和私钥。为了自动续期证书,可以利用Go的`acme/autocert`包与ACME服务交互。掌握这些技能对于确保Web服务的安全至关重要。
|
13天前
|
中间件 Go
【Go语言专栏】使用Go语言编写HTTP服务器
【4月更文挑战第30天】本文介绍了如何使用Go语言创建基本的HTTP服务器,包括设置路由、处理请求和响应。首先确保安装了Go环境,然后引入`net/http`包,定义路由和处理器函数。处理器函数接收`http.ResponseWriter`和`*http.Request`参数,用于发送响应和处理请求。使用`http.ListenAndServe`启动服务器,并可通过中间件增强功能。文章还提及了处理复杂请求、查询参数和POST数据的方法,以及使用第三方库如Gin和Echo扩展功能。通过本文,读者可掌握Go语言编写HTTP服务器的基础知识。
|
13天前
|
安全 Go 开发者
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第25天】Go语言的`text/template`和`html/template`库提供动态HTML生成。本文介绍了模板基础,如基本语法和数据绑定,以及常见问题和易错点,如忘记转义、未初始化变量、复杂逻辑处理和错误处理。建议使用`html/template`防止XSS攻击,初始化数据结构,分离业务逻辑,并严谨处理错误。示例展示了条件判断和循环结构。通过遵循最佳实践,开发者能更安全、高效地生成HTML。
22 0
|
15天前
|
中间件 Go API
Golang深入浅出之-Go语言标准库net/http:构建Web服务器
【4月更文挑战第25天】Go语言的`net/http`包是构建高性能Web服务器的核心,提供创建服务器和发起请求的功能。本文讨论了使用中的常见问题和解决方案,包括:使用第三方路由库改进路由设计、引入中间件处理通用逻辑、设置合适的超时和连接管理以防止资源泄露。通过基础服务器和中间件的代码示例,展示了如何有效运用`net/http`包。掌握这些最佳实践,有助于开发出高效、易维护的Web服务。
28 1
|
1月前
|
Go
go语言的http post推送
go语言的http post推送
11 1
|
2月前
|
存储 JSON Go
ElasticSearch的HTTP操作 和Go客户端
【2月更文挑战第13天】ElasticSearch的HTTP操作 和Go客户端操作
44 0