mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Make Where template-method accept methodname as key
This is necessary to make constructs like `{{ range first 1 (where .Data.Pages "Type" "post") }}` -- as Type and Section is methods not fields.
This commit is contained in:
parent
fdae09070b
commit
8ad9c0a7dd
2 changed files with 37 additions and 9 deletions
|
@ -230,9 +230,14 @@ func Where(seq, key, match interface{}) (interface{}, error) {
|
|||
vvv = vv.MapIndex(kv)
|
||||
}
|
||||
case reflect.Struct:
|
||||
if kv.Kind() == reflect.String && vv.FieldByName(kv.String()).IsValid() {
|
||||
if kv.Kind() == reflect.String {
|
||||
method := vv.MethodByName(kv.String())
|
||||
if method.IsValid() && method.Type().NumIn() == 0 && method.Type().NumOut() > 0 {
|
||||
vvv = method.Call(nil)[0]
|
||||
} else if vv.FieldByName(kv.String()).IsValid() {
|
||||
vvv = vv.FieldByName(kv.String())
|
||||
}
|
||||
}
|
||||
case reflect.Ptr:
|
||||
if !vv.IsNil() {
|
||||
ev := vv.Elem()
|
||||
|
@ -242,12 +247,17 @@ func Where(seq, key, match interface{}) (interface{}, error) {
|
|||
vvv = ev.MapIndex(kv)
|
||||
}
|
||||
case reflect.Struct:
|
||||
if kv.Kind() == reflect.String && ev.FieldByName(kv.String()).IsValid() {
|
||||
if kv.Kind() == reflect.String {
|
||||
method := vv.MethodByName(kv.String())
|
||||
if method.IsValid() && method.Type().NumIn() == 0 && method.Type().NumOut() > 0 {
|
||||
vvv = method.Call(nil)[0]
|
||||
} else if ev.FieldByName(kv.String()).IsValid() {
|
||||
vvv = ev.FieldByName(kv.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if vvv.IsValid() && mv.Type() == vvv.Type() {
|
||||
switch mv.Kind() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package hugolib
|
||||
|
||||
import (
|
||||
"github.com/spf13/hugo/source"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
@ -296,10 +297,23 @@ func TestIntersect(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWhere(t *testing.T) {
|
||||
type X struct {
|
||||
func (x *TstX) TstRp() string {
|
||||
return "r" + x.A
|
||||
}
|
||||
|
||||
func (x TstX) TstRv() string {
|
||||
return "r" + x.B
|
||||
}
|
||||
|
||||
type TstX struct {
|
||||
A, B string
|
||||
}
|
||||
|
||||
func TestWhere(t *testing.T) {
|
||||
|
||||
page1 := &Page{contentType: "v", Source: Source{File: *source.NewFile("/x/y/z/source.md")}}
|
||||
page2 := &Page{contentType: "w", Source: Source{File: *source.NewFile("/y/z/a/source.md")}}
|
||||
|
||||
for i, this := range []struct {
|
||||
sequence interface{}
|
||||
key interface{}
|
||||
|
@ -308,9 +322,13 @@ func TestWhere(t *testing.T) {
|
|||
}{
|
||||
{[]map[int]string{{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"}}, 2, "m", []map[int]string{{1: "a", 2: "m"}}},
|
||||
{[]map[string]int{{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4}}, "b", 4, []map[string]int{{"a": 3, "b": 4}}},
|
||||
{[]X{{"a", "b"}, {"c", "d"}, {"e", "f"}}, "B", "f", []X{{"e", "f"}}},
|
||||
{[]TstX{{"a", "b"}, {"c", "d"}, {"e", "f"}}, "B", "f", []TstX{{"e", "f"}}},
|
||||
{[]*map[int]string{&map[int]string{1: "a", 2: "m"}, &map[int]string{1: "c", 2: "d"}, &map[int]string{1: "e", 3: "m"}}, 2, "m", []*map[int]string{&map[int]string{1: "a", 2: "m"}}},
|
||||
{[]*X{&X{"a", "b"}, &X{"c", "d"}, &X{"e", "f"}}, "B", "f", []*X{&X{"e", "f"}}},
|
||||
{[]*TstX{&TstX{"a", "b"}, &TstX{"c", "d"}, &TstX{"e", "f"}}, "B", "f", []*TstX{&TstX{"e", "f"}}},
|
||||
{[]*TstX{&TstX{"a", "b"}, &TstX{"c", "d"}, &TstX{"e", "c"}}, "TstRp", "rc", []*TstX{&TstX{"c", "d"}}},
|
||||
{[]TstX{TstX{"a", "b"}, TstX{"c", "d"}, TstX{"e", "c"}}, "TstRv", "rc", []TstX{TstX{"e", "c"}}},
|
||||
{[]*Page{page1, page2}, "Type", "v", []*Page{page1}},
|
||||
{[]*Page{page1, page2}, "Section", "y", []*Page{page2}},
|
||||
} {
|
||||
results, err := Where(this.sequence, this.key, this.match)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue