refactor(blog): extract blog utilities into shared module

Move common blog functionality like post filtering, sorting and data extraction into a centralized utils module.
Replace Astro.glob with import.meta.glob for better performance.
Update all blog components and pages to use the new utilities.
This commit is contained in:
joyzhao
2025-06-19 16:28:59 +08:00
parent 429b13985f
commit 7951121c7f
11 changed files with 609 additions and 695 deletions

View File

@@ -1,76 +1,42 @@
---
// 导入必要的依赖
import { type Lang } from '@/i18n/utils';
import { defaultLang } from '@/i18n/ui';
import { getBlogBaseUrl, extractCategories } from '@/utils/blog-utils';
// 定义组件属性
// Define component props
interface Props {
lang?: Lang;
currentCategory?: string;
}
// 获取组件属性
// Get component props
const { lang = defaultLang, currentCategory = '' } = Astro.props;
// 确定基础URL路径
const baseUrl = lang === defaultLang ? '/blog' : `/${lang}/blog`;
// Determine base URL path
const baseUrl = getBlogBaseUrl(lang);
// 读取所有博客文章 - 根据语言选择不同的静态路径
let allPosts = [];
if (lang === 'zh') {
allPosts = await Astro.glob('/src/pages/zh/blog/posts/*.md');
} else {
allPosts = await Astro.glob('/src/pages/blog/posts/*.md');
}
// Read all blog posts - choose different static paths based on language
const postsGlob = {
en: await import.meta.glob('/src/pages/blog/posts/*.md', { eager: true }),
zh: await import.meta.glob('/src/pages/zh/blog/posts/*.md', { eager: true })
};
// 收集所有分类
const allCategories = new Set<string>();
// Get posts for current language
const allPosts = lang === 'zh' ? Object.values(postsGlob.zh) : Object.values(postsGlob.en);
// 处理所有文章的分类
const categoryMap = new Map<string, string>(); // 存储 categoryId 到 category 名称的映射
// Extract categories from posts
const categoryMap = extractCategories(allPosts);
allPosts.forEach(post => {
// 处理分类
if (post.frontmatter?.category) {
const categories = Array.isArray(post.frontmatter.category)
? post.frontmatter.category
: [post.frontmatter.category];
const categoryIds = Array.isArray(post.frontmatter.categoryId)
? post.frontmatter.categoryId
: post.frontmatter.categoryId ? [post.frontmatter.categoryId] : [];
// 如果有 categoryId则使用 categoryId 和 category 的映射
if (categoryIds.length > 0 && categoryIds.length === categories.length) {
categories.forEach((cat, index) => {
if (cat && categoryIds[index]) {
allCategories.add(cat);
categoryMap.set(cat, categoryIds[index]);
}
});
} else {
// 如果没有 categoryId 或长度不匹配,则使用 category 名称作为 ID
categories.forEach(cat => {
if (cat) {
allCategories.add(cat);
categoryMap.set(cat, cat.toLowerCase());
}
});
}
}
});
// Convert to array and sort
const categories = Array.from(categoryMap.keys()).sort();
// 转换为数组并排序
const categories = Array.from(allCategories).sort();
// 多语言标题
// Multilingual titles
const titles = {
en: 'Categories',
zh: '分类'
};
// 获取当前语言的标题
// Get title for current language
const title = titles[lang] || titles[defaultLang];
---