hugolib: Allow creating page groups from any page collection
authorVincent Danjean <vdanjean@users.noreply.github.com>
Sat, 8 Sep 2018 09:14:09 +0000 (11:14 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sat, 8 Sep 2018 09:14:09 +0000 (11:14 +0200)
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

hugolib/pageGroup.go
hugolib/pagination.go

index 8aaa1018c9483db45d5b67f31bd3298e654c3ee5..f12eff25313864c5674638fdc60f9d98803c698e 100644 (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
+}
index 58cec576b9b9f47c941b50b7b8b75674a5472cd9..9a9b10c4894c5b3f9b82f26192318bf9197c2a91 100644 (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: