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

相关推荐
程序员鱼皮1 小时前
前后端分离,千万别再搞错了!
java·前端·后端·计算机·程序员·编程·软件开发
葡萄城技术团队1 小时前
Django 与 FastAPI 架构对比:学习路径指南
后端
golang学习记1 小时前
Go Web 应用中的配置管理最佳实践
后端
SimonKing1 小时前
【开发者必备】Spring Boot 2.7.x:WebMvcConfigurer配置手册来了(五)!
java·后端·程序员
Value_Think_Power1 小时前
Dapr pub/sub
后端
间彧1 小时前
Fastjson Map转JSON字符串API详解与项目实战
后端
Value_Think_Power2 小时前
dapr::Listiner
后端
闲云散2 小时前
WebClient 简述
java·后端
狗头大军之江苏分军2 小时前
请不要在感情里丢掉你的“我”
前端·后端
BingoGo2 小时前
2025 年必须尝试的 5 个 Laravel 新特性
后端