Iterando a través del mapa en la plantilla

94

Estoy tratando de mostrar una lista de clases de gimnasia (yoga, pilates, etc.). Para cada tipo de clase hay varias clases, así que quiero agrupar todas las clases de Yoga, y todas las clases de Pilates y así sucesivamente.

Hice esta función para tomar una porción y hacer un mapa de ella

func groupClasses(classes []entities.Class) map[string][]entities.Class {
    classMap := make(map[string][]entities.Class)
    for _, class := range classes {
        classMap[class.ClassType.Name] = append(classMap[class.ClassType.Name], class)
    }
    return classMap
}

El problema ahora es cómo puedo iterar a través de él, de acuerdo con http://golang.org/pkg/text/template/ , debe acceder a él en .Keyformato, no conozco las claves (a menos que también haya pasado un segmento de claves en la plantilla). ¿Cómo descomprimo este mapa en mi vista?

Todo lo que tengo actualmente es

{{ . }} 

que muestra algo como:

map[Pilates:[{102 PILATES ~/mobifit/video/ocen.mpg 169 40 2014-05-03 23:12:12 +0000 UTC 2014-05-03 23:12:12 +0000 UTC 1899-12-30 00:00:00 +0000 UTC {PILATES Pilates 1 2014-01-22 21:46:16 +0000 UTC} {1 [email protected] password SUPERADMIN Lee Brooks {Male true} {1990-07-11 00:00:00 +0000 UTC true} {1.85 true} {88 true} 2014-01-22 21:46:16 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false} {0001-01-01 00:00:00 +0000 UTC false} {0001-01-01 00:00:00 +0000 UTC false}} [{1 Mat 2014-01-22 21:46:16 +0000 UTC}]} {70 PILATES ~/mobifit/video/ocen.mpg 119 66 2014-03-31 15:12:12 +0000 UTC 2014-03-31 15:12:12 +0000 UTC 1899-12-30 00:00:00 +0000 UTC 
Sotavento
fuente

Respuestas:

171

Consulte la sección Variables en los documentos de plantilla de Go. Un rango puede declarar dos variables, separadas por una coma. Lo siguiente debería funcionar:

{{ range $key, $value := . }}
   <li><strong>{{ $key }}</strong>: {{ $value }}</li>
{{ end }}
Herman Schaaf
fuente
47

Como señaló Herman, puede obtener el índice y el elemento de cada iteración.

{{range $index, $element := .}}{{$index}}
{{range $element}}{{.Value}}
{{end}}
{{end}}

Ejemplo de trabajo:

package main

import (
    "html/template"
    "os"
)

type EntetiesClass struct {
    Name string
    Value int32
}

// In the template, we use rangeStruct to turn our struct values
// into a slice we can iterate over
var htmlTemplate = `{{range $index, $element := .}}{{$index}}
{{range $element}}{{.Value}}
{{end}}
{{end}}`

func main() {
    data := map[string][]EntetiesClass{
        "Yoga": {{"Yoga", 15}, {"Yoga", 51}},
        "Pilates": {{"Pilates", 3}, {"Pilates", 6}, {"Pilates", 9}},
    }

    t := template.New("t")
    t, err := t.Parse(htmlTemplate)
    if err != nil {
        panic(err)
    }

    err = t.Execute(os.Stdout, data)
    if err != nil {
        panic(err)
    }

}

Salida:

Pilates
3
6
9

Yoga
15
51

Zona de juegos: http://play.golang.org/p/4ISxcFKG7v

ANiso
fuente
Hola @ANisus, tengo el requisito de generar json a través de una plantilla como la siguiente, pero también tiene comas adicionales como en la matriz de direcciones en el ejemplo dado Salida `` `{" nombre ":" Mus "," direcciones ": [{" dirección ":" A "}, {" address ":" B "},]}` `` Ejemplo de enlace del código play.golang.org/p/nD08y0noPHv
Mohammad Mustaqeem
1
@MohammadMustaqeem Puede verificar el índice de cada iteración y no agregar una coma en la primera iteración. Ver ejemplo: play.golang.org/p/5544hc_0_g8 . Sólo sé cuidadoso. La representación de JSON con plantillas provocará problemas de escape. Vea la dirección "C&D" que agregué.
ANiso
Gracias. He resuelto el problema de escape importando "texto / plantilla" en lugar de "html / plantilla". play.golang.org/p/PXTNZGWx7Yi
Mohammad Mustaqeem
1
@MohammadMustaqeem Desafortunadamente, ahora puede obtener JSON no válido, o peor aún, JSON inyectado: play.golang.org/p/kd9bM_rpwyg . Usar una plantilla para generar json no es aconsejable, pero si tiene que hacerlo, escape los valores JSON con funciones como js (también en este ejemplo).
ANisus