diff --git a/src/components/layout/Header.astro b/src/components/layout/Header.astro index fa9966e..7a7fbce 100644 --- a/src/components/layout/Header.astro +++ b/src/components/layout/Header.astro @@ -7,18 +7,42 @@ class='relative mx-auto flex w-full items-center justify-between sm:flex sm:items-center' aria-label='global' > - resume + KazooTTT Blog
Blog + Categories + + Tags + Tools diff --git a/src/content/config.ts b/src/content/config.ts index fe9555c..779c026 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -12,7 +12,7 @@ const post = defineCollection({ schema: ({ image }) => z.object({ title: z.string().max(60), - description: z.string().min(50).max(160), + description: z.string(), publishDate: z .string() .or(z.date()) @@ -29,7 +29,8 @@ const post = defineCollection({ .optional(), draft: z.boolean().default(false), tags: z.array(z.string()).default([]).transform(removeDupsAndLowerCase), - ogImage: z.string().optional() + ogImage: z.string().optional(), + category: z.string().optional(), }) }) diff --git a/src/content/post/cover-image/index.md b/src/content/post/cover-image/index.md index 4f78dc9..7af5c5d 100644 --- a/src/content/post/cover-image/index.md +++ b/src/content/post/cover-image/index.md @@ -7,4 +7,5 @@ coverImage: src: "./cover.png" alt: "Astro build wallpaper" tags: ["test", "image"] +category: c1 --- diff --git a/src/content/post/draft-post.md b/src/content/post/draft-post.md index 8517240..1215e7a 100644 --- a/src/content/post/draft-post.md +++ b/src/content/post/draft-post.md @@ -4,6 +4,7 @@ description: "This post is for testing the draft post functionality" publishDate: "10 Sept 2023" tags: ["test"] draft: true +category: c2 --- If this is working correctly, this post should only be accessible in a dev environment, as well as any tags that are unique to this post. diff --git a/src/content/post/long-title.md b/src/content/post/long-title.md index f79f330..d22020f 100644 --- a/src/content/post/long-title.md +++ b/src/content/post/long-title.md @@ -3,6 +3,7 @@ title: "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Id" description: "This post is purely for testing if the css is correct for the title on the page" publishDate: "01 Feb 2023" tags: ["test"] +category: c3 --- ## Testing the title tag diff --git a/src/pages/blog/[...page].astro b/src/pages/blog/[...page].astro index 641f644..defcdf5 100644 --- a/src/pages/blog/[...page].astro +++ b/src/pages/blog/[...page].astro @@ -8,21 +8,23 @@ import Button from '@/components/Button.astro' import Pagination from '@/components/Paginator.astro' import PostPreview from '@/components/blog/PostPreview.astro' import PageLayout from '@/layouts/BaseLayout.astro' -import { getAllPosts, getUniqueTags, sortMDByDate } from '@/utils' +import { getAllPosts, getUniqueCategories, getUniqueTags, sortMDByDate } from '@/utils' export const getStaticPaths = (async ({ paginate }) => { const allPosts = await getAllPosts() const allPostsByDate = sortMDByDate(allPosts) const uniqueTags = getUniqueTags(allPosts) - return paginate(allPostsByDate, { pageSize: 10, props: { uniqueTags } }) + const uniqueCategories = getUniqueCategories(allPosts) + return paginate(allPostsByDate, { pageSize: 10, props: { uniqueTags, uniqueCategories } }) }) satisfies GetStaticPaths interface Props { page: Page> uniqueTags: string[] + uniqueCategories: string[] } -const { page, uniqueTags } = Astro.props +const { page, uniqueTags, uniqueCategories } = Astro.props const meta = { description: 'Posts', @@ -77,41 +79,89 @@ const paginationProps = { - {!!uniqueTags.length && ( - - )} +
+ {!!uniqueCategories.length && ( + + )} + + {!!uniqueTags.length && ( + + )} +
) } diff --git a/src/pages/categories/[category]/[...page].astro b/src/pages/categories/[category]/[...page].astro new file mode 100644 index 0000000..4971476 --- /dev/null +++ b/src/pages/categories/[category]/[...page].astro @@ -0,0 +1,96 @@ +--- +export const prerender = true + +import type { GetStaticPaths, Page } from 'astro' +import type { CollectionEntry } from 'astro:content' + +import Pagination from '@/components/Paginator.astro' +import PostPreview from '@/components/blog/PostPreview.astro' +import PageLayout from '@/layouts/BaseLayout.astro' +import Button from '@/components/Button.astro' +import { getAllPosts, getUniqueTags, sortMDByDate } from '@/utils' + +export const getStaticPaths: GetStaticPaths = async ({ paginate }) => { + const allPosts = await getAllPosts() + const allPostsByDate = sortMDByDate(allPosts) + const uniqueTags = getUniqueTags(allPostsByDate) + + return uniqueTags.flatMap((tag) => { + const filterPosts = allPostsByDate.filter((post) => post.data.tags.includes(tag)) + return paginate(filterPosts, { + pageSize: 10, + params: { tag } + }) + }) +} + +interface Props { + page: Page> +} + +const { page } = Astro.props +const { tag } = Astro.params + +const meta = { + description: `View all posts with the tag - ${tag}`, + title: `Tag: ${tag}` +} + +const paginationProps = { + ...(page.url.prev && { + prevUrl: { + text: `← Previous Tags`, + url: page.url.prev + } + }), + ...(page.url.next && { + nextUrl: { + text: `Next Tags →`, + url: page.url.next + } + }) +} +--- + + +
+ +

+ Tags: + #{tag} +

+
+
    + {page.data.map((p) => )} +
+ +
+ + + + + + +

Get free template

+
+
+
diff --git a/src/pages/categories/index.astro b/src/pages/categories/index.astro new file mode 100644 index 0000000..86c250d --- /dev/null +++ b/src/pages/categories/index.astro @@ -0,0 +1,72 @@ +--- +import Button from '@/components/Button.astro' +import PageLayout from '@/layouts/BaseLayout.astro' +import { getAllPosts, getUniqueCategoriesWithCount } from '@/utils' + +const allPosts = await getAllPosts() +const allCategories = getUniqueCategoriesWithCount(allPosts) + +const meta = { + description: "A list of all the topics I've written about in my posts", + title: 'All Categories' +} +--- + + +
+ + +

Categories

+ {allCategories.length === 0 &&

No posts yet.

} + + { + allCategories.length > 0 && ( +
    + {allCategories.map(([tag, val]) => ( +
  • + + #{tag} + + + - {val} post{val > 1 && 's'} + +
  • + ))} +
+ ) + } + + + + + + + +

Get free template

+
+
+
diff --git a/src/site.config.ts b/src/site.config.ts index bfacd21..28574f8 100644 --- a/src/site.config.ts +++ b/src/site.config.ts @@ -3,18 +3,18 @@ import type { AstroExpressiveCodeOptions } from 'astro-expressive-code' export const siteConfig: SiteConfig = { // Used as both a meta property (src/components/BaseHead.astro L:31 + L:49) & the generated satori png (src/pages/og-image/[slug].png.ts) - author: 'SRLEOM', + author: 'KazooTTT', // Meta property used to construct the meta title property, found in src/components/BaseHead.astro L:11 - title: 'astro-theme-resume', + title: 'KazooTTT Blog', // Meta property used as the default description meta property - description: 'The official Astro Resume Theme', + description: '声控烤箱 | 我喜欢的烤箱是声控的 | 前端小透明', // HTML lang property, found in src/layouts/Base.astro L:18 - lang: 'en-GB', + lang: 'zh-CN', // Meta property, found in src/components/BaseHead.astro L:42 - ogLocale: 'en_GB', + ogLocale: 'zh-CN', // Date.prototype.toLocaleDateString() parameters, found in src/utils/date.ts. date: { - locale: 'en-GB', + locale: 'zh-CN', options: { day: 'numeric', month: 'short', @@ -31,7 +31,7 @@ export const menuLinks: Array<{ title: string; path: string }> = [ { title: 'Blog', path: '/blog/' - } + }, ] // https://expressive-code.com/reference/configuration/ diff --git a/src/utils/index.ts b/src/utils/index.ts index 4718b09..4b33472 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,5 +1,5 @@ export { cn } from './tailwind' -export { getAllPosts, sortMDByDate, getUniqueTags, getUniqueTagsWithCount } from './post' +export { getAllPosts, sortMDByDate, getUniqueTags, getUniqueTagsWithCount, getAllCategories, getUniqueCategories,getUniqueCategoriesWithCount } from './post' export { getFormattedDate } from './date' export { generateToc } from './generateToc' export type { TocItem } from './generateToc' diff --git a/src/utils/post.ts b/src/utils/post.ts index ed90e65..bfcaec9 100644 --- a/src/utils/post.ts +++ b/src/utils/post.ts @@ -37,3 +37,26 @@ export function getUniqueTagsWithCount( ) ].sort((a, b) => b[1] - a[1]) } + +/** Note: This function doesn't filter draft posts, pass it the result of getAllPosts above to do so. */ +export function getAllCategories(posts: Array>): string[] { + return posts.map(post => post.data.category ?? "未分类") +} + + +/** Note: This function doesn't filter draft posts, pass it the result of getAllPosts above to do so. */ +export function getUniqueCategories(posts: Array>) { + return [...new Set(getAllCategories(posts))] +} + +/** Note: This function doesn't filter draft posts, pass it the result of getAllPosts above to do so. */ +export function getUniqueCategoriesWithCount( + posts: Array> +): Array<[string, number]> { + return [ + ...getAllCategories(posts).reduce( + (acc, t) => acc.set(t, (acc.get(t) || 0) + 1), + new Map() + ) + ].sort((a, b) => b[1] - a[1]) +} \ No newline at end of file