text/template.Template.ExecuteTemplate în Go

Execută din set șablonul cu numele dat (definit cu {{define}} sau încărcat dintr-un fișier).

Sintaxă
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error

// în șablon: {{define "nume"}}...{{end}}  {{template "nume" .}}  {{block "nume" .}}...{{end}}

Ce face text/template.Template.ExecuteTemplate

Un *template.Template poate conține mai multe șabloane cu nume: fișiere încărcate cu ParseFiles sau blocuri definite cu {{define "nume"}}...{{end}}. t.ExecuteTemplate(w, "nume", date) execută doar șablonul cerut.

Așa se construiesc pagini din bucăți: un șablon "antet", unul "subsol", iar paginile le includ cu {{template "antet" .}}. {{block "nume" .}}conținut implicit{{end}} definește și include deodată un bloc pe care alt șablon îl poate redefini.

Parametri

Parametru Descriere
wr Destinația.
name Numele șablonului de executat.
data Datele.

Ce returnează

nil sau o eroare (inclusiv dacă nu există șablon cu acel nume).

Exemple

Exemplul 1: Mai multe șabloane într-un singur text

package main

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

const sabloane = `
{{define "antet"}}=== {{.Magazin}} ==={{end}}
{{define "chitanta"}}{{template "antet" .}}
{{range .Linii}}{{printf "%-12s %8.2f" .Produs .Pret}}
{{end}}{{template "subsol" .}}{{end}}
{{define "subsol"}}Mulțumim! {{.Oras}}
{{end}}`

func main() {
	t := template.Must(template.New("tot").Parse(sabloane))
	date := map[string]any{
		"Magazin": "Cafeneaua Dex",
		"Oras":    "Iași",
		"Linii": []map[string]any{
			{"Produs": "espresso", "Pret": 9.5},
			{"Produs": "croissant", "Pret": 12.0},
		},
	}
	if err := t.ExecuteTemplate(os.Stdout, "chitanta", date); err != nil {
		fmt.Println(err)
	}
	err := t.ExecuteTemplate(os.Stdout, "factura", date)
	fmt.Println("Eroare:", err)
}

Rezultat

=== Cafeneaua Dex ===
espresso         9.50
croissant       12.00
Mulțumim! Iași
Eroare: template: no template "factura" associated with template "tot"

Exemplul 2: Bloc implicit redefinit

Șablonul de bază are un block cu conținut implicit. Pentru pagina „contact”, clonăm baza și redefinim blocul.

package main

import (
	"os"
	"text/template"
)

func main() {
	baza := template.Must(template.New("baza").Parse(
		"[{{block \"continut\" .}}Pagina principală{{end}}] - {{.Site}}\n"))

	contact := template.Must(template.Must(baza.Clone()).Parse(
		`{{define "continut"}}Contact: {{.Email}}{{end}}`))

	date := map[string]string{"Site": "dexblog.ro", "Email": "contact@dexblog.ro"}
	baza.ExecuteTemplate(os.Stdout, "baza", date)
	contact.ExecuteTemplate(os.Stdout, "baza", date)
}

Rezultat

[Pagina principală] - dexblog.ro
[Contact: contact@dexblog.ro] - dexblog.ro

Greșeli frecvente

  • Scrii {{template "antet"}} fără punct: șablonul inclus primește nil ca date și câmpurile apar ca <no value>. Scrie {{template "antet" .}}.
  • Redefinești același bloc direct în setul de bază pentru mai multe pagini: ultima definiție câștigă pentru toate. Folosește Clone() pentru fiecare pagină.

Comenzi înrudite

  • text/template.ParseFiles: Încarcă șabloane din fișiere; fiecare fișier devine un șablon numit după numele fișierului.
  • text/template.Template.Execute: Completează șablonul cu datele date și scrie rezultatul într-un io.Writer (ecran, fișier, răspuns HTTP, buffer).
  • html/template.Template: Șabloane pentru HTML, cu aceeași interfață ca text/template, care codează automat datele după context (protecție XSS).