feat: add categories page instead of the pinned categories.

This commit is contained in:
Yufan Sheng 2024-11-27 22:36:40 +08:00
parent 0730a865b9
commit 4cefde38b0
Signed by: syhily
GPG Key ID: DEB186763C308C31
12 changed files with 78 additions and 67 deletions

View File

@ -1,5 +1,5 @@
{ {
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json", "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"formatter": { "formatter": {
"enabled": false "enabled": false
}, },

View File

@ -48,7 +48,6 @@ const Options = z
post: z.object({ post: z.object({
sort: z.enum(['asc', 'desc']), sort: z.enum(['asc', 'desc']),
feature: z.array(z.string()).min(3).optional(), feature: z.array(z.string()).min(3).optional(),
category: z.array(z.string()).optional(),
}), }),
pagination: z.object({ pagination: z.object({
posts: z.number().optional().default(5), posts: z.number().optional().default(5),
@ -121,6 +120,10 @@ const options: z.input<typeof Options> = {
text: '首页', text: '首页',
link: '/', link: '/',
}, },
{
text: '分类',
link: '/categories',
},
{ {
text: '关于', text: '关于',
link: '/about', link: '/about',
@ -133,11 +136,6 @@ const options: z.input<typeof Options> = {
text: '友链', text: '友链',
link: '/links', link: '/links',
}, },
{
text: '笔记',
link: 'https://note.yufan.me',
target: '_blank',
},
], ],
socials: [ socials: [
{ {
@ -174,7 +172,6 @@ const options: z.input<typeof Options> = {
assetPrefix: 'https://cat.yufan.me', assetPrefix: 'https://cat.yufan.me',
post: { post: {
sort: 'desc', sort: 'desc',
category: ['article', 'think', 'gossip', 'coding'],
}, },
pagination: { pagination: {
posts: 6, posts: 6,

12
package-lock.json generated
View File

@ -7501,9 +7501,9 @@
} }
}, },
"node_modules/regex-recursion": { "node_modules/regex-recursion": {
"version": "4.2.1", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.2.1.tgz", "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-4.3.0.tgz",
"integrity": "sha512-QHNZyZAeKdndD1G3bKAbBEKOSSK4KOHQrAJ01N1LJeb0SoH4DJIeFhp0uUpETgONifS4+P3sOgoA1dhzgrQvhA==", "integrity": "sha512-5LcLnizwjcQ2ALfOj95MjcatxyqF5RPySx9yT+PaXu3Gox2vyAtLDjHB8NTJLtMGkvyau6nI3CfpwFCjPUIs/A==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"regex-utilities": "^2.3.0" "regex-utilities": "^2.3.0"
@ -8553,9 +8553,9 @@
"optional": true "optional": true
}, },
"node_modules/type-fest": { "node_modules/type-fest": {
"version": "4.28.1", "version": "4.29.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.28.1.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.29.0.tgz",
"integrity": "sha512-LO/+yb3mf46YqfUC7QkkoAlpa7CTYh//V1Xy9+NQ+pKqDqXIq0NTfPfQRwFfCt+if4Qkwb9gzZfsl6E5TkXZGw==", "integrity": "sha512-RPYt6dKyemXJe7I6oNstcH24myUGSReicxcHTvCLgzm4e0n8y05dGvcGB15/SoPRBmhlMthWQ9pvKyL81ko8nQ==",
"license": "(MIT OR CC0-1.0)", "license": "(MIT OR CC0-1.0)",
"engines": { "engines": {
"node": ">=16" "node": ">=16"

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -1,41 +0,0 @@
---
import Image from '@/components/image/Image.astro';
import { getCategory } from '@/helpers/schema';
import options from '@/options';
const pinnedSlug = options.settings.post.category ?? [];
const pinnedCategories = pinnedSlug
.map((slug) => getCategory(undefined, slug))
.filter((category) => category !== undefined);
---
<div class="row g-2 g-md-4 list-grouped mt-3 mt-md-4">
{
pinnedCategories.map((category) => (
<div class="col-md-6">
<div class="list-item block">
<div class="media media-3x1">
<a href={category.permalink} class="media-content">
<Image {...category.cover} alt={category.name} width={600} height={200} />
</a>
</div>
<div class="list-content">
<div class="list-body">
<a href={category.permalink} class="list-title h5">
{category.name}
</a>
<div class="list-subtitle d-none d-md-block text-md text-secondary mt-2">
<div class="h-1x">{category.description}</div>
</div>
</div>
<div class="list-footer mt-2">
<div class="text-muted text-sm">
<span class="d-inline-block">{`${category.counts} 篇文章`}</span>
</div>
</div>
</div>
</div>
</div>
))
}
</div>

View File

@ -0,0 +1,6 @@
name: 笔记
slug: notes
description: |-
风萧萧,天寥寥。山隐隐,木叶凋。小楼坐定,理书罢了。
灯青茶酽花静声悄,添几行斜书歪字,懒寻甚金缕玉箫。
cover: /images/categories/notes.jpg

View File

@ -120,13 +120,6 @@ if (invalidFeaturePosts.length > 0) {
throw new Error(`The bellowing feature posts are invalid:\n$${invalidFeaturePosts.join('\n')}`); throw new Error(`The bellowing feature posts are invalid:\n$${invalidFeaturePosts.join('\n')}`);
} }
// Validate pinned categories.
const pinnedCategories: string[] = options.settings.post.category ?? [];
const invalidPinnedCategories = pinnedCategories.filter((c) => categories.find((e) => e.name === c));
if (invalidPinnedCategories.length > 0) {
throw new Error(`The bellowing pinned categories are invalid:\n$${invalidPinnedCategories.join('\n')}`);
}
export const getPost = (slug: string): Post | undefined => { export const getPost = (slug: string): Post | undefined => {
return posts.find((post) => post.slug === slug); return posts.find((post) => post.slug === slug);
}; };

View File

@ -0,0 +1,52 @@
---
import Image from '@/components/image/Image.astro';
import { categories } from '@/helpers/schema';
import BaseLayout from '@/layouts/BaseLayout.astro';
interface Props {
title: string;
}
const { title } = Astro.props;
---
<BaseLayout {title}>
<div class="px-lg-2 px-xxl-5 py-3 py-md-4 py-xxl-5">
<div class="container">
<h1 class="post-title mb-3 mb-xl-4">{title}</h1>
<div class="row g-2 g-md-4 list-grouped mt-3 mt-md-4">
{
categories
.sort((a, b) => b.counts - a.counts)
.map((category) => (
<div class="col-md-6">
<div class="list-item block">
<div class="media media-3x1">
<a href={category.permalink} class="media-content">
<Image {...category.cover} alt={category.name} width={600} height={200} />
</a>
</div>
<div class="list-content">
<div class="list-body">
<a href={category.permalink} class="list-title h5">
{category.name}
</a>
<div class="list-subtitle d-none d-md-block text-md text-secondary mt-2">
<div class="h-1x">{category.description}</div>
</div>
</div>
<div class="list-footer mt-2">
<div class="text-muted text-sm">
<span class="d-inline-block">{`${category.counts} 篇文章`}</span>
</div>
</div>
</div>
</div>
</div>
))
}
</div>
</div>
</div>
<slot />
</BaseLayout>

View File

@ -14,9 +14,6 @@ interface Props {
const { category, posts, pageNum } = Astro.props; const { category, posts, pageNum } = Astro.props;
const { currentPosts, totalPage } = slicePosts(posts, pageNum, options.settings.pagination.category); const { currentPosts, totalPage } = slicePosts(posts, pageNum, options.settings.pagination.category);
if (totalPage === 0) {
return Astro.redirect('/404');
}
--- ---
<BaseLayout title={category.name}> <BaseLayout title={category.name}>

View File

@ -1,7 +1,6 @@
--- ---
import FeaturePosts from '@/components/page/post/FeaturePosts.astro'; import FeaturePosts from '@/components/page/post/FeaturePosts.astro';
import PostCards from '@/components/page/post/PostCards.astro'; import PostCards from '@/components/page/post/PostCards.astro';
import PinnedCategories from '@/components/page/post/PostCategory.astro';
import Sidebar from '@/components/sidebar/Sidebar.astro'; import Sidebar from '@/components/sidebar/Sidebar.astro';
import type { Post, Tag } from '@/helpers/schema'; import type { Post, Tag } from '@/helpers/schema';
import BaseLayout from '@/layouts/BaseLayout.astro'; import BaseLayout from '@/layouts/BaseLayout.astro';
@ -29,7 +28,6 @@ if (pageNum < 1) {
<PostCards {pageNum} {posts} /> <PostCards {pageNum} {posts} />
<Sidebar {posts} {tags} /> <Sidebar {posts} {tags} />
</div> </div>
<PinnedCategories />
</div> </div>
</div> </div>
<slot /> <slot />

View File

@ -0,0 +1,5 @@
---
import CategoriesLayout from '@/layouts/posts/CategoriesLayout.astro';
---
<CategoriesLayout title="文章分类" />

View File

@ -15,6 +15,10 @@ if (!category) {
} }
const filteredPosts = posts.filter((post) => post.category === category.name); const filteredPosts = posts.filter((post) => post.category === category.name);
if (filteredPosts.length === 0) {
return Astro.rewrite('/404');
}
--- ---
<CategoryLayout posts={filteredPosts} {category} pageNum={1} /> <CategoryLayout posts={filteredPosts} {category} pageNum={1} />