page__paginator.go (2664B)
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package hugolib
15
16 import (
17 "sync"
18
19 "github.com/gohugoio/hugo/resources/page"
20 )
21
22 func newPagePaginator(source *pageState) *pagePaginator {
23 return &pagePaginator{
24 source: source,
25 pagePaginatorInit: &pagePaginatorInit{},
26 }
27 }
28
29 type pagePaginator struct {
30 *pagePaginatorInit
31 source *pageState
32 }
33
34 type pagePaginatorInit struct {
35 init sync.Once
36 current *page.Pager
37 rev bool
38 }
39
40 // reset resets the paginator to allow for a rebuild.
41 func (p *pagePaginator) reset() {
42 p.pagePaginatorInit = &pagePaginatorInit{}
43 }
44
45 func (p *pagePaginator) Paginate(seq any, options ...any) (*page.Pager, error) {
46 var initErr error
47 p.init.Do(func() {
48 pagerSize, rev, err := page.ResolvePagerSize(p.source.s.Cfg, options...)
49 if err != nil {
50 initErr = err
51 return
52 }
53
54 pd := p.source.targetPathDescriptor
55 pd.Type = p.source.outputFormat()
56 paginator, err := page.Paginate(pd, seq, pagerSize, rev)
57 if err != nil {
58 initErr = err
59 return
60 }
61
62 p.current = paginator.Pagers()[0]
63 p.rev = rev
64 })
65
66 if initErr != nil {
67 return nil, initErr
68 }
69
70 return p.current, nil
71 }
72
73 func (p *pagePaginator) Paginator(options ...any) (*page.Pager, error) {
74 var initErr error
75 p.init.Do(func() {
76 pagerSize, rev, err := page.ResolvePagerSize(p.source.s.Cfg, options...)
77 if err != nil {
78 initErr = err
79 return
80 }
81
82 pd := p.source.targetPathDescriptor
83 pd.Type = p.source.outputFormat()
84
85 var pages page.Pages
86
87 switch p.source.Kind() {
88 case page.KindHome:
89 // From Hugo 0.57 we made home.Pages() work like any other
90 // section. To avoid the default paginators for the home page
91 // changing in the wild, we make this a special case.
92 pages = p.source.s.RegularPages()
93 case page.KindTerm, page.KindTaxonomy:
94 pages = p.source.Pages()
95 default:
96 pages = p.source.RegularPages()
97 }
98
99 paginator, err := page.Paginate(pd, pages, pagerSize, rev)
100 if err != nil {
101 initErr = err
102 return
103 }
104
105 p.current = paginator.Pagers()[0]
106 p.rev = rev
107 })
108
109 if initErr != nil {
110 return nil, initErr
111 }
112
113 return p.current, nil
114 }