mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
hugolib: Add ability to sort by frontmatter parameters
This commit is contained in:
parent
2618cfbeaa
commit
298ebc37c2
3 changed files with 71 additions and 0 deletions
|
@ -237,6 +237,18 @@ your list templates:
|
|||
</li>
|
||||
{{ end }}
|
||||
|
||||
### Order by Parameter
|
||||
Order based on the specified frontmatter parameter. Pages without that
|
||||
parameter will use the site's `.Site.Params` default. If the parameter is not
|
||||
found at all in some entries, those entries will appear together at the end
|
||||
of the ordering.
|
||||
|
||||
The below example sorts a list of posts by their rating.
|
||||
|
||||
{{ range (.Data.Pages.ByParam "rating") }}
|
||||
<!-- ... -->
|
||||
{{ end }}
|
||||
|
||||
### Reverse Order
|
||||
Can be applied to any of the above. Using Date for an example.
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ package hugolib
|
|||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
var spc = newPageCache()
|
||||
|
@ -275,3 +277,28 @@ func (p Pages) Reverse() Pages {
|
|||
|
||||
return pages
|
||||
}
|
||||
|
||||
func (p Pages) ByParam(paramsKey interface{}) Pages {
|
||||
paramsKeyStr := cast.ToString(paramsKey)
|
||||
key := "pageSort.ByParam." + paramsKeyStr
|
||||
|
||||
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 == "" {
|
||||
return false
|
||||
} else if s2 == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return s1 < s2
|
||||
}
|
||||
|
||||
pages, _ := spc.get(key, p, pageBy(paramsKeyComparator).Sort)
|
||||
|
||||
return pages
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/source"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -113,6 +114,34 @@ func TestPageSortReverse(t *testing.T) {
|
|||
assert.True(t, probablyEqualPages(p2, p1.Reverse()))
|
||||
}
|
||||
|
||||
func TestPageSortByParam(t *testing.T) {
|
||||
var k interface{} = "arbitrary"
|
||||
|
||||
unsorted := createSortTestPages(10)
|
||||
delete(unsorted[9].Params, cast.ToString(k))
|
||||
|
||||
firstSetValue, _ := unsorted[0].Param(k)
|
||||
secondSetValue, _ := unsorted[1].Param(k)
|
||||
lastSetValue, _ := unsorted[8].Param(k)
|
||||
unsetValue, _ := unsorted[9].Param(k)
|
||||
|
||||
assert.Equal(t, "xyz100", firstSetValue)
|
||||
assert.Equal(t, "xyz99", secondSetValue)
|
||||
assert.Equal(t, "xyz92", lastSetValue)
|
||||
assert.Equal(t, nil, unsetValue)
|
||||
|
||||
sorted := unsorted.ByParam("arbitrary")
|
||||
firstSetSortedValue, _ := sorted[0].Param(k)
|
||||
secondSetSortedValue, _ := sorted[1].Param(k)
|
||||
lastSetSortedValue, _ := sorted[8].Param(k)
|
||||
unsetSortedValue, _ := sorted[9].Param(k)
|
||||
|
||||
assert.Equal(t, firstSetValue, firstSetSortedValue)
|
||||
assert.Equal(t, secondSetValue, lastSetSortedValue)
|
||||
assert.Equal(t, lastSetValue, secondSetSortedValue)
|
||||
assert.Equal(t, unsetValue, unsetSortedValue)
|
||||
}
|
||||
|
||||
func BenchmarkSortByWeightAndReverse(b *testing.B) {
|
||||
|
||||
p := createSortTestPages(300)
|
||||
|
@ -154,6 +183,9 @@ func createSortTestPages(num int) Pages {
|
|||
},
|
||||
Site: &info,
|
||||
Source: Source{File: *source.NewFile(filepath.FromSlash(fmt.Sprintf("/x/y/p%d.md", i)))},
|
||||
Params: map[string]interface{}{
|
||||
"arbitrary": "xyz" + fmt.Sprintf("%v", 100-i),
|
||||
},
|
||||
}
|
||||
w := 5
|
||||
|
||||
|
|
Loading…
Reference in a new issue