mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-29 04:22:06 -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)
|
vvv = vv.MapIndex(kv)
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
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())
|
vvv = vv.FieldByName(kv.String())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
if !vv.IsNil() {
|
if !vv.IsNil() {
|
||||||
ev := vv.Elem()
|
ev := vv.Elem()
|
||||||
|
@ -242,12 +247,17 @@ func Where(seq, key, match interface{}) (interface{}, error) {
|
||||||
vvv = ev.MapIndex(kv)
|
vvv = ev.MapIndex(kv)
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
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())
|
vvv = ev.FieldByName(kv.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if vvv.IsValid() && mv.Type() == vvv.Type() {
|
if vvv.IsValid() && mv.Type() == vvv.Type() {
|
||||||
switch mv.Kind() {
|
switch mv.Kind() {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package hugolib
|
package hugolib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/spf13/hugo/source"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -296,10 +297,23 @@ func TestIntersect(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWhere(t *testing.T) {
|
func (x *TstX) TstRp() string {
|
||||||
type X struct {
|
return "r" + x.A
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x TstX) TstRv() string {
|
||||||
|
return "r" + x.B
|
||||||
|
}
|
||||||
|
|
||||||
|
type TstX struct {
|
||||||
A, B string
|
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 {
|
for i, this := range []struct {
|
||||||
sequence interface{}
|
sequence interface{}
|
||||||
key 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[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}}},
|
{[]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"}}},
|
{[]*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)
|
results, err := Where(this.sequence, this.key, this.match)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue