diff --git a/lookup.go b/lookup.go index 763e8e8..860eab8 100644 --- a/lookup.go +++ b/lookup.go @@ -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. @@ -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. diff --git a/lookup_test.go b/lookup_test.go index eb58628..d5f5906 100644 --- a/lookup_test.go +++ b/lookup_test.go @@ -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 @@ -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}, }, }, {