text/template.New în Go

Creează un șablon text cu un nume; Parse îi încarcă textul cu acțiuni {{...}} care vor fi completate din date.

Sintaxă
import "text/template"

func New(name string) *Template
func (t *Template) Parse(text string) (*Template, error)

// în șablon: {{.Camp}}  {{if .X}}...{{else}}...{{end}}  {{range .Lista}}...{{end}}

Ce face text/template.New

Un șablon este un text cu „găuri” scrise între acolade duble: {{.Nume}} înseamnă „pune aici câmpul Nume din datele primite”. template.New("factura") creează un *template.Template gol cu un nume, iar t.Parse(text) citește textul și verifică sintaxa acțiunilor. Șablonul se completează apoi cu Execute.

Acțiuni de bază: {{.}} (datele întregi), {{.Camp}} sau {{.Harta.cheie}}, {{if .Conditie}}...{{else}}...{{end}}, {{range .Lista}}...{{end}} (în interior . devine elementul curent), {{with .X}}...{{end}}, variabile ({{$total := .Total}}), funcții predefinite (len, printf, index, eq, lt…) și comentarii {{/* ... */}}. Cratima lipită de acolade ({{-, -}}) elimină spațiile și rândurile noi de lângă acțiune.

text/template produce text simplu (e-mailuri, fișiere de configurare, cod generat). Pentru pagini HTML folosește html/template, care are aceeași interfață și protejează automat împotriva XSS.

Parametri

Parametru Descriere
name Numele șablonului (folosit în mesajele de eroare și de ExecuteTemplate).
text Textul șablonului.

Ce returnează

New: un *template.Template. Parse: același șablon și o eroare de sintaxă.

Exemple

Exemplul 1: Mesaj de confirmare

package main

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

type Comanda struct {
	Client  string
	Numar   int
	Produse []string
	Total   float64
	Livrare bool
}

func main() {
	t, err := template.New("confirmare").Parse(`Bună, {{.Client}}!
Comanda #{{.Numar}} conține {{len .Produse}} produse:
{{range .Produse}}  - {{.}}
{{end}}Total: {{printf "%.2f" .Total}} lei
{{if .Livrare}}Livrare prin curier.{{else}}Ridicare din magazin.{{end}}
`)
	if err != nil {
		fmt.Println(err)
		return
	}
	c := Comanda{"Ana", 1001, []string{"cafea", "ceai verde", "cană"}, 154.4, true}
	if err := t.Execute(os.Stdout, c); err != nil {
		fmt.Println(err)
	}
}

Rezultat

Bună, Ana!
Comanda #1001 conține 3 produse:
  - cafea
  - ceai verde
  - cană
Total: 154.40 lei
Livrare prin curier.

Exemplul 2: Eroare de sintaxă la Parse

package main

import (
	"fmt"
	"text/template"
)

func main() {
	_, err := template.New("gresit").Parse("Salut {{.Nume}")
	fmt.Println(err)
	_, err = template.New("fara-end").Parse("{{if .Activ}}activ")
	fmt.Println(err)
}

Rezultat

template: gresit:1: bad character U+007D '}'
template: fara-end:1: unexpected EOF

Exemplul 3: Controlul spațiilor cu {{- și -}}

package main

import (
	"os"
	"text/template"
)

func main() {
	t, _ := template.New("lista").Parse(`Orașe:
{{- range .}}
  * {{.}}
{{- end}}
Gata.
`)
	t.Execute(os.Stdout, []string{"Iași", "Cluj", "Timișoara"})
}

Rezultat

Orașe:
  * Iași
  * Cluj
  * Timișoara
Gata.

Greșeli frecvente

  • Scrii câmpurile cu literă mică în structură: șablonul nu le poate citi și Execute dă eroare (... is an unexported field).
  • Folosești text/template pentru HTML cu date de la utilizatori: textul este pus ca atare, deci un <script> trimis de cineva ajunge în pagină. Folosește html/template.
  • Uiți că în {{range}} punctul este elementul curent: {{.Client}} în interior caută câmpul în element. Pentru datele de sus folosește {{$.Client}}.

Comenzi înrudite

  • text/template.Template.Execute: Completează șablonul cu datele date și scrie rezultatul într-un io.Writer (ecran, fișier, răspuns HTTP, buffer).
  • text/template.Must: Primește rezultatul lui Parse (șablon, eroare) și oprește programul cu panică dacă există eroare; pentru șabloane fixe.
  • text/template.Template.Funcs: Adaugă funcții proprii pe care șablonul le poate apela ({{lei .Total}}); trebuie apelată înainte de Parse.
  • html/template.Template: Șabloane pentru HTML, cu aceeași interfață ca text/template, care codează automat datele după context (protecție XSS).