Go Template Nested Loop Space

Say we have some nested data:

var (
  data = map[string]map[string][]string{
    "1": {
      "1.1": {
        "1.1.1",
        "1.1.2",
        "1.1.3",
      },
    },
    "2": {
      "2.1": {
        "2.1.1",
        "2.1.2",
        "2.1.3",
      },
    },
  }
)

And we want to use a Go template to format it. The natural way is to write:

{{ range $name, $map := . }}
{{ $name }}:
  {{ range $name, $values := $map }}
  {{ $name }}:
    {{ range $value := $values }}
    {{ $value }}
    {{ end }}
  {{ end }}
{{ end }}

Unfortunately this results in extra spaces:



1:
  
  1.1:
    
    1.1.1
    
    1.1.2
    
    1.1.3
    
  

2:
  
  2.1:
    
    2.1.1
    
    2.1.2
    
    2.1.3
    
  

To correct the spaces we need to add “-” at exactly the right places:

{{- range $name, $map := . -}}
{{ $name }}:
  {{- range $name, $values := $map }}
  {{ $name }}:
    {{- range $value := $values }}
    {{ $value }}
    {{- end }}
  {{- end }}
{{ end -}}

This results in the desired output:

1:
  1.1:
    1.1.1
    1.1.2
    1.1.3
2:
  2.1:
    2.1.1
    2.1.2
    2.1.3

Full code:

package main

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

var (
  data = map[string]map[string][]string{
    "1": {
      "1.1": {
        "1.1.1",
        "1.1.2",
        "1.1.3",
      },
    },
    "2": {
      "2.1": {
        "2.1.1",
        "2.1.2",
        "2.1.3",
      },
    },
  }
)

func run(text string) {
  fmt.Printf("Template:\n%s\n", text)
  fmt.Printf("Output:\n\n'''\n")
  template.Must(
    template.New("run").Parse(text)
  ).Execute(os.Stdout, data)
  fmt.Printf("'''\n\n")
}

func main() {
  run(`
{{ range $name, $map := . }}
{{ $name }}:
  {{ range $name, $values := $map }}
  {{ $name }}:
    {{ range $value := $values }}
    {{ $value }}
    {{ end }}
  {{ end }}
{{ end }}
`)
  run(`
{{- range $name, $map := . -}}
{{ $name }}:
  {{- range $name, $values := $map }}
  {{ $name }}:
    {{- range $value := $values }}
    {{ $value }}
    {{- end }}
  {{- end }}
{{ end -}}
`)
}

Full output:

Template:

{{ range $name, $map := . }}
{{ $name }}:
  {{ range $name, $values := $map }}
  {{ $name }}:
    {{ range $value := $values }}
    {{ $value }}
    {{ end }}
  {{ end }}
{{ end }}

Output:

'''


1:
  
  1.1:
    
    1.1.1
    
    1.1.2
    
    1.1.3
    
  

2:
  
  2.1:
    
    2.1.1
    
    2.1.2
    
    2.1.3
    
  

'''

Template:

{{- range $name, $map := . -}}
{{ $name }}:
  {{- range $name, $values := $map }}
  {{ $name }}:
    {{- range $value := $values }}
    {{ $value }}
    {{- end }}
  {{- end }}
{{ end -}}

Output:

'''
1:
  1.1:
    1.1.1
    1.1.2
    1.1.3
2:
  2.1:
    2.1.1
    2.1.2
    2.1.3
'''

Click to try this in the Go Playground.

Subscribe to my mailing list and get a free email course

* indicates required

Interests



Updated on 2020 Dec 17.

DISCLAIMER: This is not professional advice. The ideas and opinions presented here are my own, not necessarily those of my employer.