Go text/template templates: how to check value against an array of values within the template itself?

Viewed 65

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.

1 Answers

You should use "if" statement with "or" and "eq" operators like as:

    tmplText := `
    {{ if 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)
    }
Related