From 557f312bc76ff12ff832ffb2a3e42ff1c0e5e72d Mon Sep 17 00:00:00 2001
From: hoelee
Date: Tue, 20 Oct 2026 23:37:44 +0800
Subject: [PATCH] feat(tags): tag pages get the archive filter bar and topic
chips
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
/tags// passed chrome={false}, so a tag page showed a bare list — no filter
input and no chips — while /posts/ had both. Enable the chrome and add a
chipPosts prop: the tag strip is built from the whole language collection because
its chips navigate (page-scoped counts would lie), while category chips and the
row filter stay scoped to the posts on the page so their counts match the rows.
The current tag is marked is-active + aria-current instead of looking clickable.
---
src/components/Archive.astro | 20 +++++++++++++++++---
src/pages/tags/[tag].astro | 14 +++++++++++---
src/pages/zh/tags/[tag].astro | 12 +++++++++---
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/src/components/Archive.astro b/src/components/Archive.astro
index 2f074d0..0a8a58e 100644
--- a/src/components/Archive.astro
+++ b/src/components/Archive.astro
@@ -7,11 +7,21 @@ interface Props {
lang?: 'en' | 'zh';
/** Filter bar + chips. Off on tag/collection pages, where the set is already narrow. */
chrome?: boolean;
+ /**
+ * Posts the tag-chip strip is built from. Defaults to `posts`, which is right on
+ * the archive; a tag page passes the whole language collection so its strip is the
+ * same site-wide topic menu as /posts/ (the chips navigate, so their counts must be
+ * site-wide or they would lie). Category chips and the row filter stay scoped to
+ * `posts`, so their counts always match the rows actually on the page.
+ */
+ chipPosts?: CollectionEntry<'posts'>[];
+ /** On a tag page, the tag being viewed — its chip is marked active instead of looking clickable-to-self. */
+ activeTag?: string;
}
-const { posts, lang = 'en', chrome = true } = Astro.props;
+const { posts, lang = 'en', chrome = true, chipPosts = posts, activeTag } = Astro.props;
const isZh = lang === 'zh';
-const counts = tagCounts(posts);
+const counts = tagCounts(chipPosts);
const years = [...new Set(posts.map((p) => p.data.pubDate.getUTCFullYear()))].sort((a, b) => b - a);
const categories = [...new Set(posts.map((p) => p.data.category))]
.map((c) => ({ name: c, n: posts.filter((p) => p.data.category === c).length }))
@@ -56,7 +66,11 @@ const labels = isZh
>
diff --git a/src/pages/tags/[tag].astro b/src/pages/tags/[tag].astro
index 4e18d02..70bebec 100644
--- a/src/pages/tags/[tag].astro
+++ b/src/pages/tags/[tag].astro
@@ -16,11 +16,16 @@ export async function getStaticPaths() {
const counts = tagCounts(posts);
return tagPageNames(posts).map((tag) => ({
params: { tag },
- props: { tag, n: counts.get(tag) ?? 0, posts: posts.filter((p) => p.data.tags.includes(tag)) },
+ props: {
+ tag,
+ n: counts.get(tag) ?? 0,
+ posts: posts.filter((p) => p.data.tags.includes(tag)),
+ all: posts,
+ },
}));
}
-const { tag, posts } = Astro.props as { tag: string; posts: any[] };
+const { tag, posts, all } = Astro.props as { tag: string; posts: any[]; all: any[] };
---
·
Categories
-
+ {/* Same filter bar and topic chips as /posts/ — a tag page that hides them makes
+ the reader go back up to the archive to filter anything. `chipPosts` is the whole
+ language collection so the tag strip keeps site-wide counts. */}
+
diff --git a/src/pages/zh/tags/[tag].astro b/src/pages/zh/tags/[tag].astro
index 016c552..6585fd4 100644
--- a/src/pages/zh/tags/[tag].astro
+++ b/src/pages/zh/tags/[tag].astro
@@ -14,11 +14,16 @@ export async function getStaticPaths() {
const counts = tagCounts(posts);
return tagPageNames(posts).map((tag) => ({
params: { tag },
- props: { tag, n: counts.get(tag) ?? 0, posts: posts.filter((p) => p.data.tags.includes(tag)) },
+ props: {
+ tag,
+ n: counts.get(tag) ?? 0,
+ posts: posts.filter((p) => p.data.tags.includes(tag)),
+ all: posts,
+ },
}));
}
-const { tag, posts } = Astro.props as { tag: string; posts: any[] };
+const { tag, posts, all } = Astro.props as { tag: string; posts: any[]; all: any[] };
---
·
分类
-
+ {/* 与 /zh/posts/ 相同的筛选栏与主题标签条;chipPosts 传全站集合,标签条的计数才是全站数。 */}
+