Typecho CF 添加标签总览页
Typecho CF 添加标签总览页
本站基于 Typecho CF 搭建,默认主题没有标签总览页,所有标签只能逐个点开。本文记录如何新增一个
/tag/标签总览页,以彩色标签云展示。
一、新建页面文件
在 src/pages/tag/ 目录下新建 index.astro。该目录下已存在 [slug].astro(用于单个标签页 /tag/xxx/),而 index.astro 优先级更高,两者不冲突。
---
import Base from '@/layouts/Base.astro';
import { createContext } from '@/lib/context';
import { prepareIndexData } from '@/lib/page-data';
import { schema } from '@/db';
import { eq } from 'drizzle-orm';const ctx = await createContext(Astro.locals, Astro.request);
const { db, options, urls, user, isLoggedIn, pluginCtx } = ctx;
const data = await prepareIndexData(ctx, Astro.request.url, Astro.locals, Astro.url);
const pages = data?.pages;
const sidebarData = data?.sidebarData;
const allTags = await db
.select({
mid: schema.metas.mid,
name: schema.metas.name,
slug: schema.metas.slug,
})
.from(schema.metas)
.where(eq(schema.metas.type, 'tag'));
const relationships = await db
.select({
mid: schema.relationships.mid,
cid: schema.relationships.cid,
})
.from(schema.relationships);
const tagCountMap = {};
relationships.forEach((r) => {
tagCountMap[r.mid] = (tagCountMap[r.mid] || 0) + 1;
});
const tagsWithColor = allTags.map((tag) => {
const count = tagCountMap[tag.mid] || 0;
let hash = 0;
const name = tag.name || '';
for (let i = 0; i < name.length; i++) {
hash = name.charCodeAt(i) + ((hash << 5) - hash);
}
const hue = Math.abs(hash) % 360;
return {
...tag,
count,
bgColor: hsl(${hue}, 70%, 92%),
textColor: hsl(${hue}, 65%, 35%),
};
});
二、彩色标签云展示
页面主体用 flex 布局,把标签渲染成彩色圆角药丸:
<div class="tag-cloud">
{tagsWithColor.map((tag) => (
<a
href={`${urls.siteUrl}/tag/${tag.slug}/`}
class="tag-pill"
style={`background: ${tag.bgColor}; color: ${tag.textColor};`}
>
{tag.name}
<span>({tag.count})</span>
</a>
))}
</div>
配套样式:
.tag-cloud {
display: flex;
flex-wrap: wrap;
gap: 10px;
padding: 20px 0;
}
.tag-pill {
display: inline-block;
padding: 6px 14px;
border-radius: 999px;
text-decoration: none;
font-size: 14px;
transition: all 0.2s;
}
.tag-pill:hover {
transform: translateY(-2px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
三、修改 [slug].astro
打开 src/pages/tag/[slug].astro,找到这一行:
if (!slug) return Astro.redirect('/');
因为 index.astro 会优先匹配 /tag/,这行重定向已经用不到,注释掉即可:
// if (!slug) return Astro.redirect('/');
四、加入导航栏
在 src/pages/archive.astro 和 src/themes/typocho-theme-note/components/Archive.astro 的导航栏里加一行:
<a href={urls.siteUrl + '/tag/'}>标签</a>
五、最终效果
访问 https://hbw.me/tag/:
- 所有标签以彩色药丸展示
- 每个标签带文章数
- 颜色按标签名哈希生成,同名标签颜色稳定
- 点击进入对应标签页
/tag/xxx/
导航栏也加入「标签」按钮,方便访问。