template golang conditions html templates go go-templates

conditions - Cambie o si/elseif/else dentro de las plantillas HTML de Golang



golang template conditions (3)

Tengo esta estructura

const ( paragraph_hypothesis = 1<<iota paragraph_attachment = 1<<iota paragraph_menu = 1<<iota ) type Paragraph struct { Type int // paragraph_hypothesis or paragraph_attachment or paragraph_menu }

Quiero mostrar mis párrafos de forma dependiente del tipo.

La única solución que encontré estaba basada en funciones dedicadas como isAttachment probando el Type en Ir y anidado {{if}} :

{{range .Paragraphs}} {{if .IsAttachment}} -- attachement presentation code -- {{else}}{{if .IsMenu}} -- menu -- {{else}} -- default code -- {{end}}{{end}} {{end}}

De hecho, tengo más tipos, lo que lo hace aún más extraño, saturando tanto el código Go con IsSomething funciones de IsSomething como la plantilla con esas {{end}} .

¿Cuál es la solución limpia? ¿Hay algún switch o la solución if/elseif/else en plantillas go? ¿O una forma completamente diferente de manejar estos casos?


Las plantillas no tienen lógica. Se supone que no tienen este tipo de lógica. La lógica máxima que puedes tener es un montón de if .

En tal caso, se supone que debes hacerlo así:

{{if .IsAttachment}} -- attachment presentation code -- {{end}} {{if .IsMenu}} -- menu -- {{end}} {{if .IsDefault}} -- default code -- {{end}}


Puede lograr la funcionalidad de switch agregando funciones personalizadas a la template.FuncMap .

En el siguiente ejemplo, he definido una función, printPara (paratype int) string que toma uno de sus tipos de párrafos definidos y cambia su salida en consecuencia.

Tenga en cuenta que, en la plantilla real, el .Paratype se canaliza a la función printpara . Así es como pasar parámetros en plantillas. Tenga en cuenta que existen restricciones en el número y la forma de los parámetros de salida para las funciones agregadas a FuncMap s. Esta página tiene una buena información, así como el primer enlace.

package main import ( "fmt" "os" "html/template" ) func main() { const ( paragraph_hypothesis = 1 << iota paragraph_attachment = 1 << iota paragraph_menu = 1 << iota ) const text = "{{.Paratype | printpara}}/n" // A simple test template type Paragraph struct { Paratype int } var paralist = []*Paragraph{ &Paragraph{paragraph_hypothesis}, &Paragraph{paragraph_attachment}, &Paragraph{paragraph_menu}, } t := template.New("testparagraphs") printPara := func(paratype int) string { text := "" switch paratype { case paragraph_hypothesis: text = "This is a hypothesis/n" case paragraph_attachment: text = "This is an attachment/n" case paragraph_menu: text = "Menu/n1:/n2:/n3:/n/nPick any option:/n" } return text } template.Must(t.Funcs(template.FuncMap{"printpara": printPara}).Parse(text)) for _, p := range paralist { err := t.Execute(os.Stdout, p) if err != nil { fmt.Println("executing template:", err) } } }

Produce:

Esta es una hipótesis

Este es un archivo adjunto

Menú
1:
2:
3:

Elija cualquier opción:

Enlace de parque infantil

Espero que eso ayude, estoy bastante seguro de que el código se puede limpiar un poco, pero he tratado de mantenerme cerca del código de ejemplo que proporcionaste.


Sí, puedes usar {{else if .IsMenu}}