Let's say you have a JSON value like { "Fruit": "apple" }
as your input before applying the template. I want to check that the value of "Fruit" is in a set of []string{"pear", "banana", "grape"}
and do something or not do something depending on whether the value is in the set.
So, input to template:
{ "fruit": "apple" }
Template (assume containsVal is a custom function we pass in to the template that accepts a string and a slice of strings):
{{ if containsVal .Fruit []string{"banana", "grape", "etc"} }}do stuff{{ end }}
It seems the templates don't allow string slice literals in them -- template fails to compile.
Apparently you can define a struct and pass that into .Execute(). Or I could hard-code my values in the containsVal
function.
But for my purpose, I want the values to be dynamic and in the template, not hard-coded in Go code. So someone else should be able to come along and have a different set of values to check against ("fig", "cherry", etc.) by updating the template text.
I've poked around https://pkg.go.dev/text/template and google and am not seeing any way to do this. I have only been able to do simple equality against simpler variables, like string == string in the templates.
Thanks.
CodePudding user response:
Use a template function map to add the functionality. Here's a map with the function:
var funcs = template.FuncMap{
// in returns true if needle is in haystack
"in": func(needle any, haystack ...any) bool {
for _, v := range haystack {
if needle == v {
return true
}
}
return false
},
}
The function uses a variadic argument to specify the set of strings to match.
Use it in a template like this:
t := template.Must(template.New("").Funcs(funcs).Parse(
`{{if in . "foo" "bar" -}}YES {{else}}NO {{end}}`))
t.Execute(os.Stdout, "foo") // prints YES
t.Execute(os.Stdout, "quux") // prints NO
Run the code on the playground.
CodePudding user response:
You should use "if" statement with "or" and "eq" operators like as:
tmplText := `
{{ if or (eq .Fruit "banana" "grape" "etc") }}
{{ .Fruit }} exists in the list
{{ else }}
{{ .Fruit }} doesn't exist in the list
{{ end }}
`
tmpl, err := template.New("").Parse(tmplText)
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, map[string]interface{}{
"Fruit": "apple",
})
if err != nil {
panic(err)
}