feat: add categories page instead of the pinned categories.
This commit is contained in:
parent
0730a865b9
commit
4cefde38b0
@ -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
|
||||||
},
|
},
|
||||||
|
11
options.ts
11
options.ts
@ -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
12
package-lock.json
generated
@ -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"
|
||||||
|
BIN
public/images/categories/notes.jpg
Normal file
BIN
public/images/categories/notes.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
@ -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>
|
|
6
src/content/categories/notes.yml
Normal file
6
src/content/categories/notes.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
name: 笔记
|
||||||
|
slug: notes
|
||||||
|
description: |-
|
||||||
|
风萧萧,天寥寥。山隐隐,木叶凋。小楼坐定,理书罢了。
|
||||||
|
灯青茶酽花静声悄,添几行斜书歪字,懒寻甚金缕玉箫。
|
||||||
|
cover: /images/categories/notes.jpg
|
@ -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);
|
||||||
};
|
};
|
||||||
|
52
src/layouts/posts/CategoriesLayout.astro
Normal file
52
src/layouts/posts/CategoriesLayout.astro
Normal 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>
|
@ -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}>
|
||||||
|
@ -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 />
|
||||||
|
5
src/pages/categories/index.astro
Normal file
5
src/pages/categories/index.astro
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
import CategoriesLayout from '@/layouts/posts/CategoriesLayout.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<CategoriesLayout title="文章分类" />
|
@ -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} />
|
||||||
|
Loading…
Reference in New Issue
Block a user