feat: add category pages and per-category feeds to site builder
Extend the publishing pipeline to generate category index pages, per-category archive pages, per-category RSS/JSON feeds, and display categories on individual post pages and post lists. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4c2ce7272d
commit
6c69131b03
10 changed files with 329 additions and 61 deletions
|
|
@ -8,7 +8,7 @@ import (
|
|||
"lmika.dev/lmika/weiro/providers/db"
|
||||
)
|
||||
|
||||
// PostIter returns a post iterator which returns posts in reverse chronological order.
|
||||
// postIter returns a post iterator which returns posts in reverse chronological order.
|
||||
func (s *Publisher) postIter(ctx context.Context, site int64) iter.Seq[models.Maybe[*models.Post]] {
|
||||
return func(yield func(models.Maybe[*models.Post]) bool) {
|
||||
paging := db.PagingParams{Offset: 0, Limit: 50}
|
||||
|
|
@ -39,3 +39,26 @@ func (s *Publisher) postIter(ctx context.Context, site int64) iter.Seq[models.Ma
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// postIterByCategory returns a post iterator for posts in a specific category.
|
||||
func (s *Publisher) postIterByCategory(ctx context.Context, categoryID int64) iter.Seq[models.Maybe[*models.Post]] {
|
||||
return func(yield func(models.Maybe[*models.Post]) bool) {
|
||||
paging := db.PagingParams{Offset: 0, Limit: 50}
|
||||
for {
|
||||
page, err := s.db.SelectPostsOfCategory(ctx, categoryID, paging)
|
||||
if err != nil {
|
||||
yield(models.Maybe[*models.Post]{Err: err})
|
||||
return
|
||||
}
|
||||
if len(page) == 0 {
|
||||
return
|
||||
}
|
||||
for _, post := range page {
|
||||
if !yield(models.Maybe[*models.Post]{Value: post}) {
|
||||
return
|
||||
}
|
||||
}
|
||||
paging.Offset += paging.Limit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,24 @@ func (p *Publisher) Publish(ctx context.Context, site models.Site) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Fetch categories with counts
|
||||
cats, err := p.db.SelectCategoriesOfSite(ctx, site.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var catsWithCounts []models.CategoryWithCount
|
||||
for _, cat := range cats {
|
||||
count, err := p.db.CountPostsOfCategory(ctx, cat.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
catsWithCounts = append(catsWithCounts, models.CategoryWithCount{
|
||||
Category: *cat,
|
||||
PostCount: int(count),
|
||||
DescriptionBrief: models.BriefDescription(cat.Description),
|
||||
})
|
||||
}
|
||||
|
||||
for _, target := range targets {
|
||||
if !target.Enabled {
|
||||
continue
|
||||
|
|
@ -56,8 +74,15 @@ func (p *Publisher) Publish(ctx context.Context, site models.Site) error {
|
|||
PostIter: func(ctx context.Context) iter.Seq[models.Maybe[*models.Post]] {
|
||||
return p.postIter(ctx, site.ID)
|
||||
},
|
||||
BaseURL: target.BaseURL,
|
||||
Uploads: uploads,
|
||||
BaseURL: target.BaseURL,
|
||||
Uploads: uploads,
|
||||
Categories: catsWithCounts,
|
||||
PostIterByCategory: func(ctx context.Context, categoryID int64) iter.Seq[models.Maybe[*models.Post]] {
|
||||
return p.postIterByCategory(ctx, categoryID)
|
||||
},
|
||||
CategoriesOfPost: func(ctx context.Context, postID int64) ([]*models.Category, error) {
|
||||
return p.db.SelectCategoriesOfPost(ctx, postID)
|
||||
},
|
||||
OpenUpload: func(u models.Upload) (io.ReadCloser, error) {
|
||||
return p.up.OpenUpload(site, u)
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue