goweb模板语法html/template

在Go语言里, html/template 包主要用于安全地生成HTML输出。它能够有效防止跨站脚本攻击(XSS),借助模板语法将数据动态填充到HTML文件中。

模板的定义与解析

借助 template.Newtemplate.ParseFiles 或者 template.ParseGlob 方法,能够定义并解析模板文件。

go 复制代码
package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    // 创建一个新的模板
    tmpl := template.New("example")

    // 解析模板文件
    tmpl, err := tmpl.ParseFiles("example.tmpl")
    if err != nil {
        log.Fatal(err)
    }

    // 定义数据
    data := struct {
        Name string
    }{
        Name: "John Doe",
    }

    // 执行模板并将结果输出到标准输出
    err = tmpl.Execute(os.Stdout, data)
    if err != nil {
        log.Fatal(err)
    }
}

模板文件示例(example.tmpl)

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Example Template</title>
</head>
<body>
    <h1>Hello, {{.Name}}!</h1>
</body>
</html>

条件语句

在模板里能够使用条件语句来依据数据展示不同内容。

go 复制代码
package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    tmpl, err := template.ParseFiles("conditional.tmpl")
    if err != nil {
        log.Fatal(err)
    }

    data := struct {
        IsAdmin bool
    }{
        IsAdmin: true,
    }

    err = tmpl.Execute(os.Stdout, data)
    if err != nil {
        log.Fatal(err)
    }
}

条件模板文件示例(conditional.tmpl)

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Conditional Template</title>
</head>
<body>
    {{if .IsAdmin}}
        <p>You are an admin!</p>
    {{else}}
        <p>You are a regular user.</p>
    {{end}}
</body>
</html>

循环语句

在模板中可使用循环语句来遍历切片或者映射。

go 复制代码
package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    tmpl, err := template.ParseFiles("loop.tmpl")
    if err != nil {
        log.Fatal(err)
    }

    data := []string{"Apple", "Banana", "Cherry"}

    err = tmpl.Execute(os.Stdout, data)
    if err != nil {
        log.Fatal(err)
    }
}

循环模板文件示例(loop.tmpl)

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Loop Template</title>
</head>
<body>
    <ul>
        {{range .}}
            <li>{{.}}</li>
        {{end}}
    </ul>
</body>
</html>

嵌套模板

可以在一个模板里包含另一个模板。

可以使用 {{template "templateName" .}} 来调用并执行定义好的模板块。其中,. 表示传递给模板块的数据。

go 复制代码
package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    tmpl, err := template.ParseFiles("base.tmpl", "header.tmpl")
    if err != nil {
        log.Fatal(err)
    }

    data := struct {
        Title string
    }{
        Title: "Nested Template Example",
    }

    err = tmpl.ExecuteTemplate(os.Stdout, "base.tmpl", data)
    if err != nil {
        log.Fatal(err)
    }
}

基础模板文件示例(base.tmpl)

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Title}}</title>
</head>
<body>
    {{template "header.tmpl" .}}
    <p>Main content goes here.</p>
</body>
</html>

头部模板文件示例(header.tmpl)

css 复制代码
<header>
    <h1>{{.Title}}</h1>
</header>


define 指令的作用

define 指令用于在模板文件中定义一个命名的模板块。这个模板块可以在同一个模板文件或者其他模板文件中被调用和执行。通过使用 define 指令,你可以将重复的 HTML 代码片段封装成可复用的模块,提高代码的可维护性和复用性。

基本语法

在模板文件中,使用 {{define "templateName"}} 来开始定义一个模板块,使用 {{end}} 来结束定义。其中,templateName 是你为这个模板块指定的名称。

xml 复制代码
{{define "templateName"}}
    <!-- 这里是模板块的内容 -->
{{end}}

单个模板文件中使用 define

以下是一个示例,展示了如何在单个模板文件中定义和使用模板块。

go 复制代码
package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    tmpl, err := template.ParseFiles("single_template.tmpl")
    if err != nil {
        log.Fatal(err)
    }

    data := struct {
        Title string
    }{
        Title: "Single Template Example",
    }

    err = tmpl.ExecuteTemplate(os.Stdout, "main", data)
    if err != nil {
        log.Fatal(err)
    }
}

single_template.tmpl

xml 复制代码
{{define "header"}}
    <header>
        <h1>{{.Title}}</h1>
    </header>
{{end}}

{{define "main"}}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{.Title}}</title>
    </head>
    <body>
        {{template "header" .}}
        <p>Main content goes here.</p>
    </body>
    </html>
{{end}}

在这个示例中,我们在 single_template.tmpl 文件中定义了两个模板块:headermain。在 main 模板块中,我们使用 {{template "header" .}} 调用了 header 模板块。

多个模板文件中使用 define

以下是一个示例,展示了如何在多个模板文件中定义和使用模板块。

go 复制代码
package main

import (
    "html/template"
    "log"
    "os"
)

func main() {
    tmpl, err := template.ParseFiles("base.tmpl", "header.tmpl")
    if err != nil {
        log.Fatal(err)
    }

    data := struct {
        Title string
    }{
        Title: "Multiple Templates Example",
    }

    err = tmpl.ExecuteTemplate(os.Stdout, "base", data)
    if err != nil {
        log.Fatal(err)
    }
}

header.tmpl

css 复制代码
{{define "header"}}
    <header>
        <h1>{{.Title}}</h1>
    </header>
{{end}}

base.tmpl

xml 复制代码
{{define "base"}}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{{.Title}}</title>
    </head>
    <body>
        {{template "header" .}}
        <p>Main content goes here.</p>
    </body>
    </html>
{{end}}

在这个示例中,我们将 header 模板块定义在 header.tmpl 文件中,将 base 模板块定义在 base.tmpl 文件中。在 base 模板块中,我们使用 {{template "header" .}} 调用了 header 模板块。

注意事项

  • 当使用 ParseFilesParseGlob 解析多个模板文件时,所有定义的模板块都会被加载到同一个模板集合中,因此可以在不同的模板文件中相互调用。
  • 传递给 template 指令的数据可以是任意类型,只要在模板块中能够正确处理即可。

相关推荐
乐神嘎嘎嘎2 小时前
接口测试面试题
后端
AAA修煤气灶刘哥2 小时前
ES数据同步大乱斗:同步双写 vs MQ异步,谁才是王者?
分布式·后端·elasticsearch
Yvonne爱编码3 小时前
后端编程开发路径:从入门到精通的系统性探索
java·前端·后端·python·sql·go
bobz9654 小时前
ovn 厂商使用的规模
后端
JiayinX4 小时前
django连接minio实现文件上传下载(提供接口示例)
后端·python·django
IT_陈寒5 小时前
Spring Boot 3.2 新特性全解析:这5个性能优化点让你的应用提速50%!
前端·人工智能·后端
Eiceblue5 小时前
使用 C# 设置 Excel 单元格格式
开发语言·后端·c#·.net·excel
li35745 小时前
Spring Boot 中 StringRedisTemplate 与 RedisTemplate 的区别与使用陷阱(附 getBean 为何报错
java·spring boot·后端
华仔啊5 小时前
依赖注入用@Autowired、@Resource还是构造器?3分钟搞清Spring官方到底推荐谁
java·后端