diff --git a/hugolib/pageSort.go b/hugolib/pageSort.go index c7766e2a6..454beb473 100644 --- a/hugolib/pageSort.go +++ b/hugolib/pageSort.go @@ -291,7 +291,6 @@ func (p Pages) Reverse() Pages { // Adjacent invocations on the same receiver with the same paramsKey will return a cached result. // // This may safely be executed in parallel. - func (p Pages) ByParam(paramsKey interface{}) Pages { paramsKeyStr := cast.ToString(paramsKey) key := "pageSort.ByParam." + paramsKeyStr @@ -299,16 +298,31 @@ func (p Pages) ByParam(paramsKey interface{}) Pages { paramsKeyComparator := func(p1, p2 *Page) bool { v1, _ := p1.Param(paramsKeyStr) v2, _ := p2.Param(paramsKeyStr) - s1 := cast.ToString(v1) - s2 := cast.ToString(v2) - // Sort nils last. - if s1 == "" { + if v1 == nil { return false - } else if s2 == "" { + } + + if v2 == nil { return true } + isNumeric := func(v interface{}) bool { + switch v.(type) { + case uint8, uint16, uint32, uint64, int, int8, int16, int32, int64, float32, float64: + return true + default: + return false + } + } + + if isNumeric(v1) && isNumeric(v2) { + return cast.ToFloat64(v1) < cast.ToFloat64(v2) + } + + s1 := cast.ToString(v1) + s2 := cast.ToString(v2) + return s1 < s2 } diff --git a/hugolib/pageSort_test.go b/hugolib/pageSort_test.go index 695045ff1..915947fd3 100644 --- a/hugolib/pageSort_test.go +++ b/hugolib/pageSort_test.go @@ -179,6 +179,49 @@ func TestPageSortByParam(t *testing.T) { assert.Equal(t, unsetValue, unsetSortedValue) } +func TestPageSortByParamNumeric(t *testing.T) { + t.Parallel() + var k interface{} = "arbitrarily.nested" + s := newTestSite(t) + + n := 10 + unsorted := createSortTestPages(s, n) + for i := 0; i < n; i++ { + v := 100 - i + if i%2 == 0 { + v = 100.0 - i + } + + unsorted[i].params = map[string]interface{}{ + "arbitrarily": map[string]interface{}{ + "nested": v, + }, + } + } + delete(unsorted[9].params, "arbitrarily") + + firstSetValue, _ := unsorted[0].Param(k) + secondSetValue, _ := unsorted[1].Param(k) + lastSetValue, _ := unsorted[8].Param(k) + unsetValue, _ := unsorted[9].Param(k) + + assert.Equal(t, 100, firstSetValue) + assert.Equal(t, 99, secondSetValue) + assert.Equal(t, 92, lastSetValue) + assert.Equal(t, nil, unsetValue) + + sorted := unsorted.ByParam("arbitrarily.nested") + firstSetSortedValue, _ := sorted[0].Param(k) + secondSetSortedValue, _ := sorted[1].Param(k) + lastSetSortedValue, _ := sorted[8].Param(k) + unsetSortedValue, _ := sorted[9].Param(k) + + assert.Equal(t, 92, firstSetSortedValue) + assert.Equal(t, 93, secondSetSortedValue) + assert.Equal(t, 100, lastSetSortedValue) + assert.Equal(t, unsetValue, unsetSortedValue) +} + func BenchmarkSortByWeightAndReverse(b *testing.B) { s := newTestSite(b) p := createSortTestPages(s, 300)