hugolib: Allow creating page groups from any page collection

This also adjusts the pagination logic to allow for these new collections.

Note that we will follow up with a template function named `group` that will be the end user API. The `.Group` method on `Page` should be considered as internal.

Updates #4865
This commit is contained in:
Vincent Danjean 2018-09-08 11:14:09 +02:00 committed by Bjørn Erik Pedersen
parent bb2fe814c2
commit cfda13b363
2 changed files with 44 additions and 1 deletions

View file

@ -296,3 +296,10 @@ func (p Pages) GroupByParamDate(key string, format string, order ...string) (Pag
}
return p.groupByDateField(sorter, formatter, order...)
}
// Group creates a PageGroup from a key and a Pages object
func (p *Page) Group(key interface{}, pages Pages) (PageGroup, error) {
pageGroup := PageGroup{Key: key, Pages: pages}
return pageGroup, nil
}

View file

@ -399,7 +399,11 @@ func paginatePages(td targetPathDescriptor, seq interface{}, pagerSize int) (pag
var paginator *paginator
if groups, ok := seq.(PagesGroup); ok {
groups, err := toPagesGroup(seq)
if err != nil {
return nil, err
}
if groups != nil {
paginator, _ = newPaginatorFromPageGroups(groups, pagerSize, urlFactory)
} else {
pages, err := toPages(seq)
@ -414,6 +418,36 @@ func paginatePages(td targetPathDescriptor, seq interface{}, pagerSize int) (pag
return pagers, nil
}
func toPagesGroup(seq interface{}) (PagesGroup, error) {
switch v := seq.(type) {
case nil:
return nil, nil
case PagesGroup:
return v, nil
case []PageGroup:
return PagesGroup(v), nil
case []interface{}:
l := len(v)
if l == 0 {
break
}
switch v[0].(type) {
case PageGroup:
pagesGroup := make(PagesGroup, l)
for i, ipg := range v {
if pg, ok := ipg.(PageGroup); ok {
pagesGroup[i] = pg
} else {
return nil, fmt.Errorf("unsupported type in paginate from slice, got %T instead of PageGroup", ipg)
}
}
return PagesGroup(pagesGroup), nil
}
}
return nil, nil
}
func toPages(seq interface{}) (Pages, error) {
if seq == nil {
return Pages{}, nil
@ -424,6 +458,8 @@ func toPages(seq interface{}) (Pages, error) {
return seq.(Pages), nil
case *Pages:
return *(seq.(*Pages)), nil
case []*Page:
return Pages(seq.([]*Page)), nil
case WeightedPages:
return (seq.(WeightedPages)).Pages(), nil
case PageGroup: