Field detection in Go HTML template
Asked Answered
S

1

5

Is it possible to check if a struct field exists from within a Go HTML template?

For example, given the following template:

{{if .FieldA}}
    <a>{{.FieldA}}</a>
{{end}

and structs defined as:

type MyStruct struct{  
    var FieldA string
    var FieldB string
}
// In this struct FieldA is unavailable
type MyStruct2 struct{  
    var FieldB string
}

Passing MyStruct into the template will work fine. However, passing MyStruct2 into the template will result in error. While the if statement can check for nil values, it throws an error (killing the template executor) when it encounters a field which doesn't exist in the current struct.

Sometimes a particular field is only going to be available in certain structs, so is there a way to check if the field exists prior to attempting to access it?

I've had no luck with the official documentation and have come to the conclusion that perhaps there is no elegant solution.

Shari answered 10/1, 2016 at 7:29 Comment(0)
R
18

There's not a built-in way to check for the presence of a field, but it is possible to write a template function to do the check:

func hasField(v interface{}, name string) bool {
  rv := reflect.ValueOf(v)
  if rv.Kind() == reflect.Ptr {
    rv = rv.Elem()
  }
  if rv.Kind() != reflect.Struct {
    return false
  }
  return rv.FieldByName(name).IsValid()
}

Use the function in a template like this:

{{if hasField . "FieldA"}}<a>{{.FieldA}}</a>{{end}}

Create the template with hasField in the func map:

 t := template.New("").Funcs(template.FuncMap{"hasField": hasField}).Parse(d)

playground example

Ragan answered 10/1, 2016 at 7:47 Comment(1)
A very nice solution. Thank you! I was unaware you could actually register your own functions like that.Shari

© 2022 - 2024 — McMap. All rights reserved.