归档统计
661 字
3 分钟
归档统计
AI 摘要
获取归档列表
文件路径:src/pages/archive.astro
---import { getSortedPostsList } from "@/utils/content-utils"; // [!code --]const sortedPostsList = await getSortedPostsList(); // [!code --]<ArchivePanel sortedPosts={sortedPostsList} client:only="svelte" /> // [!code --]
import { getArchiveList } from "@/utils/content-utils";
// 获取归档列表(posts + moments + bangumi + life)const archiveList = await getArchiveList();
// 计算各类型数量const postsCount = archiveList.filter(item => item.type === "post").length;const momentsCount = archiveList.filter(item => item.type === "moment").length;const bangumiCount = archiveList.filter(item => item.type === "bangumi").length;const lifeCount = archiveList.filter(item => item.type === "life").length;const totalCount = postsCount + momentsCount + bangumiCount + lifeCount;---
<MainGridLayout title={i18n(I18nKey.archive)}> <!-- 统计信息 --> <div class="card-base px-8 py-6 mb-6"> <div class="flex flex-wrap gap-6 justify-center text-center"> <div class="flex flex-col"> <span class="text-3xl font-bold text-amber-500">{postsCount}</span> <span class="text-sm text-30 mt-1">{i18n(I18nKey.postList)}</span> </div> <div class="w-px bg-neutral-200 dark:bg-neutral-700"></div> <div class="flex flex-col"> <span class="text-3xl font-bold text-(--primary)">{momentsCount}</span> <span class="text-sm text-30 mt-1">{i18n(I18nKey.moments)}</span> </div> <div class="w-px bg-neutral-200 dark:bg-neutral-700"></div> <div class="flex flex-col"> <span class="text-3xl font-bold text-red-500 dark:text-red-400">{bangumiCount}</span> <span class="text-sm text-30 mt-1">{i18n(I18nKey.bangumi)}</span> </div> <div class="w-px bg-neutral-200 dark:bg-neutral-700"></div> <div class="flex flex-col"> <span class="text-3xl font-bold text-emerald-600 dark:text-emerald-400">{lifeCount}</span> <span class="text-sm text-30 mt-1">生活</span> </div> <div class="w-px bg-neutral-200 dark:bg-neutral-700"></div> <div class="flex flex-col"> <span class="text-3xl font-bold text-(--primary)">{totalCount}</span> <span class="text-sm text-30 mt-1">总计</span> </div> </div> </div> <ArchivePanel sortedPosts={archiveList} client:only="svelte" /></MainGridLayout>更新内容工具函数文件
文件路径:src/utils/content-utils.ts
---import { getCategoryUrl, getPostUrlBySlug } from "@utils/url-utils";import { getDiaryList } from "@/data/diary"---
export interface ArchiveItem { id: string; type: "post" | "moment" | "bangumi" | "life"; link?: string; data: { title: string; published: Date; tags: string[]; category?: string | null; };}
export async function getArchiveList(): Promise<ArchiveItem[]> { const posts = await getCollection("posts", ({ data }) => { return import.meta.env.PROD ? data.draft !== true : true; }); const diaryList = getDiaryList();
const postItems: ArchiveItem[] = posts.map((post) => ({ id: post.id, type: "post", link: getPostUrlBySlug(post.id), data: { title: post.data.title, published: post.data.published, tags: post.data.tags, category: post.data.category || null, }, }));
// 将日记数据转换为归档项 const momentItems: ArchiveItem[] = diaryList.map((diary) => { let title = diary.content || ""; title = title.replace(/[#*`]/g, "").trim(); if (title.length > 50) title = `${title.substring(0, 50)}...`; if (!title) title = i18n(I18nKey.moments) || "日常动态";
return { id: String(diary.id), type: "moment", link: "/diary/", data: { title: title, published: new Date(diary.date), tags: diary.tags || [], category: null, }, }; });
// 空数组,用于保持接口兼容性 const bangumiItems: ArchiveItem[] = []; const lifeItems: ArchiveItem[] = [];
return [...postItems, ...momentItems, ...bangumiItems, ...lifeItems].sort((a, b) => { const timeA = a.data.published.getTime(); const timeB = b.data.published.getTime(); return timeB - timeA; });}定义类型
文件路径:src/components/controls/ArchivePanel.svelte
interface Post { id: string; type?: "post" | "moment" | "bangumi" | "life"; link?: string; data: { title: string; tags: string[]; category?: string | null; published: Date; };}
{@const postLink = post.link || getPostUrlBySlug(post.id)}<a href={getPostUrlBySlug(post.id)} // [!code --] href={postLink} // [!code ++] aria-label={post.data.title} class="group btn-plain block! h-10 w-full rounded-lg hover:text-[initial]">
<div class="w-[70%] md:max-w-[65%] md:w-[65%] text-left font-bold group-hover:translate-x-1 transition-all group-hover:text-(--primary) text-75 pr-8 whitespace-nowrap text-ellipsis overflow-hidden flex items-center gap-2" > {#if post.type === 'post'} <span class="px-1.5 py-0.5 text-[10px] bg-amber-500 text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal"> 文章 </span> {:else if post.type === 'moment'} <span class="px-1.5 py-0.5 text-[10px] bg-(--primary) text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal"> {i18n(I18nKey.moments) || 'Moment'} </span> {:else if post.type === 'bangumi'} <span class="px-1.5 py-0.5 text-[10px] bg-red-500 text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal"> {i18n(I18nKey.bangumi) || 'Record'} </span> {:else if post.type === 'life'} <span class="px-1.5 py-0.5 text-[10px] bg-emerald-600 text-white rounded-md shrink-0 uppercase tracking-wider opacity-80 font-normal"> 生活 </span> {/if} <span class="truncate">{post.data.title}</span> </div>语言配置
- 文件路径:
src/i18n/i18nKey.ts
moments = "moments",- 文件路径:
src/i18n/languages/en.ts
[Key.moments]: "Dynamic",- 文件路径:
src/i18n/languages/ja.ts
[Key.moments]: "ダイナミック",- 文件路径:
src/i18n/languages/ru.ts
[Key.moments]: "Динамика",- 文件路径:
src/i18n/languages/zh_CN.ts
[Key.moments]: "动态",- 文件路径:
src/i18n/languages/zh_TW.ts
[Key.moments]: "動態",支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
相关文章 智能推荐
1
Umami 访问统计卡片
Firefly 最近给博客侧边栏加了个小彩蛋——Umami 访问统计卡片,不用后端、不破风格,数据实时还带点击跳转。整个过程就是在 Firefly 主题里新建一个组件,填入 Umami 的分享链接,系统自动解析 API 和 Token,再配个备用数据兜底。连统计周期都能按需调,比如改成最近 30 天,改个毫秒数就完事~现在每次打开博客,侧边栏都默默告诉我:“今天又被看了好多眼”。
2
集成朋友圈与笔记本功能
Firefly 本教程详细介绍如何将朋友圈(Moments)和笔记本(Notebooks)功能集成到项目中,数据存储在 GitHub Gist 中。
3
隐藏封面图
Firefly 最近在折腾博客的封面图显示逻辑,加了个「隐藏封面图」的开关功能——从类型定义、配置项、工具函数到 UI 控件和样式,一步步把整个流程补全了。代码分散在多个文件里,但核心就一件事:让用户能一键收起或展开文章封面,既保持页面简洁,又不丢失视觉层次。顺手还做了多语言支持,中文、英文切换也一起配上了。
4
给博客增加单个和全部分类页面
Firefly 最近给博客加了个小功能:点击分类名就能跳转到该分类下的所有文章,还能一键查看全部分类列表——整个过程其实挺顺的,从创建页面、写 URL 工具函数,到更新导航栏和多语言支持,一步步配下来,连分类链接都自动带上了本地化路径,现在逛自己博客像逛图书馆一样清爽 😄
5
恋爱计时组件
Firefly 最近给博客加了个小彩蛋——「恋爱计时组件」,从零撸了一个记录纪念日的小工具。写了组件代码、配了全局注册、还兼顾了桌面端侧边栏和移动端的显示逻辑,连 TypeScript 类型定义和双方昵称/日期的配置项都琢磨得挺细。虽然只是个轻量小功能,但每次看到倒计时跳动,心里都悄悄甜一下 😊
随机文章 随机推荐