mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
Add nil comparison to where tpl function
`where` template function's internal condition check function always returns `false` when a target value doesn't exist or it's nil value but this behavior makes it difficult to filter values which doesn't have a particular parameter. To solve it, this adds nil value comparison to the function. `where Values ".Param.key" nil` like clause can be used for the case above. Only "=", "==", "eq", "!=", "<>", "ne" operators are allowed to be used with `nil`. If an other operator is passed with `nil`, the condition check function returns `false` like before. Fix #1232
This commit is contained in:
parent
033a13e10e
commit
dd732e84f4
2 changed files with 40 additions and 9 deletions
|
@ -536,17 +536,21 @@ func evaluateSubElem(obj reflect.Value, elemName string) (reflect.Value, error)
|
|||
}
|
||||
|
||||
func checkCondition(v, mv reflect.Value, op string) (bool, error) {
|
||||
if !v.IsValid() || !mv.IsValid() {
|
||||
return false, nil
|
||||
v, vIsNil := indirect(v)
|
||||
if !v.IsValid() {
|
||||
vIsNil = true
|
||||
}
|
||||
|
||||
var isNil bool
|
||||
v, isNil = indirect(v)
|
||||
if isNil {
|
||||
return false, nil
|
||||
mv, mvIsNil := indirect(mv)
|
||||
if !mv.IsValid() {
|
||||
mvIsNil = true
|
||||
}
|
||||
mv, isNil = indirect(mv)
|
||||
if isNil {
|
||||
if vIsNil || mvIsNil {
|
||||
switch op {
|
||||
case "", "=", "==", "eq":
|
||||
return vIsNil == mvIsNil, nil
|
||||
case "!=", "<>", "ne":
|
||||
return vIsNil != mvIsNil, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -673,6 +673,7 @@ func TestCheckCondition(t *testing.T) {
|
|||
"",
|
||||
expect{true, false},
|
||||
},
|
||||
{reflect.ValueOf(nil), reflect.ValueOf(nil), "", expect{true, false}},
|
||||
{reflect.ValueOf(123), reflect.ValueOf(456), "!=", expect{true, false}},
|
||||
{reflect.ValueOf("foo"), reflect.ValueOf("bar"), "!=", expect{true, false}},
|
||||
{
|
||||
|
@ -681,6 +682,7 @@ func TestCheckCondition(t *testing.T) {
|
|||
"!=",
|
||||
expect{true, false},
|
||||
},
|
||||
{reflect.ValueOf(123), reflect.ValueOf(nil), "!=", expect{true, false}},
|
||||
{reflect.ValueOf(456), reflect.ValueOf(123), ">=", expect{true, false}},
|
||||
{reflect.ValueOf("foo"), reflect.ValueOf("bar"), ">=", expect{true, false}},
|
||||
{
|
||||
|
@ -943,6 +945,31 @@ func TestWhere(t *testing.T) {
|
|||
{A: "a", B: "b"}, {A: "e", B: "f"},
|
||||
},
|
||||
},
|
||||
{
|
||||
sequence: []map[string]int{
|
||||
{"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
|
||||
},
|
||||
key: "b", op: "", match: nil,
|
||||
expect: []map[string]int{
|
||||
{"a": 3},
|
||||
},
|
||||
},
|
||||
{
|
||||
sequence: []map[string]int{
|
||||
{"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
|
||||
},
|
||||
key: "b", op: "!=", match: nil,
|
||||
expect: []map[string]int{
|
||||
{"a": 1, "b": 2}, {"a": 5, "b": 6},
|
||||
},
|
||||
},
|
||||
{
|
||||
sequence: []map[string]int{
|
||||
{"a": 1, "b": 2}, {"a": 3}, {"a": 5, "b": 6},
|
||||
},
|
||||
key: "b", op: ">", match: nil,
|
||||
expect: []map[string]int{},
|
||||
},
|
||||
{sequence: (*[]TstX)(nil), key: "A", match: "a", expect: false},
|
||||
{sequence: TstX{A: "a", B: "b"}, key: "A", match: "a", expect: false},
|
||||
{sequence: []map[string]*TstX{{"foo": nil}}, key: "foo.B", match: "d", expect: false},
|
||||
|
|
Loading…
Reference in a new issue