Переключить или if/elseif/else внутри golang HTML-шаблоны
У меня есть эта структура:
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
}
Я хочу отображать мои абзацы зависимым образом Type
.
Единственное найденное мной решение было основано на специальных функциях, таких как isAttachment
тестирование Type
в Go и вложенных {{if}}
:
{{range .Paragraphs}}
{{if .IsAttachment}}
-- attachement presentation code --
{{else}}{{if .IsMenu}}
-- menu --
{{else}}
-- default code --
{{end}}{{end}}
{{end}}
На самом деле у меня больше типов, что делает его еще более странным, загромождая как код Go с IsSomething
функциями, так и шаблон с этими {{end}}
.
Какое чистое решение? Есть ли решение switch
или if/elseif/else
в шаблонах go? Или совсем другой способ справиться с этими случаями?
Ответы
Ответ 1
Шаблоны не имеют логики. У них не должно быть такой логики. Максимальная логика, которую вы можете получить, - это куча if
.
В таком случае вы должны сделать это следующим образом:
{{if .IsAttachment}}
-- attachment presentation code --
{{end}}
{{if .IsMenu}}
-- menu --
{{end}}
{{if .IsDefault}}
-- default code --
{{end}}
Ответ 2
Вы можете достичь функциональности switch
, добавив пользовательские функции в template.FuncMap.
В приведенном ниже примере я определил функцию printPara (paratype int) string
, которая берет один из ваших определенных типов абзацев и соответственно меняет его.
Обратите внимание, что в фактическом шаблоне .Paratype
передается в функцию printpara
. Вот как передать параметры в шаблонах. Обратите внимание, что существуют ограничения на количество и форму выходных параметров для функций, добавленных в FuncMap
s. Эта страница содержит некоторую полезную информацию, а также первую ссылку.
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)
}
}
}
Выдает:
Это гипотеза
Это вложение
Меню
1:
2:
3:
Выберите любую опцию:
Игровая площадка
Надеюсь, что это поможет, я уверен, что код можно немного очистить, но я старался оставаться рядом с примером кода, который вы предоставили.