liveBook · Manning

Text/template package

As explained in Go in Practice, Second Edition

The Go text/template package generates text from templates containing data substitutions and control logic without HTML-specific contextual escaping.

Use Go’s standard-library text/template package when formatted output is text rather than HTML: email messages and generated Go source are two examples. It substitutes data into a template without html/template’s context-aware escaping. For HTML output, prefer html/template, which builds on text/template and adds HTML-specific handling. section 9.1 section 9.2 section 13.3

Render an email into a buffer

Parse the template, execute it with message data, then give the buffer’s contents to mail-sending code: package main import ( "bytes" "fmt" "text/template" ) func main() { const body = "From: {{.From}}\nTo: {{.To}}\nSubject: {{.Subject}}\n\n{{.Body}}\n" message := struct{ From, To, Subject, Body string }{ "me@example.com", "you@example.com", "Hello", "Welcome!", } t := template.Must(template.New("email").Parse(body)) var output bytes.Buffer if err := t.Execute(&output, message); err != nil { panic(err) } fmt.Print(output.String()) } The buffer separates rendering from delivery; net/smtp can send the rendered message. Injected properties are not HTML-escaped, so apply escaping explicitly where the output requires it. section 9.2 section 13.3

The same substitution pattern can remove repetitive source-code boilerplate. A queue generator fills package and type names into a Go-source template, then writes one file per requested type. A go:generate directive can invoke that generator. Parse once before producing multiple files rather than repeating the parsing work. section 13.3 section 9.3

Listing 13.19 The queue template
package main

import (
     "fmt"
     "os"
     "strings"
     "text/template"
)

var tpl = `package {{.Package}}   #1
type {{.MyType}}Queue struct {    #2
     q []{{.MyType}}
}

func New{{.MyType}}Queue() *{{.MyType}}Queue {
     return &{{.MyType}}Queue{
            q: []{{.MyType}}{},
     }
}

func (o *{{.MyType}}Queue) Insert(v {{.MyType}}) {
     o.q = append(o.q, v)
}

func (o *{{.MyType}}Queue) Remove() {{.MyType}} {
     if len(o.q) == 0 {
            panic("Oops.")
     }
     first := o.q[0]
     o.q = o.q[1:]
     return first
}

The queue template shows how package and type-name substitutions turn one implementation pattern into type-specific Go source. section 13.3

For reusable HTML page sections, use html/template rather than switching to text/template: nested templates and shared base templates retain HTML-aware rendering. Templates can also be parsed ahead of use, while buffering output helps avoid partial renderings when execution fails. section 9.1.5 section 9.3

How Go in Practice, Second Edition covers it

How deep it goes
Works through buffered email rendering and a type-specific queue generator, but does not examine template-engine internals.
Examples
Uses a templated email message and a queue template that substitutes package and type names.
What it assumes
Assumes basic Go structs and output handling while demonstrating template parsing, data substitution, and execution.
What you can do after
Apply it via text/template to render email into a buffer or generate type-specific Go source files.
How it connects
Connects text/template to html/template, context-aware escaping, bytes.Buffer, net/smtp, and go generate.

Also explained in

Compare how 2 books explain text/template package →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Practice, Second Edition. The section links point to the parts of the book it draws on.