首页 > 其他分享 >标准库之template

标准库之template

时间:2024-03-14 16:45:21浏览次数:14  
标签:pipeline 函数 err 标准 html template 模板

目录

Template

  • html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出。它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用text/template包。
  • 功能同python的Django框架的模板语言类似

1. 模板

  • 在基于MVC的Web架构中,我们通常需要在后端渲染一些数据到HTML文件中,从而实现动态的网页效果。

1. 模板示例

  • 通过将模板应用于一个数据结构(即该数据结构作为模板的参数)来执行,来获得输出。模板中的注释引用数据接口的元素(一般如结构体的字段或者字典的键)来控制执行过程和获取需要呈现的值。模板执行时会遍历结构并将指针表示为’.‘(称之为”dot”)指向运行过程中数据结构的当前位置的值。

  • 用作模板的输入文本必须是utf-8编码的文本。”Action”—数据运算和控制单位—由”“界定;在Action之外的所有文本都不做修改的拷贝到输出中。Action内部不能有换行,但注释可以有换行。

  • HTML文件代码如下:

<!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>Hello</title>
</head>
<body>
    <p>Hello {{.}}</p>
</body>
</html>

我们的HTTP server端代码如下:

// main.go

func sayHello(w http.ResponseWriter, r *http.Request) {
    // 解析指定文件生成模板对象
    tmpl, err := template.ParseFiles("./hello.html")
    if err != nil {
        fmt.Println("create template failed, err:", err)
        return
    }
    // 利用给定数据渲染模板,并将结果写入w
    tmpl.Execute(w, "5lmh.com")
}
func main() {
    http.HandleFunc("/", sayHello)
    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        fmt.Println("HTTP server failed,err:", err)
        return
    }
}

2. 模板语法

(1){{.}}

  • 模板语法都包含在{{和}}中间,其中{{.}}中的点表示当前对象。

  • 当我们传入一个结构体对象时,我们可以根据.来访问结构体的对应字段。例如:

// main.go

type UserInfo struct {
    Name   string
    Gender string
    Age    int
}

func sayHello(w http.ResponseWriter, r *http.Request) {
    // 解析指定文件生成模板对象
    tmpl, err := template.ParseFiles("./hello.html")
    if err != nil {
        fmt.Println("create template failed, err:", err)
        return
    }
    // 利用给定数据渲染模板,并将结果写入w
    user := UserInfo{
        Name:   "枯藤",
        Gender: "男",
        Age:    18,
    }
    tmpl.Execute(w, user)
}
  • HTML文件代码如下:
<!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>Hello</title>
</head>
<body>
    <p>Hello {{.Name}}</p>
    <p>性别:{{.Gender}}</p>
    <p>年龄:{{.Name}}</p>
</body>
</html>
  • 同理,当我们传入的变量是map时,也可以在模板文件中通过.根据key来取值。

(2)注释

    {{/* a comment */}}
    注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。

(3)pipeline

  • pipeline是指产生数据的操作。比如{{.}}{{.Name}}等。Go的模板语法中支持使用管道符号|链接多个命令,用法和unix下的管道类似:|前面的命令会将运算结果(或返回值)传递给后一个命令的最后一个位置。

  • 注意 : 并不是只有使用了|才是pipeline。Go的模板语法中,pipeline的概念是传递数据,只要能产生数据的,都是pipeline。

(4)变量

  • Action里可以初始化一个变量来捕获管道的执行结果。初始化语法如下:
    $variable := pipeline
  • 其中$variable是变量的名字。声明变量的action不会产生任何输出。

3. 条件判断

  • Go模板语法中的条件判断有以下几种:
{{if pipeline}} T1 {{end}}

{{if pipeline}} T1 {{else}} T0 {{end}}

{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}

(1)range

  • Go的模板语法中使用range关键字进行遍历,有以下两种写法,其中pipeline的值必须是数组、切片、字典或者通道。
{{range pipeline}} T1 {{end}}
如果pipeline的值其长度为0,不会有任何输出

{{range pipeline}} T1 {{else}} T0 {{end}}
如果pipeline的值其长度为0,则会执行T0。

(2)with

{{with pipeline}} T1 {{end}}
如果pipeline为empty不产生输出,否则将dot设为pipeline的值并执行T1。不修改外面的dot。

{{with pipeline}} T1 {{else}} T0 {{end}}
如果pipeline为empty,不改变dot并执行T0,否则dot设为pipeline的值并执行T1。

4. 预定义函数

  • 执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用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逸码等价表示。
urlquery
    返回其参数文本表示的可嵌入URL查询的逸码等价表示。
js
    返回其参数文本表示的JavaScript逸码等价表示。
call
    执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;
    如"call .X.Y 1 2"等价于go语言里的dot.X.Y(1, 2);
    其中Y是函数类型的字段或者字典的值,或者其他类似情况;
    call的第一个参数的执行结果必须是函数类型的值(和预定义函数如print明显不同);
    该函数类型值必须有1到2个返回值,如果有2个则后一个必须是error接口类型;
    如果有2个返回值的方法返回的error非nil,模板执行会中断并返回给调用模板执行者该错误;

5. 比较函数

  • 布尔函数会将任何类型的零值视为假,其余视为真。

  • 下面是定义为函数的二元比较运算的集合:

    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}}
  • 比较函数只适用于基本类型(或重定义的基本类型,如”type Celsius float32”)。但是,整数和浮点数不能互相比较。

6. 自定义函数

  • Go的模板支持自定义函数。
func sayHello(w http.ResponseWriter, r *http.Request) {
    htmlByte, err := ioutil.ReadFile("./hello.html")
    if err != nil {
        fmt.Println("read html failed, err:", err)
        return
    }
    // 自定义一个夸人的模板函数
    kua := func(arg string) (string, error) {
        return arg + "真帅", nil
    }
    // 采用链式操作在Parse之前调用Funcs添加自定义的kua函数
    tmpl, err := template.New("hello").Funcs(template.FuncMap{"kua": kua}).Parse(string(htmlByte))
    if err != nil {
        fmt.Println("create template failed, err:", err)
        return
    }

    user := UserInfo{
        Name:   "枯藤",
        Gender: "男",
        Age:    18,
    }
    // 使用user渲染模板,并将结果写入w
    tmpl.Execute(w, user)
}
  • 我们可以在模板文件hello.html中使用我们自定义的kua函数了。
    {{kua .Name}}

7. 嵌套template

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

  • 举个例子: t.html文件内容如下:

<!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>tmpl test</title>
</head>
<body>

    <h1>测试嵌套template语法</h1>
    <hr>
    {{template "ul.html"}}
    <hr>
    {{template "ol.html"}}
</body>
</html>

{{ define "ol.html"}}
<h1>这是ol.html</h1>
<ol>
    <li>吃饭</li>
    <li>睡觉</li>
    <li>打豆豆</li>
</ol>
{{end}}
  • ul.html文件内容如下:
<ul>
    <li>注释</li>
    <li>日志</li>
    <li>测试</li>
</ul>
  • 我们注册一个templDemo路由处理函数.
http.HandleFunc("/tmpl", tmplDemo)
  • tmplDemo函数的具体内容如下:
func tmplDemo(w http.ResponseWriter, r *http.Request) {
    tmpl, err := template.ParseFiles("./t.html", "./ul.html")
    if err != nil {
        fmt.Println("create template failed, err:", err)
        return
    }
    user := UserInfo{
        Name:   "枯藤",
        Gender: "男",
        Age:    18,
    }
    tmpl.Execute(w, user)
}

标签:pipeline,函数,err,标准,html,template,模板
From: https://www.cnblogs.com/Mcoming/p/18073212

相关文章

  • VMware ESXi 8.0U1d macOS Unlocker & OEM BIOS 标准版和厂商定制版
    VMwareESXi8.0U1dmacOSUnlocker&OEMBIOS标准版和厂商定制版ESXi8.0U1标准版,Dell(戴尔)、HPE(慧与)、Lenovo(联想)、Inspur(浪潮)、Cisco(思科)、Hitachi(日立)、Fujitsu(富士通)、NEC(日电)OEM定制版请访问原文链接:https://sysin.org/blog/vmware-esxi-8-u1......
  • 标准库之http
    目录一、Http1.net/http介绍2.HTTP协议3.HTTP客户端4.GET请求示例5.带参数的GET请求示例6.Post请求示例7.自定义Client8.自定义Transport9.服务端(1)默认的Server(2)默认的Server示例(3)自定义Server一、HttpGo语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实......
  • 标准库之os
    目录os介绍1.os基础操作2.os文件及目录相关3.其他os介绍os包提供了不依赖平台的操作系统函数接口。错误处理设计为go风格,失败的调用会返回错误值而非错误码。通常错误值里包含更多信息1.os基础操作//获取文件信息,可以用来判断文件或目录是否存在,获取文件大小os.Stat......
  • 标准库之exec
    目录一、exec介绍1.exec函数和Cmd的方法二、案例1.只执行命令,不获取结果2.执行命令并获取结果3.执行命令,区分stdout和stderr4.使用管道,多条命令组合5.设置程序级别的环境变量一、exec介绍有时候我们的go程序需要执行外部的命令,比如执行linuxshell命令,一个其他语言编......
  • 标准库之strings
    目录一、strings库介绍二、字符串比较-Compare1.介绍2.示例三、检测字符串是否包含子串-Contains1.介绍2.示例四、大小写转换1.介绍2.示例五、统计子字符串出现的次数1.介绍2.示例六、判断字符串的前后缀1.介绍2.示例七、分割和连接1.介绍2.示例八、索引1.介绍2.示......
  • 标准库之rand
    目录一、rand库介绍二、math/rand1.基本使用2.常用的方法3.生成定长的随机数三、crypto/rand一、rand库介绍在Go中,有两个包提供了rand,分别为math/rand和crypto/rand,对应两种应用场景math/rand包实现了伪随机数生成器。也就是生成整型和浮点型crypto/rand包实......
  • 标准库之path和filepath
    目录一、Path包1.常用函数2.示例二、filepath1.常用函数2.示例一、Path包实现的功能和python的os模块的os.path的方法类似注意:该包只对/路径有效,windows的\路径无效1.常用函数path包实现了对用斜杠进行分隔的路径进行操作的函数funcIsAbs(pathstring)bool//......
  • 标准库之context(很重要)
    目录标准库之context一、为什么需要context1.基本并发的示例2.全局变量方式的并发3.通道方式的并发4.官方版的方案二、Context初识1.Context接口2.两个顶级Context(1)Background()和TODO()(2)区别3.派生Context(With系列函数)(1)WithCancel(可取消context)i.context控制goroutin......
  • 第四章 python的标准库
    第四章python的标准库一、`os`1.1基本功能1.2文件和目录操作1.2.1目录操作1.2.2文件操作1.3路径操作1.4环境变量1.4.1`os.environ`1.4.2`os.pathsep`1.4.3`os.name`1.4.4`os.system()`1.4.5`os.putenv(key,value)`和`os.unsetenv(key)`1.5进程管理1.5......
  • Rust 标准库 Trait 指南
    部分内容来自Rust2021年期刊内容目录引言Trait基础自动Trait泛型Trait格式化Trait操作符Trait转换Trait错误处理迭代器TraitI/OTrait总结引言你是否曾想过下面这些trait有什么不同?Deref<Traget=T>,AsRef<T>,以及Borrow<T>?Clone,Copy,和ToOwned?From......