Paging #4
|
|
@ -5,4 +5,10 @@
|
|||
|
||||
{{ template "_post_meta.html" . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ if or .PrevURL .NextURL }}
|
||||
<nav class="pagination">
|
||||
{{ if .PrevURL }}<a href="{{ .PrevURL }}">← Newer posts</a>{{ end }}
|
||||
{{ if .NextURL }}<a href="{{ .NextURL }}">Older posts →</a>{{ end }}
|
||||
</nav>
|
||||
{{ end }}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ func (b *Builder) BuildSite(outDir string) error {
|
|||
}
|
||||
|
||||
func (b *Builder) renderPostListWithCategories(bctx buildContext, ctx context.Context) error {
|
||||
var posts []postSingleData
|
||||
// Collect all posts
|
||||
var allPosts []postSingleData
|
||||
for mp := range b.site.PostIter(ctx) {
|
||||
post, err := mp.Get()
|
||||
if err != nil {
|
||||
|
|
@ -132,17 +133,70 @@ func (b *Builder) renderPostListWithCategories(bctx buildContext, ctx context.Co
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
posts = append(posts, rp)
|
||||
allPosts = append(allPosts, rp)
|
||||
}
|
||||
|
||||
pl := postListData{
|
||||
commonData: commonData{Site: b.site},
|
||||
Posts: posts,
|
||||
postsPerPage := b.site.PostsPerPage
|
||||
if postsPerPage < 1 {
|
||||
postsPerPage = 10
|
||||
}
|
||||
|
||||
return b.createAtPath(bctx, "", func(f io.Writer) error {
|
||||
return b.renderTemplate(f, tmplNamePostList, pl)
|
||||
})
|
||||
totalPages := (len(allPosts) + postsPerPage - 1) / postsPerPage
|
||||
if totalPages < 1 {
|
||||
totalPages = 1
|
||||
}
|
||||
|
||||
for page := 1; page <= totalPages; page++ {
|
||||
start := (page - 1) * postsPerPage
|
||||
end := start + postsPerPage
|
||||
if end > len(allPosts) {
|
||||
end = len(allPosts)
|
||||
}
|
||||
|
||||
pageInfo := models.PageInfo{
|
||||
CurrentPage: page,
|
||||
TotalPages: totalPages,
|
||||
PostsPerPage: postsPerPage,
|
||||
}
|
||||
|
||||
var prevURL, nextURL string
|
||||
if page > 1 {
|
||||
if page == 2 {
|
||||
prevURL = "/posts/"
|
||||
} else {
|
||||
prevURL = fmt.Sprintf("/posts/page/%d/", page-1)
|
||||
}
|
||||
}
|
||||
if page < totalPages {
|
||||
nextURL = fmt.Sprintf("/posts/page/%d/", page+1)
|
||||
}
|
||||
|
||||
pl := postListData{
|
||||
commonData: commonData{Site: b.site},
|
||||
Posts: allPosts[start:end],
|
||||
PageInfo: pageInfo,
|
||||
PrevURL: prevURL,
|
||||
NextURL: nextURL,
|
||||
}
|
||||
|
||||
// Page 1 renders at both root and /posts/
|
||||
var paths []string
|
||||
if page == 1 {
|
||||
paths = []string{"", "/posts"}
|
||||
} else {
|
||||
paths = []string{fmt.Sprintf("/posts/page/%d", page)}
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
if err := b.createAtPath(bctx, path, func(f io.Writer) error {
|
||||
return b.renderTemplate(f, tmplNamePostList, pl)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Builder) renderFeeds(ctx buildContext, postIter iter.Seq[models.Maybe[*models.Post]], opts feedOptions) error {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ func TestBuilder_BuildSite(t *testing.T) {
|
|||
}
|
||||
|
||||
site := pubmodel.Site{
|
||||
Site: models.Site{PostsPerPage: 10},
|
||||
BaseURL: "https://example.com",
|
||||
PostIter: func(ctx context.Context) iter.Seq[models.Maybe[*models.Post]] {
|
||||
return func(yield func(models.Maybe[*models.Post]) bool) {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,10 @@ type postSingleData struct {
|
|||
|
||||
type postListData struct {
|
||||
commonData
|
||||
Posts []postSingleData
|
||||
Posts []postSingleData
|
||||
PageInfo models.PageInfo
|
||||
PrevURL string
|
||||
NextURL string
|
||||
}
|
||||
|
||||
type layoutData struct {
|
||||
|
|
|
|||
Loading…
Reference in a new issue