J'ai cette structure:
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
}
Je souhaite afficher mes paragraphes de manière dépendante de Type
.
La seule solution que j'ai trouvée était basée sur des fonctions dédiées comme isAttachment
tester le Type
dans Go et imbriqué {{if}}
:
{{range .Paragraphs}}
{{if .IsAttachment}}
-- attachement presentation code --
{{else}}{{if .IsMenu}}
-- menu --
{{else}}
-- default code --
{{end}}{{end}}
{{end}}
En fait, j'ai plus de types, ce qui le rend encore plus étrange, encombrant à la fois le code Go avec les fonctions IsSomething
et le modèle avec ces {{end}}
.
Quelle est la solution propre? Y a-t-il switch
ou if/elseif/else
solution dans les modèles go? Ou une manière complètement différente de gérer ces cas?
Les modèles sont sans logique. Ils ne sont pas censés avoir ce genre de logique. La logique maximale que vous pouvez avoir est un tas de if
.
Dans un tel cas, vous êtes censé le faire comme ceci:
{{if .IsAttachment}}
-- attachment presentation code --
{{end}}
{{if .IsMenu}}
-- menu --
{{end}}
{{if .IsDefault}}
-- default code --
{{end}}
Oui, vous pouvez utiliser {{else if .IsMenu}}
Vous pouvez obtenir la fonctionnalité switch
en ajoutant des fonctions personnalisées à template.FuncMap .
Dans l'exemple ci-dessous, j'ai défini une fonction, printPara (paratype int) string
qui prend l'un de vos types de paragraphe définis et modifie sa sortie en conséquence.
Veuillez noter que, dans le modèle actuel, le .Paratype
est canalisé dans la fonction printpara
. Voici comment passer des paramètres dans les modèles. Veuillez noter qu'il existe des restrictions sur le nombre et la forme des paramètres de sortie pour les fonctions ajoutées aux FuncMap
s. Cette page a quelques bonnes informations, ainsi que le premier lien.
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)
}
}
}
Produit:
Ceci est une hypothèse
Ceci est une pièce jointe
Menu
1:
2:
3:Choisissez n'importe quelle option:
J'espère que cela aide, je suis presque sûr que le code pourrait être nettoyé un peu, mais j'ai essayé de rester proche de l'exemple de code que vous avez fourni.