LogoMkSaaS文档

博客

学习如何创建、管理和自定义支持多语言的博客文章

MkSaaS 包含一个基于 Fumadocs MDX 构建的强大博客系统。博客系统支持多语言内容、分类、作者和丰富的内容格式,非常适合 SaaS 营销、公告、教程和知识库文章。

Blog

博客系统架构

博客系统使用 Fumadocs MDX 构建,并与国际化集成。

blog-card.tsx
blog-grid.tsx
blog-category-filter.tsx
blog-toc.tsx
source.ts
source.config.ts

源配置

博客系统在 source.config.ts 文件中使用 Fumadocs MDX 配置:

source.config.ts
import { defineCollections, frontmatterSchema } from 'fumadocs-mdx/config';
import { z } from 'zod';

// 博客文章集合
export const blog = defineCollections({
  type: 'doc',
  dir: 'content/blog',
  schema: frontmatterSchema.extend({
    image: z.string(),
    date: z.string().date(),
    published: z.boolean().default(true),
    categories: z.array(z.string()),
    author: z.string(),
  }),
});

// 博客作者集合
export const author = defineCollections({
  type: 'doc',
  dir: 'content/author',
  schema: z.object({
    name: z.string(),
    avatar: z.string(),
    description: z.string().optional(),
  }),
});

// 博客分类集合
export const category = defineCollections({
  type: 'doc',
  dir: 'content/category',
  schema: z.object({
    name: z.string(),
    description: z.string().optional(),
  }),
});

然后在 src/lib/source.ts 中使用 Fumadocs 加载器加载博客文章、作者和分类:

src/lib/source.ts
import { type InferPageType, loader } from 'fumadocs-core/source';
import { createMDXSource } from 'fumadocs-mdx';
import { author, blog, category } from '../../../.source';
import { docsI18nConfig } from './i18n';

/**
 * 博客文章源
 */
export const blogSource = loader({
  baseUrl: '/blog',
  i18n: docsI18nConfig,
  source: createMDXSource(blog),
});

/**
 * 博客作者源
 */
export const authorSource = loader({
  baseUrl: '/author',
  i18n: docsI18nConfig,
  source: createMDXSource(author),
});

/**
 * 博客分类源
 */
export const categorySource = loader({
  baseUrl: '/category',
  i18n: docsI18nConfig,
  source: createMDXSource(category),
});

// 类型定义
export type BlogType = InferPageType<typeof blogSource>;
export type AuthorType = InferPageType<typeof authorSource>;
export type CategoryType = InferPageType<typeof categorySource>;

创建博客内容

添加新作者

content/author 目录中创建新的 MDX 文件:

content/author/john-doe.mdx
---
name: John Doe
avatar: /images/authors/john-doe.jpg
---

添加新分类

content/category 目录中创建新的 MDX 文件:

content/category/tutorial.mdx
---
name: Tutorial
description: Step-by-step guides to learn new features
---

添加新博客文章

content/blog 目录中创建新的 MDX 文件:

content/blog/my-first-post.mdx
---
title: My First Blog Post
description: This is a brief description of my first blog post.
image: /images/blog/my-first-post.jpg
date: "2023-12-01"
published: true
categories: ["tutorial", "announcement"]
author: "mksaas"
---

# 介绍

这是我的第一篇博客文章。在这里我将谈论一些有趣的事情。

## 第一部分

这里是一些内容...

## 第二部分

这里是更多内容...

多语言支持

MkSaaS 博客系统完全支持国际化。您可以使用以下文件命名约定创建多语言内容:

  1. 默认语言(例如英语)filename.mdx
  2. 其他语言(例如中文)filename.zh.mdx

多语言作者和分类

对作者和分类遵循相同的模式:

content/author/mksaas.zh.mdx
---
name: MkSaaS 团队
avatar: /images/authors/mksaas.jpg
---
content/category/announcement.zh.mdx
---
name: 公告
description: 官方平台公告和更新
---

多语言博客文章示例

英语博客文章:

content/blog/welcome-post.mdx
---
title: Welcome to our Blog
description: Our first official blog post
image: /images/blog/welcome.jpg
date: "2023-12-01"
published: true
categories: ["announcement"]
author: "mksaas"
---

英语内容...

同一篇文章的中文版本:

content/blog/welcome-post.zh.mdx
---
title: 欢迎来到我们的博客
description: 我们的第一篇官方博客文章
image: /images/blog/welcome.jpg
date: "2023-12-01"
published: true
categories: ["announcement"]
author: "mksaas"
---

中文内容...

系统将根据用户的语言设置自动匹配相应语言的文章。

自定义博客架构

要向博客文章、作者或分类添加新字段:

  1. source.config.ts 中修改架构
  2. 运行命令 pnpm run content 重新生成 .source 文件夹
  3. 更新组件以显示新字段

示例:添加"精选"字段

source.config.ts
export const blog = defineCollections({
  type: 'doc',
  dir: 'content/blog',
  schema: frontmatterSchema.extend({
    image: z.string(),
    date: z.string().date(),
    published: z.boolean().default(true),
    categories: z.array(z.string()),
    author: z.string(),
    // 添加新字段
    featured: z.boolean().default(false),
  }),
});

然后,您可以在博客文章中使用此字段:

content/blog/important-post.mdx
---
title: 重要公告
description: 阅读这个重要公告
image: /images/blog/announcement.jpg
date: "2023-12-01"
published: true
categories: ["announcement"]
author: "mksaas"
featured: true
---

内容在这里...

然后,运行命令 pnpm run content 重新生成 .source 文件夹。

高级用法

程序化查询文章

您可以使用 Fumadocs 源程序化查询文章:

import { blogSource, authorSource, categorySource } from '@/lib/docs/source';

// 获取所有博客文章
const allPosts = blogSource.getPages();

// 获取已发布的文章
const publishedPosts = allPosts.filter(post => post.data.published);

// 按分类获取文章
const getPostsByCategory = (categorySlug: string) => {
  return allPosts.filter(post =>
    post.data.categories.includes(categorySlug)
  );
};

// 按作者获取文章
const getPostsByAuthor = (authorSlug: string) => {
  return allPosts.filter(post => post.data.author === authorSlug);
};

// 获取所有作者
const allAuthors = authorSource.getPages();

// 获取所有分类
const allCategories = categorySource.getPages();

更改博客文章卡片布局

src/components/blog/blog-card.tsx 中自定义博客卡片组件:

src/components/blog/blog-card.tsx
import type { BlogType } from '@/lib/docs/source';

interface BlogCardProps {
  post: BlogType;
}

export function BlogCard({ post }: BlogCardProps) {
  return (
    <div className="group flex flex-col border rounded-lg overflow-hidden h-full bg-card shadow-sm hover:shadow-md transition-shadow">
      {/* 通过 post.data 访问文章数据 */}
      <h3>{post.data.title}</h3>
      <p>{post.data.description}</p>
      <time>{post.data.date}</time>
      {/* ... 组件的其余部分 */}
    </div>
  );
}

构建过程

博客系统使用 Fumadocs MDX 的构建过程:

  1. 开发:在开发过程中按需处理内容
  2. 构建:运行 pnpm run content 生成优化的内容源
  3. 生成的文件.source 目录包含生成的 TypeScript 文件和您的内容

最佳实践

  1. 使用高质量图片:为博客文章使用适当大小和优化的图片
  2. 一致的分类:在文章中保持一致的分类集合
  3. 强大的元数据:编写引人注目的标题和描述提高 SEO 效果
  4. 结构化内容:在博客文章内容中使用适当的标题和段落
  5. 包含目录:对于较长的文章,确保标题组织良好以便生成目录
  6. 国际化内容:在所有本地化内容中保持翻译一致性
  7. 优化图片:使用响应式图片和延迟加载以获得更好的性能
  8. 架构验证:利用 Zod 架构进行类型安全的内容验证

视频教程

下一步

现在您了解了如何在 MkSaaS 中使用博客系统,您可能想要探索这些相关功能: