当前位置: 首页>>编程示例 >>用法及示例精选 >>正文


GO Template用法及代码示例

GO语言"html/template"包中"Template"类型的用法及代码示例。

模板是来自"text/template" 的专用模板,可生成安全的 HTML 文档片段。

用法:

type Template struct {

    // The underlying template's parse tree, updated to be HTML-safe.
    Tree *parse.Tree // Go 1.2
    // contains filtered or unexported fields
}

示例(块):

package main

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

func main() {
    const (
        master  = `Names:{{block "list" .}}{{"\n"}}{{range .}}{{println "-" .}}{{end}}{{end}}`
        overlay = `{{define "list"}} {{join . ", "}}{{end}} `
    )
    var (
        funcs     = template.FuncMap{"join": strings.Join}
        guardians = []string{"Gamora", "Groot", "Nebula", "Rocket", "Star-Lord"}
    )
    masterTmpl, err := template.New("master").Funcs(funcs).Parse(master)
    if err != nil {
        log.Fatal(err)
    }
    overlayTmpl, err := template.Must(masterTmpl.Clone()).Parse(overlay)
    if err != nil {
        log.Fatal(err)
    }
    if err := masterTmpl.Execute(os.Stdout, guardians); err != nil {
        log.Fatal(err)
    }
    if err := overlayTmpl.Execute(os.Stdout, guardians); err != nil {
        log.Fatal(err)
    }
}

输出:

Names:
- Gamora
- Groot
- Nebula
- Rocket
- Star-Lord
Names: Gamora, Groot, Nebula, Rocket, Star-Lord

示例(全局):

在这里,我们演示从目录加载一组模板。

package main

import (
    "io"
    "log"
    "os"
    "path/filepath"
    "text/template"
)

// templateFile defines the contents of a template to be stored in a file, for testing.
type templateFile struct {
    name     string
    contents string
}

func createTestDir(files []templateFile) string {
    dir, err := os.MkdirTemp("", "template")
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        f, err := os.Create(filepath.Join(dir, file.name))
        if err != nil {
            log.Fatal(err)
        }
        defer f.Close()
        _, err = io.WriteString(f, file.contents)
        if err != nil {
            log.Fatal(err)
        }
    }
    return dir
}

func main() {
    // Here we create a temporary directory and populate it with our sample
    // template definition files; usually the template files would already
    // exist in some location known to the program.
    dir := createTestDir([]templateFile{
        // T0.tmpl is a plain template file that just invokes T1.
        {"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},
        // T1.tmpl defines a template, T1 that invokes T2.
        {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
        // T2.tmpl defines a template T2.
        {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
    })
    // Clean up after the test; another quirk of running as an example.
    defer os.RemoveAll(dir)

    // pattern is the glob pattern used to find all the template files.
    pattern := filepath.Join(dir, "*.tmpl")

    // Here starts the example proper.
    // T0.tmpl is the first name matched, so it becomes the starting template,
    // the value returned by ParseGlob.
    tmpl := template.Must(template.ParseGlob(pattern))

    err := tmpl.Execute(os.Stdout, nil)
    if err != nil {
        log.Fatalf("template execution: %s", err)
    }
}

输出:

T0 invokes T1: (T1 invokes T2: (This is T2))

示例(助手):

此示例演示了一种共享模板并在不同上下文中使用它们的方法。在这个变体中,我们手动将多个驱动程序模板添加到现有的模板包中。

package main

import (
    "io"
    "log"
    "os"
    "path/filepath"
    "text/template"
)

// templateFile defines the contents of a template to be stored in a file, for testing.
type templateFile struct {
    name     string
    contents string
}

func createTestDir(files []templateFile) string {
    dir, err := os.MkdirTemp("", "template")
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        f, err := os.Create(filepath.Join(dir, file.name))
        if err != nil {
            log.Fatal(err)
        }
        defer f.Close()
        _, err = io.WriteString(f, file.contents)
        if err != nil {
            log.Fatal(err)
        }
    }
    return dir
}

func main() {
    // Here we create a temporary directory and populate it with our sample
    // template definition files; usually the template files would already
    // exist in some location known to the program.
    dir := createTestDir([]templateFile{
        // T1.tmpl defines a template, T1 that invokes T2.
        {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
        // T2.tmpl defines a template T2.
        {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
    })
    // Clean up after the test; another quirk of running as an example.
    defer os.RemoveAll(dir)

    // pattern is the glob pattern used to find all the template files.
    pattern := filepath.Join(dir, "*.tmpl")

    // Here starts the example proper.
    // Load the helpers.
    templates := template.Must(template.ParseGlob(pattern))
    // Add one driver template to the bunch; we do this with an explicit template definition.
    _, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}")
    if err != nil {
        log.Fatal("parsing driver1: ", err)
    }
    // Add another driver template.
    _, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}")
    if err != nil {
        log.Fatal("parsing driver2: ", err)
    }
    // We load all the templates before execution. This package does not require
    // that behavior but html/template's escaping does, so it's a good habit.
    err = templates.ExecuteTemplate(os.Stdout, "driver1", nil)
    if err != nil {
        log.Fatalf("driver1 execution: %s", err)
    }
    err = templates.ExecuteTemplate(os.Stdout, "driver2", nil)
    if err != nil {
        log.Fatalf("driver2 execution: %s", err)
    }
}

输出:

Driver 1 calls T1: (T1 invokes T2: (This is T2))
Driver 2 calls T2: (This is T2)

示例(解析文件):

这里我们演示从不同目录的文件中加载一组模板

package main

import (
    "io"
    "log"
    "os"
    "path/filepath"
    "text/template"
)

// templateFile defines the contents of a template to be stored in a file, for testing.
type templateFile struct {
    name     string
    contents string
}

func createTestDir(files []templateFile) string {
    dir, err := os.MkdirTemp("", "template")
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        f, err := os.Create(filepath.Join(dir, file.name))
        if err != nil {
            log.Fatal(err)
        }
        defer f.Close()
        _, err = io.WriteString(f, file.contents)
        if err != nil {
            log.Fatal(err)
        }
    }
    return dir
}

func main() {
    // Here we create different temporary directories and populate them with our sample
    // template definition files; usually the template files would already
    // exist in some location known to the program.
    dir1 := createTestDir([]templateFile{
        // T1.tmpl is a plain template file that just invokes T2.
        {"T1.tmpl", `T1 invokes T2: ({{template "T2"}})`},
    })

    dir2 := createTestDir([]templateFile{
        // T2.tmpl defines a template T2.
        {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
    })

    // Clean up after the test; another quirk of running as an example.
    defer func(dirs ...string) {
        for _, dir := range dirs {
            os.RemoveAll(dir)
        }
    }(dir1, dir2)

    // Here starts the example proper.
    // Let's just parse only dir1/T0 and dir2/T2
    paths := []string{
        filepath.Join(dir1, "T1.tmpl"),
        filepath.Join(dir2, "T2.tmpl"),
    }
    tmpl := template.Must(template.ParseFiles(paths...))

    err := tmpl.Execute(os.Stdout, nil)
    if err != nil {
        log.Fatalf("template execution: %s", err)
    }
}

输出:

T1 invokes T2: (This is T2)

示例(共享):

此示例演示如何将一组驱动程序模板与不同的帮助程序模板集一起使用。

package main

import (
    "io"
    "log"
    "os"
    "path/filepath"
    "text/template"
)

// templateFile defines the contents of a template to be stored in a file, for testing.
type templateFile struct {
    name     string
    contents string
}

func createTestDir(files []templateFile) string {
    dir, err := os.MkdirTemp("", "template")
    if err != nil {
        log.Fatal(err)
    }
    for _, file := range files {
        f, err := os.Create(filepath.Join(dir, file.name))
        if err != nil {
            log.Fatal(err)
        }
        defer f.Close()
        _, err = io.WriteString(f, file.contents)
        if err != nil {
            log.Fatal(err)
        }
    }
    return dir
}

func main() {
    // Here we create a temporary directory and populate it with our sample
    // template definition files; usually the template files would already
    // exist in some location known to the program.
    dir := createTestDir([]templateFile{
        // T0.tmpl is a plain template file that just invokes T1.
        {"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"},
        // T1.tmpl defines a template, T1 that invokes T2. Note T2 is not defined
        {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
    })
    // Clean up after the test; another quirk of running as an example.
    defer os.RemoveAll(dir)

    // pattern is the glob pattern used to find all the template files.
    pattern := filepath.Join(dir, "*.tmpl")

    // Here starts the example proper.
    // Load the drivers.
    drivers := template.Must(template.ParseGlob(pattern))

    // We must define an implementation of the T2 template. First we clone
    // the drivers, then add a definition of T2 to the template name space.

    // 1. Clone the helper set to create a new name space from which to run them.
    first, err := drivers.Clone()
    if err != nil {
        log.Fatal("cloning helpers: ", err)
    }
    // 2. Define T2, version A, and parse it.
    _, err = first.Parse("{{define `T2`}}T2, version A{{end}}")
    if err != nil {
        log.Fatal("parsing T2: ", err)
    }

    // Now repeat the whole thing, using a different version of T2.
    // 1. Clone the drivers.
    second, err := drivers.Clone()
    if err != nil {
        log.Fatal("cloning drivers: ", err)
    }
    // 2. Define T2, version B, and parse it.
    _, err = second.Parse("{{define `T2`}}T2, version B{{end}}")
    if err != nil {
        log.Fatal("parsing T2: ", err)
    }

    // Execute the templates in the reverse order to verify the
    // first is unaffected by the second.
    err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second")
    if err != nil {
        log.Fatalf("second execution: %s", err)
    }
    err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first")
    if err != nil {
        log.Fatalf("first: execution: %s", err)
    }

}

输出:

T0 (second version) invokes T1: (T1 invokes T2: (T2, version B))
T0 (first version) invokes T1: (T1 invokes T2: (T2, version A))

相关用法


注:本文由纯净天空筛选整理自golang.google.cn大神的英文原创作品 Template。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。