Templates 04 - Adicionando funções
Adicionando funções
Em algumas situações podemos precisar de funções que não existem no pacote template, para essas situações podemos mapear funções para dentro do template.
O primeiro exemplo será com a função Repeat do pacote strings
A função Repeat recebe dois parâmetros, o primeiro é uma string que será repetida, e o segundo é um inteiro que determina quantas vezes aquela string deverá ser repetida, exemplo:
func main() {
fmt.Print(strings.Repeat("-", 10))
}
----------
Podemos utilizar a função repeat dentro dos nossos templates da seguinte forma:
type Report struct {
ReportName string
ReportYear string
ReportUser string
ReportDivider string
Users []User
}
type User struct {
Name string
LastName string
Country string
Admin bool
YearsOfExperience int
}
func main() {
tmplFile := "addf.tmpl"
funcMap := template.FuncMap{
"repeat": strings.Repeat,
}
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",
ReportDivider: "*",
Users: users,
}
tmpl, err := template.New(tmplFile).Funcs(funcMap).ParseFiles(tmplFile)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, report)
if err != nil {
panic(err)
}
}
Nós temos que mapear as funções dessa forma:
funcMap := template.FuncMap{
"repeat": strings.Repeat,
}
E quando vamos parsear o arquivos nós vamos injetar as funções através da função Funcs
tmpl, err := template.New(tmplFile).Funcs(funcMap).ParseFiles(tmplFile)
Com as funções mapeadas para nosso template, já podemos utilizá-la:
Template addf.tmpl
{{ .ReportName }}
{{ repeat "-" 10 }}
Essa é a saída do nosso programa:
Sales
----------
Mapeamos a função Repeat com o nome repeat dentro do template.
Mas poderíamos ter mapeado a função Repeat como func01 por exemplo:
funcMap := template.FuncMap{
"func01": strings.Repeat,
}
{{ .ReportName }}
{{ func01 "-" 10 }}
Podemos criar a nossa própria função e mapeá-la para o template, exemplo:
func Greetings(name, prefix, suffix string) string {
return fmt.Sprintf("%s %s %s", prefix, name, suffix)
}
func main() {
tmplFile := "addf.tmpl"
funcMap := template.FuncMap{
"repeat": strings.Repeat,
"greetings": Greetings,
}
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",
ReportDivider: "*",
Users: users,
}
tmpl, err := template.New(tmplFile).Funcs(funcMap).ParseFiles(tmplFile)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, report)
if err != nil {
panic(err)
}
}
{{ .ReportName }}
{{ repeat "-" 10 }}
{{ greetings "Goku" "Hello" "!!!!!" }}
Esse é a saída do programa:
Sales
----------
Hello Goku !!!!!
Podemos utilizar os próprios campos através dos dados enviados para o template como entrada para as funções:
{{ .ReportName }}{{ "\n" }}
{{- range .Users -}}
{{ repeat $.ReportDivider 10 }}{{ "\n" }}
{{- greetings .Name "Hello" "!!!!!" }}{{ "\n" }}
{{- end -}}
Repare que acessamos o campo .ReportDivider com o símbolo $, isso é porque naquele ponto estamos dentro do range e queremos acessar um campo que está acima do slice, dessa forma conseguimos acessar o escopo principal.
Essa é a saída do programa:
Sales
**********
Hello John !!!!!
**********
Hello Gavin !!!!!
**********
Hello Ashton !!!!!