723 字
4 分钟
移除分类

对于一般的技术类个人博客来说,标签和系列已经足够满足我们需求了,而且大部分情况下文章可能都会是一个类目,反而显得有些冗余,所以去除这个分类可以使我们的博客更加美观

需要修改的文件#

1. 侧边栏组件#

文件: src/components/widget/SideBar.astro

移除 Categories 组件的导入:

src/components/widget/SideBar.astro
---
import type { MarkdownHeading } from "astro";
import Categories from "./Categories.astro";
import Profile from "./Profile.astro";
import Series from "./Series.astro";
import Tag from "./Tags.astro";
interface Props {
class?: string;
headings?: MarkdownHeading[];
series?: string;
}

移除分类组件的显示:

src/components/widget/SideBar.astro
<div id="sidebar-sticky" class="transition-all duration-700 flex flex-col w-full gap-4 top-4 sticky top-4">
<div id="series" class="flex flex-col w-full gap-4">
{ series && <Series series={ series }></Series> }
</div>
<Categories class="onload-animation" style="animation-delay: 150ms"></Categories>
<Tag class="onload-animation" style="animation-delay: 200ms"></Tag>
</div>

2. 文章元数据组件#

文件: src/components/PostMeta.astro

移除导入中的 getCategoryUrl,Props 接口中的 category 属性,以及 Props 解构中的 category 和整个 categories 显示区块:

src/components/PostMeta.astro
---
import { Icon } from "astro-icon/components";
import I18nKey from "../i18n/i18nKey";
import { i18n } from "../i18n/translation";
import { formatDateToYYYYMMDD } from "../utils/date-utils";
import { getCategoryUrl, getTagUrl } from "../utils/url-utils";
interface Props {
class: string;
published: Date;
updated?: Date;
tags: string[];
category: string | null;
hideTagsForMobile?: boolean;
hideUpdateDate?: boolean;
}
const {
published,
updated,
tags,
category,
hideTagsForMobile = false,
hideUpdateDate = false,
} = Astro.props;
const className = Astro.props.class;
---
<div class:list={["flex flex-wrap text-neutral-500 dark:text-neutral-400 items-center gap-4 gap-x-4 gap-y-2", className]}>
<!-- publish date -->
<div class="flex items-center">
<div class="meta-icon">
<Icon name="material-symbols:calendar-today-outline-rounded" class="text-xl"></Icon>
</div>
<span class="text-50 text-sm font-medium">{formatDateToYYYYMMDD(published)}</span>
</div>
<!-- update date -->
{!hideUpdateDate && updated && updated.getTime() !== published.getTime() && (
<div class="flex items-center">
<div class="meta-icon">
<Icon name="material-symbols:edit-calendar-outline-rounded" class="text-xl"></Icon>
</div>
<span class="text-50 text-sm font-medium">{formatDateToYYYYMMDD(updated)}</span>
</div>
)}
<!-- categories -->
<div class="flex items-center">
<div class="meta-icon">
<Icon name="material-symbols:book-2-outline-rounded" class="text-xl"></Icon>
</div>
<div class="flex flex-row flex-nowrap items-center">
<a href={getCategoryUrl(category)} aria-label={`View all posts in the ${category} category`}
class="link-lg transition text-50 text-sm font-medium
hover:text-[var(--primary)] dark:hover:text-[var(--primary)] whitespace-nowrap">
{category || i18n(I18nKey.uncategorized)}
</a>
</div>
</div>
<!-- tags -->
<div class:list={["items-center", {"flex": !hideTagsForMobile, "hidden md:flex": hideTagsForMobile}]}>

3. 文章卡片组件#

文件: src/components/PostCard.astro

移除 Props 接口中的 category 属性和解构中的 category

src/components/PostCard.astro
interface Props {
class?: string;
entry: CollectionEntry<"posts">;
title: string;
url: string;
published: Date;
updated?: Date;
tags: string[];
category: string | null;
image: string;
description: string;
draft: boolean;
style: string;
}
const {
entry,
title,
url,
published,
updated,
tags,
category,
image,
description,
style,
} = Astro.props;

移除传递给 PostMetadata 的 category 参数:

src/components/PostCard.astro
<PostMetadata published={published} updated={updated} tags={tags} category={category} hideTagsForMobile={true} hideUpdateDate={true} class="mb-4"></PostMetadata>

4. 文章列表页面#

文件: src/components/PostPage.astro

移除传递给 PostCard 的 category={entry.data.category} 参数:

src/components/PostPage.astro
{page.data.map((entry: CollectionEntry<"posts">) => (
<PostCard
entry={entry}
title={entry.data.title}
tags={entry.data.tags}
category={entry.data.category}
published={entry.data.published}
updated={entry.data.updated}
url={getPostUrlBySlug(entry.slug)}
image={entry.data.image}
description={entry.data.description}
draft={entry.data.draft}
class:list="onload-animation"
style={`animation-delay: calc(var(--content-delay) + ${delay++ * interval}ms);`}
></PostCard>
))}

5. 文章详情页面#

文件: src/pages/posts/[...slug].astro

移除传递给 PostMetadata 的 category={entry.data.category} 参数:

src/pages/posts/[...slug].astro
<div class="onload-animation">
<PostMetadata
class="mb-5"
published={entry.data.published}
updated={entry.data.updated}
tags={entry.data.tags}
category={entry.data.category}
></PostMetadata>
{!entry.data.image && <div class="border-[var(--line-divider)] border-dashed border-b-[1px] mb-5"></div>}
</div>

注意事项#

保留的部分#

虽然移除了分类功能的显示,但以下部分仍然保留:

  1. Content Schemasrc/content/config.ts 中的 category 字段定义保留,这样不会破坏现有文章的 frontmatter。
const postsCollection = defineCollection({
schema: z.object({
// ... 其他字段
category: z.string().optional().nullable().default(""),
// ...
}),
});
  1. 文章 Frontmatter:现有文章的 category 字段可以保留,只是不会在页面上显示。

完全移除#

如果想完全移除分类相关的所有代码,可以删除:

  1. src/components/widget/Categories.astro 文件
  2. src/utils/content-utils.ts 中的 getCategoryList 函数
  3. src/utils/url-utils.ts 中的 getCategoryUrl 函数
  4. 国际化文件中的 categoriesuncategorized 翻译

但这些不是必需的,保留它们不会影响功能。

移除分类
https://blog.gabrlie.cn/posts/remove-category-feature/
作者
Gabrlie
发布于
2025-11-28
许可协议
CC BY-NC-SA 4.0