URI: 
       Support numeric sort in ByParam - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 26f75edb7a76c816349749a05edf98fb36dc338a
   DIR parent e1a66c7343db9d232749255dd9e3a58d94b86997
  HTML Author: Anton Harniakou <anton.harniakou@gmail.com>
       Date:   Tue, 15 Jan 2019 15:41:54 +0300
       
       Support numeric sort in ByParam
       
       With this commit ByParam takes into account a type of a value under a
       key. If both values are numeric then they're coerced into float64 and
       then get compared.
       If any value isn't numeric, for example it's nil or string, then both
       values coerced into string and get compared as strings
       (lexicographicaly)
       
       Nil values are always sent to the end.
       
       Numeric values confirm to any type listed below:
       uint8, uint16, uint32, uint64, int, int8, int16, int32, int64, float32, float64
       
       Closes #5305
       
       Diffstat:
         M hugolib/pageSort.go                 |      26 ++++++++++++++++++++------
         M hugolib/pageSort_test.go            |      43 ++++++++++++++++++++++++++++++
       
       2 files changed, 63 insertions(+), 6 deletions(-)
       ---
   DIR diff --git 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
                }
        
   DIR diff --git 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)