A template keeps structured output readable when mostly static text must include changing values. It is easier to maintain than a long fmt.Sprintf call or a sequence of strings.Builder writes, especially as an HTML page grows. Go provides text/template for general text and html/template for HTML; the latter escapes values printed into the page to protect against HTML injection. section 11.1.2
Render a list
This complete program parses a template, then executes it with a slice: package main import ( "log" "os" "text/template" ) func main() { t, err := template.New("items").Parse(`{{range .}}{{.}}, {{end}}`) if err != nil { log.Fatal(err) } if err := t.Execute(os.Stdout, []string{"a", "b", "c"}); err != nil { log.Fatal(err) } } It prints `a, b, c, `. The trailing comma is literal template text; adjust the template if the output format must omit it. section 11.2 section 11.2.1
Build an HTML page by adding actions between `{{` and `}}`:
- Parse the page with `template.New("index").Parse(page)`, then call `Execute(w, data)`. The dot in `{{.}}` is the data passed to execution; check errors from both calls. section 11.1.2
- Use `{{.Name}}` for an exposed field. Use `{{range .Habits}}...{{end}}` to render items; inside the range, dot becomes the current item. Declare `$index, $value` when both are needed. section 11.2.1 section 11.6
- Use `{{if .Habits}}...{{end}}` to omit an empty list. A map can supply several values under names such as `Habits` and `Date`; `{{with .Date}}` makes the date the current dot within its block. section 11.5.1
Prepare data for display rather than forcing every calculation into the page. For example, a week value can expose formatted start and end dates, which the template prints as `{{.Date.Start}}` and `{{.Date.End}}`. Templates depend on the field and method names supplied by Go code, so changing that interface can break rendering. Avoid templating structured formats such as JSON or YAML without considering what happens when input contains an unexpected value. section 11.5.1 section 11.6 section 11.1.2
For a small display calculation, register a Go function with `Funcs(template.FuncMap{"statusCSSClass": statusCSSClass})` before parsing, then call `{{statusCSSClass .}}` in the template. Pipelines pass one function’s result to the next. Test the function and the rendered page after changing the output. section 11.5.2
Listing 11.45 habititem.html: Declaring a template in another file
{{- define "habitItem"}}
<li class="habit {{ statusCSSClass . }}">
<b>{{.Name}}</b>
<span class="{{ if ge .Ticks .WeeklyFrequency -}} done
➥{{- end -}} "> {{- progress . }}</span>
<a href="/tick/{{ .ID }}">Tick!</a>
</li>
{{- end }}
A named `habitItem` template moves repeated list-item markup into its own HTML file. Invoke it inside a range with `{{template "habitItem" .}}`, passing the current item as dot. When parsing several files with `ParseFS`, execute the named page with `ExecuteTemplate`; executing an empty root template instead produces an error. section 11.5.3




















