refactor(blog): restore two-column index layout with sidebar
This commit is contained in:
@@ -3,32 +3,25 @@ import BlogLayout from '../../layouts/BlogLayout.astro';
|
|||||||
import BlogList from '../../components/blog/BlogList.astro';
|
import BlogList from '../../components/blog/BlogList.astro';
|
||||||
import CategoryCard from '../../components/blog/CategoryCard.astro';
|
import CategoryCard from '../../components/blog/CategoryCard.astro';
|
||||||
import TagCard from '../../components/blog/TagCard.astro';
|
import TagCard from '../../components/blog/TagCard.astro';
|
||||||
import Container from "../../components/ui/Container.astro";
|
import Container from '../../components/ui/Container.astro';
|
||||||
import { type BlogPost } from '@/types';
|
import { type BlogPost } from '@/types';
|
||||||
import { useTranslations } from '@/i18n/utils';
|
|
||||||
import { type Lang } from '@/types/i18n';
|
import { type Lang } from '@/types/i18n';
|
||||||
import { defaultLang } from '@/i18n/ui';
|
import { defaultLang } from '@/i18n/ui';
|
||||||
import { sortPostsByDate } from '@/utils/blog-utils';
|
import { sortPostsByDate } from '@/utils/blog-utils';
|
||||||
|
|
||||||
// Get current language environment using Astro.currentLocale
|
|
||||||
const lang = Astro.currentLocale as Lang || defaultLang;
|
const lang = Astro.currentLocale as Lang || defaultLang;
|
||||||
const t = useTranslations(lang);
|
|
||||||
|
|
||||||
// Read all blog posts using import.meta.glob
|
|
||||||
const allPosts = await import.meta.glob('./posts/*.md', { eager: true });
|
const allPosts = await import.meta.glob('./posts/*.md', { eager: true });
|
||||||
|
|
||||||
// Process blog post data
|
|
||||||
const blogPosts: BlogPost[] = Object.values(allPosts).map((post: any) => {
|
const blogPosts: BlogPost[] = Object.values(allPosts).map((post: any) => {
|
||||||
const slug = post.url?.split('/').filter(Boolean).pop() || '';
|
const slug = post.url?.split('/').filter(Boolean).pop() || '';
|
||||||
|
const defaultImage = 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=400&h=250&fit=crop&crop=center';
|
||||||
// Default image if not specified in frontmatter
|
|
||||||
const defaultImage = "https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=400&h=250&fit=crop&crop=center";
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: post.frontmatter.title,
|
title: post.frontmatter.title,
|
||||||
description: post.frontmatter.description || '',
|
description: post.frontmatter.description || '',
|
||||||
image: post.frontmatter.image || defaultImage,
|
image: post.frontmatter.image || defaultImage,
|
||||||
slug: slug,
|
slug,
|
||||||
tags: post.frontmatter.tags || [],
|
tags: post.frontmatter.tags || [],
|
||||||
tagId: post.frontmatter.tagId || [],
|
tagId: post.frontmatter.tagId || [],
|
||||||
category: Array.isArray(post.frontmatter.category) ? post.frontmatter.category : post.frontmatter.category ? [post.frontmatter.category] : [],
|
category: Array.isArray(post.frontmatter.category) ? post.frontmatter.category : post.frontmatter.category ? [post.frontmatter.category] : [],
|
||||||
@@ -38,14 +31,11 @@ const blogPosts: BlogPost[] = Object.values(allPosts).map((post: any) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort posts by date
|
|
||||||
const sortedBlogPosts = sortPostsByDate(blogPosts);
|
const sortedBlogPosts = sortPostsByDate(blogPosts);
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<BlogLayout title="Writing - Joey Z." description="Engineering notes on architecture, delivery, and AI-assisted development workflows.">
|
<BlogLayout title="Writing - Joey Z." description="Engineering notes on architecture, delivery, and AI-assisted development workflows.">
|
||||||
<main class="min-h-screen">
|
<main class="min-h-screen">
|
||||||
<!-- Header Section -->
|
|
||||||
<Container className="pt-24 pb-12">
|
<Container className="pt-24 pb-12">
|
||||||
<div class="text-center mb-16">
|
<div class="text-center mb-16">
|
||||||
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-primary to-primary dark:from-foreground dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent mb-6">
|
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-primary to-primary dark:from-foreground dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent mb-6">
|
||||||
@@ -57,19 +47,13 @@ const sortedBlogPosts = sortPostsByDate(blogPosts);
|
|||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<!-- Main Content -->
|
|
||||||
<Container className="pb-20">
|
<Container className="pb-20">
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
|
||||||
<!-- 侧边栏 -->
|
|
||||||
<div class="lg:col-span-1 space-y-8">
|
<div class="lg:col-span-1 space-y-8">
|
||||||
<!-- 分类卡片 -->
|
|
||||||
<CategoryCard lang="en" />
|
<CategoryCard lang="en" />
|
||||||
|
|
||||||
<!-- 标签卡片 -->
|
|
||||||
<TagCard lang="en" />
|
<TagCard lang="en" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Blog Posts -->
|
|
||||||
<div class="lg:col-span-3">
|
<div class="lg:col-span-3">
|
||||||
<BlogList posts={sortedBlogPosts} lang="en" />
|
<BlogList posts={sortedBlogPosts} lang="en" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,32 +3,25 @@ import BlogLayout from '../../../layouts/BlogLayout.astro';
|
|||||||
import BlogList from '../../../components/blog/BlogList.astro';
|
import BlogList from '../../../components/blog/BlogList.astro';
|
||||||
import CategoryCard from '../../../components/blog/CategoryCard.astro';
|
import CategoryCard from '../../../components/blog/CategoryCard.astro';
|
||||||
import TagCard from '../../../components/blog/TagCard.astro';
|
import TagCard from '../../../components/blog/TagCard.astro';
|
||||||
import Container from "../../../components/ui/Container.astro";
|
import Container from '../../../components/ui/Container.astro';
|
||||||
import { type BlogPost } from '@/types';
|
import { type BlogPost } from '@/types';
|
||||||
import { useTranslations } from '@/i18n/utils';
|
|
||||||
import { type Lang } from '@/types/i18n';
|
import { type Lang } from '@/types/i18n';
|
||||||
import { defaultLang } from '@/i18n/ui';
|
import { defaultLang } from '@/i18n/ui';
|
||||||
import { sortPostsByDate, extractCategories, extractTags } from '@/utils/blog-utils';
|
import { sortPostsByDate } from '@/utils/blog-utils';
|
||||||
|
|
||||||
// 使用Astro.currentLocale获取当前语言环境
|
|
||||||
const lang = Astro.currentLocale as Lang || defaultLang;
|
const lang = Astro.currentLocale as Lang || defaultLang;
|
||||||
const t = useTranslations(lang);
|
|
||||||
|
|
||||||
// 使用import.meta.glob读取所有中文博客文章
|
|
||||||
const allPosts = await import.meta.glob('./posts/*.md', { eager: true });
|
const allPosts = await import.meta.glob('./posts/*.md', { eager: true });
|
||||||
|
|
||||||
// 处理博客文章数据
|
|
||||||
const blogPosts: BlogPost[] = Object.values(allPosts).map((post: any) => {
|
const blogPosts: BlogPost[] = Object.values(allPosts).map((post: any) => {
|
||||||
const slug = post.url?.split('/').filter(Boolean).pop() || '';
|
const slug = post.url?.split('/').filter(Boolean).pop() || '';
|
||||||
|
const defaultImage = 'https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=400&h=250&fit=crop&crop=center';
|
||||||
// 获取文章的默认图片,如果frontmatter中没有指定
|
|
||||||
const defaultImage = "https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=400&h=250&fit=crop&crop=center";
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: post.frontmatter.title,
|
title: post.frontmatter.title,
|
||||||
description: post.frontmatter.description || '',
|
description: post.frontmatter.description || '',
|
||||||
image: post.frontmatter.image || defaultImage,
|
image: post.frontmatter.image || defaultImage,
|
||||||
slug: slug,
|
slug,
|
||||||
tags: post.frontmatter.tags || [],
|
tags: post.frontmatter.tags || [],
|
||||||
tagId: post.frontmatter.tagId || [],
|
tagId: post.frontmatter.tagId || [],
|
||||||
category: Array.isArray(post.frontmatter.category) ? post.frontmatter.category : post.frontmatter.category ? [post.frontmatter.category] : [],
|
category: Array.isArray(post.frontmatter.category) ? post.frontmatter.category : post.frontmatter.category ? [post.frontmatter.category] : [],
|
||||||
@@ -38,26 +31,11 @@ const blogPosts: BlogPost[] = Object.values(allPosts).map((post: any) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// 使用工具函数按日期排序
|
|
||||||
const sortedBlogPosts = sortPostsByDate(blogPosts);
|
const sortedBlogPosts = sortPostsByDate(blogPosts);
|
||||||
|
|
||||||
// 提取所有文章的分类和标签信息(用于侧边栏)
|
|
||||||
const allPostsArray = Object.values(allPosts).map((post: any) => ({
|
|
||||||
category: post.frontmatter.category || [],
|
|
||||||
categoryId: post.frontmatter.categoryId || [],
|
|
||||||
tags: post.frontmatter.tags || [],
|
|
||||||
tagId: post.frontmatter.tagId || []
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 使用工具函数提取分类和标签
|
|
||||||
const categories = extractCategories(allPostsArray);
|
|
||||||
const tags = extractTags(allPostsArray);
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<BlogLayout title="写作 - Joey Z." description="聚焦架构设计、工程交付与 AI 协作开发实践的技术写作。">
|
<BlogLayout title="写作 - Joey Z." description="聚焦架构设计、工程交付与 AI 协作开发实践的技术写作。">
|
||||||
<main class="min-h-screen">
|
<main class="min-h-screen">
|
||||||
<!-- 头部区域 -->
|
|
||||||
<Container className="pt-24 pb-12">
|
<Container className="pt-24 pb-12">
|
||||||
<div class="text-center mb-16">
|
<div class="text-center mb-16">
|
||||||
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-primary to-primary dark:from-foreground dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent mb-6">
|
<h1 class="text-5xl md:text-6xl font-bold bg-gradient-to-r from-foreground via-primary to-primary dark:from-foreground dark:via-blue-200 dark:to-orange-300 bg-clip-text text-transparent mb-6">
|
||||||
@@ -69,20 +47,13 @@ const tags = extractTags(allPostsArray);
|
|||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<!-- 主要内容 -->
|
|
||||||
<Container className="pb-20">
|
<Container className="pb-20">
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
|
||||||
<!-- 侧边栏 -->
|
|
||||||
<div class="lg:col-span-1 space-y-8">
|
<div class="lg:col-span-1 space-y-8">
|
||||||
<!-- 分类卡片 -->
|
|
||||||
<CategoryCard lang="zh" />
|
<CategoryCard lang="zh" />
|
||||||
|
|
||||||
<!-- 标签卡片 -->
|
|
||||||
<TagCard lang="zh" />
|
<TagCard lang="zh" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 博客文章 -->
|
|
||||||
<div class="lg:col-span-3">
|
<div class="lg:col-span-3">
|
||||||
<BlogList posts={sortedBlogPosts} lang="zh" />
|
<BlogList posts={sortedBlogPosts} lang="zh" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user