tpl/collections: Add group template func

This extends the page grouping in Hugo with a template function that allows for ad-hoc grouping.

A made-up example:

```
{{ $cool := where .Site.RegularPages "Params.cool" true | group "cool" }}
{{ $blue := where .Site.RegularPages "Params.blue" true | group "blue" }}
{{ $paginator := .Paginate (slice $cool $blue) }}
```

Closes #4865
This commit is contained in:
Bjørn Erik Pedersen
2018-09-08 13:00:36 +02:00
parent cfda13b363
commit 6667c6d743
8 changed files with 130 additions and 5 deletions

View File

@@ -23,6 +23,7 @@ import (
"strings"
"time"
"github.com/gohugoio/hugo/common/collections"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/deps"
@@ -311,6 +312,30 @@ func (ns *Namespace) Intersect(l1, l2 interface{}) (interface{}, error) {
}
}
// Group groups a set of elements by the given key.
// This is currently only supported for Pages.
func (ns *Namespace) Group(key interface{}, items interface{}) (interface{}, error) {
if key == nil {
return nil, errors.New("nil is not a valid key to group by")
}
tp := reflect.TypeOf(items)
switch tp.Kind() {
case reflect.Array, reflect.Slice:
tp = tp.Elem()
if tp.Kind() == reflect.Ptr {
tp = tp.Elem()
}
in := reflect.Zero(tp).Interface()
switch vv := in.(type) {
case collections.Grouper:
return vv.Group(key, items)
}
}
return nil, fmt.Errorf("grouping not supported for type %T", items)
}
// IsSet returns whether a given array, channel, slice, or map has a key
// defined.
func (ns *Namespace) IsSet(a interface{}, key interface{}) (bool, error) {