GO Learning Notes - Template Rendering and Multiple Outputs

Posted by kerching on Tue, 01 Oct 2019 22:51:28 +0200

Theme of this article: Implementing Golang template rendering based on built-in text/template, and writing the results to files, screens and variables.

Little slow brother's original article, welcome to reprint.

Catalog

Defining Structures
Define template text
Template Rendering and Output Mode
Complete examples

Defining Structures

First, define a structure for subsequent template rendering

type Person struct {
    Name string
    Age int
    Boy bool
}

Note: Strct elements must be exportable (capitalization first), otherwise they will not be found when rendering.

Instantiate the structure to get the corresponding value in template rendering

foo := Person{
    Name: "foo",
    Age: 18,
    Boy: false,
}

Define template text

Next, we define a template text, where we directly define a constant to represent the template text.

const text = `My name is {{.Name}},
I'm {{.Age}} years old,
I'm a {{if .Boy}}boy{{else}}girl{{end}}.
`

Read the text to get the handler of the template

tmpl, err := template.New("").Parse(text)
if err != nil {
    log.Fatalln(err)
}

Template Rendering and Output Mode

When rendering, you need to pass a parameter to specify where to export. There are three common destinations:

_Output to file
_Output to Variables
_Output to Screen

Output to file: You need to open a file first and get a file handle

f, err := os.OpenFile("/tmp/test", os.O_WRONLY|os.O_CREATE, 0644)
defer f.Close()
if err != nil {
    log.Fatalln(err)
}

// Render and write files
if err := tmpl.Execute(f, foo); err != nil {
    log.Fatalln(err)
}

Output to variables

var buf bytes.Buffer

if err := tmpl.Execute(&buf, foo); err != nil {
    log.Fatalln(err)
}
fmt.Println(buf.String())

Output to screen

if err := tmpl.Execute(os.Stdout, foo); err != nil {
    log.Fatalln(err)
}

Complete example

package main

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

type Person struct {
    Name string
    Age int
    Boy bool
}

func main() {
    // Instance structure
    foo := Person{
        Name: "foo",
        Age: 18,
        Boy: false,
    }

    // Define template text
    const text = `My name is {{.Name}},
I'm {{.Age}} years old,
I'm a {{if .Boy}}boy{{else}}girl{{end}}.
`

    // Generate handler Based on specified template text
    tmpl, err := template.New("").Parse(text)
    if err != nil {
        log.Fatalln(err)
    }

    // Template rendering and writing to files
    f, err := os.OpenFile("/tmp/test", os.O_WRONLY|os.O_CREATE, 0644)
    defer f.Close()
    if err != nil {
        log.Fatalln(err)
    }
    if err := tmpl.Execute(f, foo); err != nil {
        log.Fatalln(err)
    }

    // Template rendering and assignment to variables
    var buf bytes.Buffer
    if err := tmpl.Execute(&buf, foo); err != nil {
        log.Fatalln(err)
    }
    fmt.Println(buf.String())

    // Template rendering and output to screen standard output
    if err := tmpl.Execute(os.Stdout, foo); err != nil {
        log.Fatalln(err)
    }
}

Testing effect

# Compile
go build template.go
./template

# output
My name is foo,
I'm 18 years old,
I'm a girl.

My name is foo,
I'm 18 years old,
I'm a girl.

# View the contents of the file (/tmp/test)
My name is foo,
I'm 18 years old,
I'm a girl.

Topics: Go