From 49630682783c74bb74efc13e5261bdb1d22b253a Mon Sep 17 00:00:00 2001 From: Dawid Rycerz Date: Fri, 30 Jan 2026 23:10:01 +0100 Subject: feat(tags): replace pagination with year-grouped single page Remove pagination from tag pages and show all posts on one page. Tags with >20 posts group entries by year with headers matching the main posts page style. Tags with <=20 posts keep a flat list. Co-Authored-By: Claude Opus 4.5 --- src/pages/tags/[tag]/[...page].astro | 99 ------------------------------------ src/pages/tags/[tag]/index.astro | 95 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 99 deletions(-) delete mode 100644 src/pages/tags/[tag]/[...page].astro create mode 100644 src/pages/tags/[tag]/index.astro (limited to 'src') diff --git a/src/pages/tags/[tag]/[...page].astro b/src/pages/tags/[tag]/[...page].astro deleted file mode 100644 index 8ae9716..0000000 --- a/src/pages/tags/[tag]/[...page].astro +++ /dev/null @@ -1,99 +0,0 @@ ---- -import { render } from "astro:content"; -import type { GetStaticPaths, InferGetStaticPropsType } from "astro"; -import { Icon } from "astro-icon/components"; -import PostPreview from "@/components/blog/PostPreview.astro"; -import Pagination from "@/components/Paginator.astro"; -import { getAllPosts, getTagMeta, getUniqueTags } from "@/data/post"; -import PageLayout from "@/layouts/Base.astro"; -import { collectionDateSort } from "@/utils/date"; - -export const getStaticPaths = (async ({ paginate }) => { - const allPosts = await getAllPosts(true); // Include archived posts (now includes pleroma too) - - // Get unique tags from all posts - const allTags = getUniqueTags(allPosts); - - return allTags.flatMap((tag) => { - // Filter posts by tag - const postsWithTag = allPosts.filter((post) => post.data.tags.includes(tag)); - - // Sort chronologically - const sortedPosts = postsWithTag.sort(collectionDateSort); - - return paginate(sortedPosts, { - pageSize: 10, - params: { tag }, - }); - }); -}) satisfies GetStaticPaths; - -type Props = InferGetStaticPropsType; - -const { page } = Astro.props as Props; -const { tag } = Astro.params; -const tagMeta = await getTagMeta(tag); - -const TagContent = tagMeta ? (await render(tagMeta)).Content : null; - -// Capitalize first letter of tag for display -const tagDisplay = tag.charAt(0).toUpperCase() + tag.slice(1); - -const meta = { - description: tagMeta?.data.description ?? `View all posts with the tag - ${tag}`, - title: tagMeta?.data.title ?? `${tagDisplay} posts`, -}; - -const paginationProps = { - ...(page.url.prev && { - prevUrl: { - text: "← Previous posts", - url: page.url.prev, - }, - }), - ...(page.url.next && { - nextUrl: { - text: "Next posts →", - url: page.url.next, - }, - }), -}; ---- - - - -

- {tagMeta?.data.title ?? `${tagDisplay} posts`} - - RSS feed - -

-
- {tagMeta?.data.description &&

{tagMeta.data.description}

} - {TagContent && } -
-
    - { - page.data.map((post) => ( -
  • - -
  • - )) - } -
- -
diff --git a/src/pages/tags/[tag]/index.astro b/src/pages/tags/[tag]/index.astro new file mode 100644 index 0000000..2f7fa47 --- /dev/null +++ b/src/pages/tags/[tag]/index.astro @@ -0,0 +1,95 @@ +--- +import { render } from "astro:content"; +import type { GetStaticPaths } from "astro"; +import { Icon } from "astro-icon/components"; +import PostPreview from "@/components/blog/PostPreview.astro"; +import { getAllPosts, getTagMeta, getUniqueTags, groupPostsByYear } from "@/data/post"; +import PageLayout from "@/layouts/Base.astro"; +import { collectionDateSort } from "@/utils/date"; + +export const getStaticPaths = (async () => { + const allPosts = await getAllPosts(true); + const allTags = getUniqueTags(allPosts); + + return allTags.map((tag) => { + const postsWithTag = allPosts + .filter((post) => post.data.tags.includes(tag)) + .sort(collectionDateSort); + + return { params: { tag }, props: { posts: postsWithTag } }; + }); +}) satisfies GetStaticPaths; + +const { posts } = Astro.props; +const { tag } = Astro.params; +const tagMeta = await getTagMeta(tag); + +const TagContent = tagMeta ? (await render(tagMeta)).Content : null; + +// Capitalize first letter of tag for display +const tagDisplay = tag.charAt(0).toUpperCase() + tag.slice(1); + +const meta = { + description: tagMeta?.data.description ?? `View all posts with the tag - ${tag}`, + title: tagMeta?.data.title ?? `${tagDisplay} posts`, +}; + +const groupedByYear = groupPostsByYear(posts); +const descYearKeys = Object.keys(groupedByYear).sort((a, b) => +b - +a); +const useYearGrouping = posts.length > 20; +--- + + + +

+ {tagMeta?.data.title ?? `${tagDisplay} posts`} + + RSS feed + +

+
+ {tagMeta?.data.description &&

{tagMeta.data.description}

} + {TagContent && } +
+ { + useYearGrouping ? ( + descYearKeys.map((yearKey) => ( +
+

+ Posts in + {yearKey} +

+
    + {groupedByYear[yearKey]?.map((post) => ( +
  • + +
  • + ))} +
+
+ )) + ) : ( +
    + {posts.map((post) => ( +
  • + +
  • + ))} +
+ ) + } +
-- cgit v1.2.3