GO语言html模板

Posted aresxin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GO语言html模板相关的知识,希望对你有一定的参考价值。

模板

一个模板是一个字符串或一个文件,里面包含了一个或多个由双花括号包含的action对象。大部分的字符串只是按面值打印,但是对于actions部分将触发其它的行为。每个actions都包含了一个用模板语言书写的表达式,一个action虽然简短但是可以输出复杂的打印值,模板语言包含通过选择结构体的成员、调用函数或方法、表达式控制流if-else 语句range循环语句,还有其它实例化模板等诸多特性。Action内部不能有换行,但注释可以有换行。

示例

模板执行时会遍历结构并将指针表示为’.‘(称之为”dot”)指向运行过程中数据结构的当前位置的值。
用作模板的输入文本必须是utf-8编码的文本。
html示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
    <p>Hello .!</p>
</body>
</html>

GO server端:

func sayHi(w http.ResponseWriter,r *http.Request)  
    // 解析指定文件生成模板对象
    tem,err := template.ParseFiles("xx/hello.html")
    if err != nil
        fmt.Println("读取文件失败,err",err)
        return
    
    // 利用给定数据渲染模板,并将结果写入w
    tem.Execute(w,"Ares")

func main()  
    http.HandleFunc("/",sayHi)
    err := http.ListenAndServe("127.0.0.1:8888",nil)
    if err != nil
        fmt.Println("监听失败,err",err)
        return
    

效果:
技术图片?

模板语法

模板语法都包含在和中间,其中.中的点表示当前对象。
当我们传入一个结构体对象时,我们可以根据.来访问结构体的对应字段。Html示例:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello</title>
</head>
<body>
    <p>Hello .Name!</p>
    <p>年龄 .Age!</p>
    <p>性别 .Male!</p>
</body>
</html>

GO server端:

type People struct 
    Name string
    Age int
    Male string

func sayHi(w http.ResponseWriter,r *http.Request)  
    // 解析指定文件生成模板对象
    tem,err := template.ParseFiles("xx/hello.html")
    if err != nil
        fmt.Println("读取文件失败,err",err)
        return
    
    // 利用给定数据渲染模板,并将结果写入w
    People := People
        Name:"Ares",
        Age:28,
        Male:"男",
    
    tem.Execute(w,People)

func main()  
    http.HandleFunc("/",sayHi)
    err := http.ListenAndServe("127.0.0.1:8888",nil)
    if err != nil
        fmt.Println("监听失败,err",err)
        return
    

效果:
技术图片?

注释

/* a comment */
可以多行。注释不能嵌套。

变量

Action里可以初始化一个变量来捕获管道的执行结果。初始化语法如下:

$variable := pipeline

示例:

<body>
    <p>Hello .Name!</p>
    <p>年龄 .Age!</p>
    <p>性别 .Male!</p>
     $age := . 
     $age.Age 
</body>

条件判断

初始语法:

if pipeline T1 end
if pipeline T1 else T0 end
if pipeline T1 else if pipeline T0 end

示例:

<body>
    <p>Hello .Name!</p>
    <p>年龄 .Age!</p>
    <p>性别 .Male!</p>
     $age := . 
     $age.Age 
    if gt .Age 18
    <div>成年啦!</div>
    else
    <div>快乐成长!</div>
    end
</body>

比较函数

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

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

range

使用range关键字进行遍历,有以下两种写法,其中pipeline的值必须是数组、切片、字典或者通道。
基本语法:

range pipeline T1 end
如果pipeline的值其长度为0,不会有任何输出

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

map示例:

PeopleMap := map[int]People
        1: "Ares", 18, "男",
        2: "龙猫", 28, "女",
    
tem.Execute(w, PeopleMap)

切片示例:

PeopleSlice := []People
        "Ares", 18, "男",
        "龙猫", 28, "女",
    
    tem.Execute(w, PeopleSlice)

HTML模板:

<body>
<table border="1">
    <thead>
    <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>性别</th>
    </tr>
    </thead>
    <tbody>
    range $index, $user := .
    <tr>
        <td>$index</td>
        <td>$user.Name</td>
        <td>$user.Age</td>
        <td>$user.Male</td>
    </tr>
    end
    </tbody>
</table>
</body>

效果:
技术图片?

预定义函数

执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用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,模板执行会中断并返回给调用模板执行者该错误;

参考:GO语言标准库
示例:

<p>index . 1</p>
    <p>切片长度: len .</p>
    <p>
        with index . 1
        printf "姓名:%s 年龄:%d 性别:%s" .Name .Age .Male
        end
    </p>

效果:
技术图片?

自定义函数

自定义一个book函数:

type Book struct 
    Name string
    Author string
    Price float32


func info(w http.ResponseWriter,r *http.Request)  
    // 打开一个模板文件
    htmlByte,err := ioutil.ReadFile("./info.html")
    if err != nil
        fmt.Println("读取html文件失败,err",err)
        return
    
    // 1. 自定义一个函数
    // 自定义一个书籍的模板函数
    bookFunc := func(arg string) (string, error) 
        return arg + "真好看!", nil
    
    // 2. 把自定义的函数告诉模板系统
    // template.New("info") // 创建一个Template对象
    // template.New("info").Funcs(template.FuncMap"book": bookFunc) // 给模板系统追加自定义函数
    // 解析模板
    t,err := template.New("info").Funcs(template.FuncMap"book": bookFunc).Parse(string(htmlByte))
    if err != nil
        fmt.Println("parse html文件失败,err",err)
        return
    
    BookMap := map[int]Book
        1:"跟Ares一起学GO","Ares",9.9,
        2:"斗破苍穹","Ares1",99.9,
    
    t.Execute(w,BookMap)


func main()  
    http.HandleFunc("/info",info)
    http.ListenAndServe("127.0.0.1:8888",nil)

html:

<body>
    <p>
    with index . 1
    <p>book .Name</p>
    end
    </p>
    <p>
    with index . 2
    <p>book .Name</p>
    end
    </p>
</body>

效果:
技术图片?

模板嵌套

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

func index(w http.ResponseWriter,r * http.Request)  
    t , err := template.ParseFiles("./index.html","./test.html")
    if err != nil
        fmt.Println("读取html文件失败,err",err)
        return
    
    t.Execute(w,nil)

func main()  
    http.HandleFunc("/",index)
    http.ListenAndServe("127.0.0.1:8888",nil)

index.html:

<body>
<h1>测试嵌套template语法</h1>
<hr>
template "test.html"
<hr>
/* 在index.html这个模板中调用了另外一个模板:index.html */
template "inside.html"
</body>
</html>
        
/* 在index.html这个模板中定义了另外一个模板:inside.html */
 define "inside.html"
<h1>inside.html</h1>
<ol>
    <li>吃饭</li>
    <li>睡觉</li>
    <li>打豆豆</li>
</ol>
end

test.html:

<body>
<ol>
    <li>嵌套模板</li>
    <li>out模板</li>
</ol>
</body>

效果:
技术图片?

以上是关于GO语言html模板的主要内容,如果未能解决你的问题,请参考以下文章

Go语言标准库之http/template

Go语言标准库之http/template

go语言整数二分模板

VSCode自定义代码片段——.vue文件的模板

在Visual Studio Code中配置GO开发环境

Go Web编程实战(10)----模板引擎库text/template包的使用