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 指令的数据可以是任意类型,只要在模板块中能够正确处理即可。

相关推荐
花花鱼19 分钟前
spring boot项目使用tomcat发布,也可以使用Undertow(理论)
spring boot·后端·tomcat
你的人类朋友2 小时前
快速搭建redis环境并使用redis客户端进行连接测试
前端·redis·后端
235163 小时前
【MySQL】数据库事务深度解析:从四大特性到隔离级别的实现逻辑
java·数据库·后端·mysql·java-ee
何中应4 小时前
MyBatis-Plus字段类型处理器使用
java·数据库·后端·mybatis
绝无仅有4 小时前
资深面试题之MySQL问题及解答(二)
后端·面试·github
绝无仅有5 小时前
某大厂库存秒杀的设计与实现总结
后端·面试·github
JavaPub-rodert6 小时前
用 go-commons 打造更优雅的字符串处理工具
开发语言·后端·golang
老华带你飞7 小时前
学生信息管理系统|基于Springboot的学生信息管理系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·学生信息管理系统
Fency咖啡8 小时前
Spring 基础核心 - SpringMVC 入门与请求流程
java·后端·spring·mvc
阑梦清川8 小时前
深入理解文件系统和软硬链接
后端