diff --git a/src/components/BlogList.tsx b/src/components/BlogList.tsx deleted file mode 100644 index 6189844..0000000 --- a/src/components/BlogList.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import React from 'react'; -import { useTranslations, type Lang } from '@/i18n/utils'; -import { type BlogPost, type BlogListProps } from '@/types'; - -/** - * Reusable blog list component that displays blog posts in a grid layout - * @param posts - Array of blog posts to display - * @param lang - Current language for internationalization - * @param baseUrl - Base URL for blog post links - */ -export default function BlogList({ posts, lang, baseUrl = '/blog/posts/' }: BlogListProps) { - const t = useTranslations(lang); - - // Adjust base URL for Chinese language - const postBaseUrl = lang === 'zh' ? '/zh/blog/posts/' : baseUrl; - - // Get localized "Read More" text - const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More'; - - return ( -
- {posts.map((post, index) => ( -
-
-
- {/* Featured Image */} -
- {post.title} -
-
- - {/* Content */} -
-
-

- - {post.title} - -

- -

- {post.description} -

- - {/* Tags */} -
- {post.tags.map((tag, tagIndex) => { - // 使用 tagId 如果存在,否则使用 tag 本身 - const tagRoute = post.tagId && Array.isArray(post.tagId) && tagIndex < post.tagId.length - ? post.tagId[tagIndex] - : tag.toLowerCase(); - - return ( - - # {tag} - - ); - })} -
-
- - {/* Meta Info */} -
-
- - - - - {post.date} - - {post.readTime} -
- - - {readMoreText} - - - - -
-
-
-
-
- ))} -
- ); -} - -/** - * CSS styles for line clamping (to be included in global styles) - */ -export const blogListStyles = ` -.line-clamp-3 { - display: -webkit-box; - -webkit-line-clamp: 3; - -webkit-box-orient: vertical; - overflow: hidden; -} -`; \ No newline at end of file diff --git a/src/components/blog/BlogList.astro b/src/components/blog/BlogList.astro new file mode 100644 index 0000000..636bbdd --- /dev/null +++ b/src/components/blog/BlogList.astro @@ -0,0 +1,192 @@ +--- +import { type BlogPost, type Lang } from '@/types'; + +interface Props { + posts?: BlogPost[]; + lang: Lang; + baseUrl?: string; + category?: string; + tag?: string; +} + +// 获取组件属性 +const { lang, baseUrl, category, tag, posts: providedPosts } = Astro.props; + +// 如果没有提供 posts,则直接从文件系统读取 +let posts: BlogPost[] = []; + +if (providedPosts) { + // 使用提供的文章列表 + posts = providedPosts; +} else { + // 根据当前语言读取博客文章 + let allPosts = []; + if (lang === 'zh') { + // 读取中文博客文章 + allPosts = await Astro.glob('../zh/blog/posts/*.md'); + } else { + // 读取英文博客文章 + allPosts = await Astro.glob('../blog/posts/*.md'); + } + + // 处理博客文章数据 + posts = allPosts.map((post) => { + const slug = post.url?.split('/').filter(Boolean).pop() || ''; + + // 获取文章的默认图片,如果frontmatter中没有指定 + const defaultImage = "https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=400&h=250&fit=crop&crop=center"; + + return { + title: post.frontmatter.title, + description: post.frontmatter.description || '', + image: post.frontmatter.image || defaultImage, + slug: slug, + tags: post.frontmatter.tags || [], + tagId: post.frontmatter.tagId || [], + category: Array.isArray(post.frontmatter.category) ? post.frontmatter.category : post.frontmatter.category ? [post.frontmatter.category] : [], + categoryId: Array.isArray(post.frontmatter.categoryId) ? post.frontmatter.categoryId : post.frontmatter.categoryId ? [post.frontmatter.categoryId] : [], + date: post.frontmatter.date || post.frontmatter.pubDate || '', + readTime: post.frontmatter.readTime || post.frontmatter.readingTime || '5 min read', + }; + }); + + // 按日期排序 + posts = posts + .filter(post => post.date) // 过滤掉没有日期的文章 + .sort((a, b) => { + const dateA = new Date(a.date).getTime(); + const dateB = new Date(b.date).getTime(); + return dateB - dateA; // 降序排列,最新的文章在前 + }); +} + +// 如果指定了分类,则过滤文章 +if (category) { + posts = posts.filter(post => { + // 优先检查文章是否包含当前分类ID + if (post.categoryId && Array.isArray(post.categoryId)) { + return post.categoryId.some(catId => + catId.toLowerCase() === category.toLowerCase() + ); + } + // 如果没有 categoryId,则检查 category + else if (post.category && Array.isArray(post.category)) { + return post.category.some(cat => + cat.toLowerCase() === category.toLowerCase() + ); + } + return false; + }); +} + +// 如果指定了标签,则过滤文章 +if (tag) { + posts = posts.filter(post => { + // 优先检查文章是否包含当前标签ID + if (post.tagId && Array.isArray(post.tagId)) { + return post.tagId.some(tagId => + tagId.toLowerCase() === tag.toLowerCase() + ); + } + // 如果没有 tagId,则检查 tags + else if (post.tags && Array.isArray(post.tags)) { + return post.tags.some(postTag => + postTag.toLowerCase() === tag.toLowerCase() + ); + } + return false; + }); +} + +// 调整基础URL +const postBaseUrl = lang === 'zh' ? '/zh/blog/posts/' : '/blog/posts/'; + +// 获取本地化的"阅读更多"文本 +const readMoreText = lang === 'zh' ? '阅读更多' : 'Read More'; +--- + +
+ {posts.map((post, index) => ( +
+
+
+ {/* Featured Image */} +
+ {post.title} +
+
+ + {/* Content */} +
+
+

+ + {post.title} + +

+ +

+ {post.description} +

+ + {/* Tags */} +
+ {post.tags.map((tag, tagIndex) => { + // 使用 tagId 如果存在,否则使用 tag 本身 + const tagRoute = post.tagId && Array.isArray(post.tagId) && tagIndex < post.tagId.length + ? post.tagId[tagIndex] + : tag.toLowerCase(); + + return ( + + # {tag} + + ); + })} +
+
+ + {/* Meta Info */} +
+
+ + + + + {post.date} + + {post.readTime} +
+ + + {readMoreText} + + + + +
+
+
+
+
+ ))} +
+ + \ No newline at end of file diff --git a/src/components/blog/CategoryCard.astro b/src/components/blog/CategoryCard.astro new file mode 100644 index 0000000..96588e4 --- /dev/null +++ b/src/components/blog/CategoryCard.astro @@ -0,0 +1,95 @@ +--- +// 导入必要的依赖 +import { type Lang } from '@/i18n/utils'; +import { defaultLang } from '@/i18n/ui'; + +// 定义组件属性 +interface Props { + lang?: Lang; + currentCategory?: string; +} + +// 获取组件属性 +const { lang = defaultLang, currentCategory = '' } = Astro.props; + +// 确定基础URL路径 +const baseUrl = lang === defaultLang ? '/blog' : `/${lang}/blog`; + +// 读取所有博客文章 - 根据语言选择不同的静态路径 +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'); +} + +// 收集所有分类 +const allCategories = new Set(); + +// 处理所有文章的分类 +const categoryMap = new Map(); // 存储 categoryId 到 category 名称的映射 + +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()); + } + }); + } + } +}); + + +// 转换为数组并排序 +const categories = Array.from(allCategories).sort(); + +// 多语言标题 +const titles = { + en: 'Categories', + zh: '分类' +}; + +// 获取当前语言的标题 +const title = titles[lang] || titles[defaultLang]; +--- + +
+

+ + + + {title} +

+
+ {categories.map((cat) => { + const categoryId = categoryMap.get(cat) || cat.toLowerCase(); + return ( + + {cat} + + ); + })} +
+
\ No newline at end of file diff --git a/src/components/blog/TagCard.astro b/src/components/blog/TagCard.astro new file mode 100644 index 0000000..07cd490 --- /dev/null +++ b/src/components/blog/TagCard.astro @@ -0,0 +1,92 @@ +--- +// 导入必要的依赖 +import { type Lang } from '@/i18n/utils'; +import { defaultLang } from '@/i18n/ui'; + +// 定义组件属性 +interface Props { + lang?: Lang; + currentTag?: string; +} + +// 获取组件属性 +const { lang = defaultLang, currentTag = '' } = Astro.props; + +// 确定基础URL路径 +const baseUrl = lang === defaultLang ? '/blog' : `/${lang}/blog`; + +// 读取所有博客文章 - 根据语言选择不同的静态路径 +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'); +} + +// 收集所有标签 +const allTags = new Set(); +const tagMap = new Map(); // 存储 tag 到 tagId 的映射 + +// 处理所有文章的标签 +allPosts.forEach(post => { + // 处理标签 + if (post.frontmatter?.tags && Array.isArray(post.frontmatter.tags)) { + const tags = post.frontmatter.tags; + const tagIds = Array.isArray(post.frontmatter.tagId) + ? post.frontmatter.tagId + : post.frontmatter.tagId ? [post.frontmatter.tagId] : []; + + // 如果有 tagId,则使用 tagId 和 tag 的映射 + if (tagIds.length > 0 && tagIds.length === tags.length) { + tags.forEach((tag, index) => { + if (tag && tagIds[index]) { + allTags.add(tag); + tagMap.set(tag, tagIds[index]); + } + }); + } else { + // 如果没有 tagId 或长度不匹配,则使用 tag 名称作为 ID + tags.forEach(tag => { + if (tag) { + allTags.add(tag); + tagMap.set(tag, tag.toLowerCase()); + } + }); + } + } +}); + +// 转换为数组,添加 # 前缀,并排序 +const tags = Array.from(allTags).map(tag => `# ${tag}`).sort(); + +// 多语言标题 +const titles = { + en: '# Tags', + zh: '# 标签' +}; + +// 获取当前语言的标题 +const title = titles[lang] || titles[defaultLang]; +--- + +
+

+ + + + {title} +

+
+ {tags.map((tagItem) => { + const tagName = tagItem.slice(2); // 去掉 '# ' 前缀 + const tagId = tagMap.get(tagName) || tagName.toLowerCase(); + const isCurrentTag = tagId === currentTag.toLowerCase(); + return ( + + {tagItem} + + ); + })} +
+
\ No newline at end of file diff --git a/src/pages/blog/categories/[category].astro b/src/pages/blog/categories/[category].astro index c489da4..4321dc0 100644 --- a/src/pages/blog/categories/[category].astro +++ b/src/pages/blog/categories/[category].astro @@ -1,6 +1,8 @@ --- import BlogLayout from '../../../layouts/BlogLayout.astro'; -import BlogList from '../../../components/BlogList.tsx'; +import BlogList from '../../../components/blog/BlogList.astro'; +import CategoryCard from '../../../components/blog/CategoryCard.astro'; +import TagCard from '../../../components/blog/TagCard.astro'; import { type Lang } from '@/i18n/utils'; import { defaultLang } from '@/i18n/ui'; import { type BlogPost } from '@/types'; @@ -137,12 +139,33 @@ allPosts.forEach(post => { const categories = Array.from(allCategories).sort(); const tags = Array.from(allTags).map(tag => `# ${tag}`).sort(); -// 获取当前分类的格式化名称(首字母大写) -const formattedCategory = decodedCategory.charAt(0).toUpperCase() + decodedCategory.slice(1); +// 查找与当前分类ID匹配的分类名称 +let displayCategoryName = ""; + +// 从博客文章中查找匹配的分类名称 +for (const post of allPosts) { + if (post.frontmatter?.categoryId && Array.isArray(post.frontmatter.categoryId) && + post.frontmatter?.category && Array.isArray(post.frontmatter.category)) { + // 查找分类ID和分类名称的索引匹配 + const categoryIndex = post.frontmatter.categoryId.findIndex(id => + id.toLowerCase() === decodedCategory.toLowerCase() + ); + + if (categoryIndex !== -1 && categoryIndex < post.frontmatter.category.length) { + displayCategoryName = post.frontmatter.category[categoryIndex]; + break; + } + } +} + +// 如果没有找到匹配的分类名称,则使用分类ID并格式化(首字母大写) +if (!displayCategoryName) { + displayCategoryName = decodedCategory.charAt(0).toUpperCase() + decodedCategory.slice(1); +} // 动态生成页面标题和描述 -const pageTitle = `${formattedCategory} - Blog | Joy Zhao`; -const pageDescription = `Explore articles about ${formattedCategory}. Dive into my thoughts on ${formattedCategory} and related topics.`; +const pageTitle = `${displayCategoryName} - Blog | Joy Zhao`; +const pageDescription = `Explore articles about ${displayCategoryName}. Dive into my thoughts on ${displayCategoryName} and related topics.`; --- @@ -151,10 +174,10 @@ const pageDescription = `Explore articles about ${formattedCategory}. Dive into

- Category: {formattedCategory} + Category: {displayCategoryName}

- Explore articles about {formattedCategory}. Found {sortedBlogPosts.length} article{sortedBlogPosts.length !== 1 ? 's' : ''}. + Explore articles about {displayCategoryName}. Found {sortedBlogPosts.length} article{sortedBlogPosts.length !== 1 ? 's' : ''}.

@@ -164,47 +187,18 @@ const pageDescription = `Explore articles about ${formattedCategory}. Dive into
- -
-

- - - - Categories -

-
- {categories.map((cat) => ( - - {cat} - - ))} -
-
+ + + + + - -
-

- - - - # Tags -

-
- {tags.map((tag) => ( - - {tag} - - ))} -
-
{sortedBlogPosts.length > 0 ? ( - + ) : (

No articles found

diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro index a36bfc1..f9f589f 100644 --- a/src/pages/blog/index.astro +++ b/src/pages/blog/index.astro @@ -1,9 +1,11 @@ --- import BlogLayout from '../../layouts/BlogLayout.astro'; -import BlogList from '../../components/BlogList.tsx'; +import BlogList from '../../components/blog/BlogList.astro'; +import CategoryCard from '../../components/blog/CategoryCard.astro'; +import TagCard from '../../components/blog/TagCard.astro'; +import { type BlogPost } from '@/types'; import { type Lang } from '@/i18n/utils'; import { defaultLang } from '@/i18n/ui'; -import { type BlogPost } from '@/types'; // 使用Astro.currentLocale获取当前语言环境 const lang = Astro.currentLocale as Lang || defaultLang; @@ -89,48 +91,18 @@ const tags = Array.from(allTags).map(tag => `# ${tag}`).sort();
- +
- -
-

- - - - Categories -

-
- {categories.map((category) => ( - - {category} - - ))} -
-
+ + - -
-

- - - - # Tags -

-
- {tags.map((tag) => ( - - {tag} - - ))} -
-
+ +
- +
diff --git a/src/pages/blog/tags/[tag].astro b/src/pages/blog/tags/[tag].astro index a296a56..b7f488d 100644 --- a/src/pages/blog/tags/[tag].astro +++ b/src/pages/blog/tags/[tag].astro @@ -1,6 +1,8 @@ --- import BlogLayout from '../../../layouts/BlogLayout.astro'; -import BlogList from '../../../components/BlogList.tsx'; +import BlogList from '../../../components/blog/BlogList.astro'; +import CategoryCard from '../../../components/blog/CategoryCard.astro'; +import TagCard from '../../../components/blog/TagCard.astro'; import { type Lang } from '@/i18n/utils'; import { defaultLang } from '@/i18n/ui'; import { type BlogPost } from '@/types'; @@ -125,12 +127,33 @@ allPosts.forEach(post => { const categories = Array.from(allCategories).sort(); const tags = Array.from(allTags).map(postTag => `# ${postTag}`).sort(); -// 获取当前标签的格式化名称(首字母大写) -const formattedTag = decodedTag.charAt(0).toUpperCase() + decodedTag.slice(1); +// 查找与当前标签ID匹配的标签名称 +let displayTagName = ""; + +// 从博客文章中查找匹配的标签名称 +for (const post of allPosts) { + if (post.frontmatter?.tagId && Array.isArray(post.frontmatter.tagId) && + post.frontmatter?.tags && Array.isArray(post.frontmatter.tags)) { + // 查找标签ID和标签名称的索引匹配 + const tagIndex = post.frontmatter.tagId.findIndex(id => + id.toLowerCase() === decodedTag.toLowerCase() + ); + + if (tagIndex !== -1 && tagIndex < post.frontmatter.tags.length) { + displayTagName = post.frontmatter.tags[tagIndex]; + break; + } + } +} + +// 如果没有找到匹配的标签名称,则使用标签ID并格式化(首字母大写) +if (!displayTagName) { + displayTagName = decodedTag.charAt(0).toUpperCase() + decodedTag.slice(1); +} // 动态生成页面标题和描述 -const pageTitle = `# ${formattedTag} - Blog | Joy Zhao`; -const pageDescription = `Explore articles tagged with # ${formattedTag}. Dive into my thoughts on ${formattedTag} and related topics.`; +const pageTitle = `# ${displayTagName} - Blog | Joy Zhao`; +const pageDescription = `Explore articles tagged with # ${displayTagName}. Dive into my thoughts on ${displayTagName} and related topics.`; --- @@ -139,10 +162,10 @@ const pageDescription = `Explore articles tagged with # ${formattedTag}. Dive in

- Tag: # {formattedTag} + Tag: # {displayTagName}

- Explore articles tagged with # {formattedTag}. Found {sortedBlogPosts.length} article{sortedBlogPosts.length !== 1 ? 's' : ''}. + Explore articles tagged with # {displayTagName}. Found {sortedBlogPosts.length} article{sortedBlogPosts.length !== 1 ? 's' : ''}.

@@ -152,51 +175,18 @@ const pageDescription = `Explore articles tagged with # ${formattedTag}. Dive in
- -
-

- - - - Categories -

-
- {categories.map((cat) => ( - - {cat} - - ))} -
-
+ + + + + - -
-

- - - - # Tags -

-
- {tags.map((tagItem) => { - const tagName = tagItem.slice(2).toLowerCase(); - const isCurrentTag = tagName === decodedTag.toLowerCase(); - return ( - - {tagItem} - - ); - })} -
-
{sortedBlogPosts.length > 0 ? ( - + ) : (

No articles found

diff --git a/src/pages/zh/blog/categories/[category].astro b/src/pages/zh/blog/categories/[category].astro index 0c0918a..1fdcdf2 100644 --- a/src/pages/zh/blog/categories/[category].astro +++ b/src/pages/zh/blog/categories/[category].astro @@ -1,6 +1,8 @@ --- import BlogLayout from '../../../../layouts/BlogLayout.astro'; -import BlogList from '../../../../components/BlogList.tsx'; +import BlogList from '../../../../components/blog/BlogList.astro'; +import CategoryCard from '../../../../components/blog/CategoryCard.astro'; +import TagCard from '../../../../components/blog/TagCard.astro'; import { type Lang } from '@/i18n/utils'; import { defaultLang } from '@/i18n/ui'; import { type BlogPost } from '@/types'; @@ -137,12 +139,33 @@ allPosts.forEach(post => { const categories = Array.from(allCategories).sort(); const tags = Array.from(allTags).map(tag => `# ${tag}`).sort(); -// 获取当前分类的格式化名称(首字母大写) -const formattedCategory = decodedCategory.charAt(0).toUpperCase() + decodedCategory.slice(1); +// 查找与当前分类ID匹配的分类名称 +let displayCategoryName = ""; + +// 从博客文章中查找匹配的分类名称 +for (const post of allPosts) { + if (post.frontmatter?.categoryId && Array.isArray(post.frontmatter.categoryId) && + post.frontmatter?.category && Array.isArray(post.frontmatter.category)) { + // 查找分类ID和分类名称的索引匹配 + const categoryIndex = post.frontmatter.categoryId.findIndex(id => + id.toLowerCase() === decodedCategory.toLowerCase() + ); + + if (categoryIndex !== -1 && categoryIndex < post.frontmatter.category.length) { + displayCategoryName = post.frontmatter.category[categoryIndex]; + break; + } + } +} + +// 如果没有找到匹配的分类名称,则使用分类ID并格式化(首字母大写) +if (!displayCategoryName) { + displayCategoryName = decodedCategory.charAt(0).toUpperCase() + decodedCategory.slice(1); +} // 动态生成页面标题和描述 -const pageTitle = `${formattedCategory} - 博客 | 赵桂阳`; -const pageDescription = `探索关于${formattedCategory}的文章。深入了解我对${formattedCategory}和相关主题的思考。`; +const pageTitle = `${displayCategoryName} - 博客 | 赵桂阳`; +const pageDescription = `探索关于${displayCategoryName}的文章。深入了解我对${displayCategoryName}和相关主题的思考。`; --- @@ -151,10 +174,10 @@ const pageDescription = `探索关于${formattedCategory}的文章。深入了

- 分类: {formattedCategory} + 分类: {displayCategoryName}

- 探索关于{formattedCategory}的文章。找到 {sortedBlogPosts.length} 篇文章。 + 探索关于{displayCategoryName}的文章。找到 {sortedBlogPosts.length} 篇文章。

@@ -164,47 +187,18 @@ const pageDescription = `探索关于${formattedCategory}的文章。深入了
- -
-

- - - - 分类 -

-
- {categories.map((cat) => ( - - {cat} - - ))} -
-
+ + + + + - -
-

- - - - # 标签 -

-
- {tags.map((tag) => ( - - {tag} - - ))} -
-
{sortedBlogPosts.length > 0 ? ( - + ) : (

未找到文章

diff --git a/src/pages/zh/blog/index.astro b/src/pages/zh/blog/index.astro index f4a33a8..68a8dd7 100644 --- a/src/pages/zh/blog/index.astro +++ b/src/pages/zh/blog/index.astro @@ -1,9 +1,11 @@ --- import BlogLayout from '../../../layouts/BlogLayout.astro'; -import BlogList from '../../../components/BlogList.tsx'; +import BlogList from '../../../components/blog/BlogList.astro'; +import CategoryCard from '../../../components/blog/CategoryCard.astro'; +import TagCard from '../../../components/blog/TagCard.astro'; +import { type BlogPost } from '@/types'; import { type Lang } from '@/i18n/utils'; import { defaultLang } from '@/i18n/ui'; -import { type BlogPost } from '@/types'; // 使用Astro.currentLocale获取当前语言环境 const lang = Astro.currentLocale as Lang || defaultLang; @@ -91,46 +93,17 @@ const tags = Array.from(allTags).map(tag => `# ${tag}`).sort();
- -
-

- - - - 分类 -

-
- {categories.map((category) => ( - - {category} - - ))} -
-
+ + + + + - -
-

- - - - # 标签 -

-
- {tags.map((tag) => ( - - {tag} - - ))} -
-
- +
diff --git a/src/pages/zh/blog/tags/[tag].astro b/src/pages/zh/blog/tags/[tag].astro index 2d4f985..8f0aca4 100644 --- a/src/pages/zh/blog/tags/[tag].astro +++ b/src/pages/zh/blog/tags/[tag].astro @@ -1,6 +1,8 @@ --- import BlogLayout from '../../../../layouts/BlogLayout.astro'; -import BlogList from '../../../../components/BlogList.tsx'; +import BlogList from '../../../../components/blog/BlogList.astro'; +import CategoryCard from '../../../../components/blog/CategoryCard.astro'; +import TagCard from '../../../../components/blog/TagCard.astro'; import { type Lang } from '@/i18n/utils'; import { defaultLang } from '@/i18n/ui'; import { type BlogPost } from '@/types'; @@ -125,12 +127,33 @@ allPosts.forEach(post => { const categories = Array.from(allCategories).sort(); const tags = Array.from(allTags).map(postTag => `# ${postTag}`).sort(); -// 获取当前标签的格式化名称(首字母大写) -const formattedTag = decodedTag.charAt(0).toUpperCase() + decodedTag.slice(1); +// 查找与当前标签ID匹配的标签名称 +let displayTagName = ""; + +// 从博客文章中查找匹配的标签名称 +for (const post of allPosts) { + if (post.frontmatter?.tagId && Array.isArray(post.frontmatter.tagId) && + post.frontmatter?.tags && Array.isArray(post.frontmatter.tags)) { + // 查找标签ID和标签名称的索引匹配 + const tagIndex = post.frontmatter.tagId.findIndex(id => + id.toLowerCase() === decodedTag.toLowerCase() + ); + + if (tagIndex !== -1 && tagIndex < post.frontmatter.tags.length) { + displayTagName = post.frontmatter.tags[tagIndex]; + break; + } + } +} + +// 如果没有找到匹配的标签名称,则使用标签ID并格式化(首字母大写) +if (!displayTagName) { + displayTagName = decodedTag.charAt(0).toUpperCase() + decodedTag.slice(1); +} // 动态生成页面标题和描述 -const pageTitle = `# ${formattedTag} - 博客 | Joy Zhao`; -const pageDescription = `浏览带有 # ${formattedTag} 标签的文章。深入了解我关于 ${formattedTag} 及相关主题的想法。`; +const pageTitle = `# ${displayTagName} - 博客 | Joy Zhao`; +const pageDescription = `浏览带有 # ${displayTagName} 标签的文章。深入了解我关于 ${displayTagName} 及相关主题的想法。`; --- @@ -139,10 +162,10 @@ const pageDescription = `浏览带有 # ${formattedTag} 标签的文章。深入

- 标签: # {formattedTag} + 标签: # {displayTagName}

- 浏览带有 # {formattedTag} 标签的文章。找到 {sortedBlogPosts.length} 篇文章。 + 浏览带有 # {displayTagName} 标签的文章。找到 {sortedBlogPosts.length} 篇文章。

@@ -150,53 +173,20 @@ const pageDescription = `浏览带有 # ${formattedTag} 标签的文章。深入
- +
- -
-

- - - - 分类 -

-
- {categories.map((cat) => ( - - {cat} - - ))} -
-
+ + + + + - -
-

- - - - # 标签 -

-
- {tags.map((tagItem) => { - const tagName = tagItem.slice(2).toLowerCase(); - const isCurrentTag = tagName === decodedTag.toLowerCase(); - return ( - - {tagItem} - - ); - })} -
-
{sortedBlogPosts.length > 0 ? ( - + ) : (

未找到文章

diff --git a/src/styles/global.css b/src/styles/global.css index ecd03ad..9a513ed 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -122,6 +122,7 @@ @layer base { * { @apply border-border outline-ring/50; + line-height: 1.2; } body { @apply bg-background text-foreground;