Templates 03 - Templates Aninhados

Templates Aninhados

Podemos aninhar templates em Go, dessa forma é possível criar partes menores de um template, como se fossem componentes.

Nesse exemplo vamos utilizar 3 arquivos, header.tmpl, body.tmpl e footer.tmpl, aqui está o conteúdo dos arquivos:

{{ define "Header" }}
Report: {{ .ReportName }} --- Year: {{ .ReportYear }}{{ "\n" }}
------------------------------------------------------------{{ "\n" }}
{{- end }}

Declaramos um novo template utilizando o marcador {{ define “TemplateName” }} e precisamos fechar o marcador com {{ end }}

{{ define "footer" -}}
------------------------------------------------------------{{ "\n" }}
Report User: {{ .ReportUser }}
{{ end }}

O template footer é bem similar ao header

Body

O template body é o que contém mais informações novas em relações aos outros templates.

{{ define "body" }}
{{ template "Header" . }}
{{- range .Users -}}
Name:{{ .Name }} LastName: {{ .LastName }}{{ "\n" }}
{{- end -}}
{{ template "footer" . }}
{{ end }}

Da mesma forma que declaramos os templates header e footer também precisamos declarar o template body

Podemos utilizar os templates criados anteriormente com a função template, seguida do nome do template que deseja utilizar.

Muita atenção ao . depois do nome do template, esse . não é obrigatório, mas com ele estamos passando os dados que foram enviados para o template body para o template header

Outra modificação é que a struct passada para o template agora é assim:

type Report struct {
	ReportName string
	ReportYear string
	ReportUser string
	Users      []User
}

type User struct {
	Name              string
	LastName          string
	Country           string
	Admin             bool
	YearsOfExperience int
}

Será passada a struct Report para o template, por isso o range é feito no campo Users

Esse é o nosso trecho de código que executa o template:

type Report struct {
	ReportName string
	ReportYear string
	ReportUser string
	Users      []User
}

type User struct {
	Name              string
	LastName          string
	Country           string
	Admin             bool
	YearsOfExperience int
}

func main() {
	tmplFiles := []string{"header.tmpl", "body.tmpl", "footer.tmpl"}

	users := []User{
		{"John", "Doe", "USA", true, 25},
		{"Gavin", "Steele", "USA", false, 3},
		{"Ashton", "Walsh", "CA", false, 5},
	}

	report := Report{
		ReportName: "Sales",
		ReportYear: "2025",
		ReportUser: "Goku",
		Users:      users,
	}

	tmpl, err := template.New("myReport").ParseFiles(tmplFiles...)
	if err != nil {
		panic(err)
	}

	err = tmpl.ExecuteTemplate(os.Stdout, "body", report)
	if err != nil {
		panic(err)
	}
}

Precisamos fazer o parse de todos os arquivos que referenciamos no template principal body

Agora vamos utilizar a função ExecuteTemplate passando a saída padrão, qual template deverá ser carrega já que fizemos o parse de 3 arquivos, e também temos que passar os dados que serão utilizados na execução.

Esse é o resultado:

Report: Sales --- Year: 2025

------------------------------------------------------------
Name:John LastName: Doe
Name:Gavin LastName: Steele
Name:Ashton LastName: Walsh
------------------------------------------------------------

Report User: Goku