-
Notifications
You must be signed in to change notification settings - Fork 1
Paginating Children
Stuart George edited this page Jan 17, 2025
·
9 revisions
Currently the children are just listed out to the page. You may want to use pagination.
Create a generic paginator struct to show a subset of the pages children.
We will keep it generic so that we can use it in other cases. If you dont want this, use []Relation as the type for Items:
type Paginator[T any] struct {
Items []T
PageNum int
PageSize int
}
func (p *Paginator[T]) Results() []T {
start := int((p.PageNum - 1) * p.PageSize)
if start >= len(p.Items) || start < 0 {
return []T{}
}
end := start + p.PageSize
if end > len(p.Items) {
end = len(p.Items)
}
return p.Items[start:end]
}
func (p *Paginator[T]) TotalPages() int {
return int(math.Ceil(float64(len(p.Items)) / float64(p.PageSize)))
}
func (p *Paginator[T]) HasNext() bool {
return p.PageNum < p.TotalPages()
}
func (p *Paginator[T]) HasPrev() bool {
return p.PageNum > 1
}Update the ui.pages.PageTypeListing struct and its body func to use the new paginator:
type PageTypeListing struct {
PageNum int
PageSize int
}templ (t *PageTypeListing) Body(page *Page) {
{{ paginator := Paginator[Relation]{page.Children, t.PageNum, t.PageSize} }}
<body class="bg-white text-black flex min-h-screen flex-col antialiased space-y-10">
@page.Header()
<main class="container mx-auto px-6 flex-grow">
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
for _, child := range paginator.Results() {
<a class="space-y-3" href={ templ.URL(child.Url) }>
<img class="w-full" src={ child.FeaturedImage } alt={ child.Title }/>
<div class="text-xl font-semibold tracking-tight">{ child.Title }</div>
<div>{ child.Meta.Description }</div>
</a>
}
</div>
</main>
if paginator.TotalPages() > 1 {
<section class="container mx-auto px-6 flex">
if paginator.HasPrev() {
<a class="mr-auto" href={ templ.URL(fmt.Sprintf("?page=%d", t.PageNum-1)) }>Prev</a>
}
if paginator.HasNext() {
<a class="ml-auto" href={ templ.URL(fmt.Sprintf("?page=%d", t.PageNum+1)) }>Next</a>
}
</section>
}
@page.Footer()
</body>
}Finally update the handler func to pass the query params to use the paginator:
func handleGenericPageListing(c echo.Context, queries *dbx.Queries, page *dbx.Page) (pages.PageType, error) {
pageStr := c.QueryParam("page")
pageNum, err := strconv.Atoi(pageStr)
if err != nil || pageNum < 1 {
pageNum = 1
}
return &pages.PageTypeListing{
PageNum: pageNum,
PageSize: 3,
}, nil
}