Variables

The template package allows you to define and use variables. As motivation for this, consider how we might print each person’s email address prefixed by their name. The type we use is again

  1. type Person struct {
  2. Name string
  3. Emails []string
  4. }

To access the email strings, we use a range statement such as

  1. {{range .Emails}}
  2. {{.}}
  3. {{end}}

But at that point we cannot access the Name field as '.' is now traversing the array elements and the Name is outside of this scope. The solution is to save the value of the Name field in a variable that can be accessed anywhere in its scope. Variables in templates are prefixed by '$'. So we write

  1. {{$name := .Name}}
  2. {{range .Emails}}
  3. Name is {{$name}}, email is {{.}}
  4. {{end}}

The program is

  1. /**
  2. * PrintNameEmails
  3. */
  4. package main
  5. import (
  6. "html/template"
  7. "os"
  8. "fmt"
  9. )
  10. type Person struct {
  11. Name string
  12. Emails []string
  13. }
  14. const templ = `{{$name := .Name}}
  15. {{range .Emails}}
  16. Name is {{$name}}, email is {{.}}
  17. {{end}}
  18. `
  19. func main() {
  20. person := Person{
  21. Name: "jan",
  22. Emails: []string{"jan@newmarch.name", "jan.newmarch@gmail.com"},
  23. }
  24. t := template.New("Person template")
  25. t, err := t.Parse(templ)
  26. checkError(err)
  27. err = t.Execute(os.Stdout, person)
  28. checkError(err)
  29. }
  30. func checkError(err error) {
  31. if err != nil {
  32. fmt.Println("Fatal error ", err.Error())
  33. os.Exit(1)
  34. }
  35. }

with output

  1. Name is jan, email is jan@newmarch.name
  2. Name is jan, email is jan.newmarch@gmail.com