Подтвердить что ты не робот

Переключить или 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? Или совсем другой способ справиться с этими случаями?

4b9b3361

Ответ 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:

Выберите любую опцию:

Игровая площадка

Надеюсь, что это поможет, я уверен, что код можно немного очистить, но я старался оставаться рядом с примером кода, который вы предоставили.