feat(taxonomy): add unified taxonomy page layout and utilities

refactor blog category and tag pages to use new TaxonomyPageLayout
add utility functions for processing taxonomy page data
pass lang prop to GlassHeader component
This commit is contained in:
joyzhao
2025-06-19 17:22:27 +08:00
parent 7951121c7f
commit 21fba08741
7 changed files with 262 additions and 383 deletions

View File

@@ -204,4 +204,106 @@ export function extractTags(posts: any[]): Map<string, string> {
*/
export function getBlogBaseUrl(lang: Lang): string {
return lang === defaultLang ? '/blog' : `/${lang}/blog`;
}
/**
* Process raw blog post data from import.meta.glob
* @param allPosts - Raw posts data from import.meta.glob
* @param lang - Current language
* @returns Processed blog posts array
*/
export function processRawBlogPosts(allPosts: Record<string, any>[] | any[], lang: Lang): BlogPost[] {
// Process blog post data
const posts: BlogPost[] = allPosts.map((post: any) => {
const slug = post.url?.split('/').filter(Boolean).pop() || '';
// Default image if not specified in frontmatter
const defaultImage = "https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=400&h=250&fit=crop&crop=center";
// Default read time text based on language
const defaultReadTime = lang === 'zh' ? '5 分钟阅读' : '5 min read';
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 || defaultReadTime,
url: post.url || '',
};
});
return posts;
}
/**
* Extract post metadata for categories and tags
* @param posts - Array of blog posts
* @returns Array of post metadata
*/
export function extractPostMetadata(posts: any[]) {
return posts.map((post: any) => ({
category: post.frontmatter?.category || [],
categoryId: post.frontmatter?.categoryId || [],
tags: post.frontmatter?.tags || [],
tagId: post.frontmatter?.tagId || []
}));
}
/**
* Get all blog posts with processing for a taxonomy page (category or tag)
* @param lang - Current language
* @param options - Additional options for processing
* @returns Object containing processed posts and metadata
*/
export async function getTaxonomyPageData(lang: Lang, options?: {
category?: string;
tag?: string;
}) {
// Read all blog posts
// Note: import.meta.glob only accepts literal strings, not variables
let allPosts;
// Use specific glob patterns based on language
if (lang === 'zh') {
allPosts = await import.meta.glob('/src/pages/zh/blog/posts/*.{md,mdx}', { eager: true });
} else {
allPosts = await import.meta.glob('/src/pages/blog/posts/*.{md,mdx}', { eager: true });
}
// Process blog post data
const blogPosts = processRawBlogPosts(Object.values(allPosts), lang);
// Apply filters if specified
let filteredPosts = blogPosts;
if (options?.category) {
filteredPosts = filterPostsByCategory(filteredPosts, options.category);
}
if (options?.tag) {
filteredPosts = filterPostsByTag(filteredPosts, options.tag);
}
// Sort posts by date
const sortedBlogPosts = sortPostsByDate(filteredPosts);
// Extract categories and tags from all posts for sidebar
const allPostsMetadata = extractPostMetadata(Object.values(allPosts));
// Get categories and tags for sidebar
const categories = extractCategories(allPostsMetadata);
const tags = extractTags(allPostsMetadata);
return {
posts: sortedBlogPosts,
categories,
tags,
allPosts
};
}