Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,14 @@ func lookup(name string, context ...interface{}) (interface{}, bool) {
// struct that matches the name. In the near future I'd like to add
// support for matching struct names to tags so we can use lower_case
// names in our templates which makes it more mustache like.
case reflect.Ptr:
reflectValue = reflectValue.Elem()
fallthrough
case reflect.Struct:
field := reflectValue.FieldByName(name)
if field.IsValid() {
return field.Interface(), truth(field)
result, isTrue := lookupStructByName(reflectValue, name)
if result != nil {
return result, isTrue
}
method := reflectValue.MethodByName(name)
if method.IsValid() && method.Type().NumIn() == 1 {
out := method.Call(nil)[0]
return out.Interface(), truth(out)
}

}
// If by this point no value was matched, we'll move up a step in the
// chain and try to match a value there.
Expand All @@ -63,6 +60,21 @@ func lookup(name string, context ...interface{}) (interface{}, bool) {
return nil, false
}

// lookupStructByName will return the field or the method result with the given name.
// Returns nil, false if no such field or method.
func lookupStructByName(reflectValue reflect.Value, name string) (interface{}, bool) {
field := reflectValue.FieldByName(name)
if field.IsValid() {
return field.Interface(), truth(field)
}
method := reflectValue.MethodByName(name)
if method.IsValid() && method.Type().NumIn() == 1 {
out := method.Call(nil)[0]
return out.Interface(), truth(out)
}
return nil, false
}

// The truth function will tell us if r is a truthy value or not. This is
// important for sections as they will render their content based on the output
// of this function.
Expand Down
8 changes: 8 additions & 0 deletions lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ func TestSimpleLookup(t *testing.T) {
"map": map[string]interface{}{
"in": "I'm nested!",
},
"ptr": &struct {
Foo *struct{ Bar string }
}{
Foo: &struct{ Bar string }{
Bar: "bar",
},
},
},
assertions: []struct {
name string
Expand All @@ -34,6 +41,7 @@ func TestSimpleLookup(t *testing.T) {
{"string", "abc", true},
{"boolean", true, true},
{"map.in", "I'm nested!", true},
{"ptr.Foo.Bar", "bar", true},
},
},
{
Expand Down