指南

大约 6 分钟

使用 vuepress-plugin-blog2,你可以轻松地将博客功能引入主题。

插件的工作逻辑

上方的流程图可以帮助你了解插件的工作原理及其设计目标。

收集文章并生成信息

起步时,插件会首选过滤并选择那些需要作为文章的页面。这将剔除你不想要的页面,并在后续处理中排除它们。

默认情况下,所有从 Markdown 文件生成但不是主页的页面,都将被包含作为文章。

你可能需要设置 filter 选项来完全自定义要收集的页面。 filter 接受一个形状为 (page: Page) => boolean 的函数。

接着,你应该设置 getInfo 选项为一个接受 Page 作为参数并返回包含所需信息的对象的函数。这样稍后,你可以从组合 API 中获取这些信息。

案例
// 主题入口
import { blogPlugin } from "vuepress-plugin-blog2";

export default {
  name: "vuepress-theme-xxx",
  plugins: [
    blogPlugin({
      filter: ({ filePathRelative, frontmatter }) => {
        // 舍弃那些不是从 Markdown 文件生成的页面
        if (!filePathRelative) return false;

        // 舍弃 `archives` 文件夹的页面
        if (filePathRelative.startsWith("archives/")) return false;

        // 舍弃那些没有使用默认布局的页面
        if (frontmatter.home || frontmatter.layout) return false;

        return true;
      },

      getInfo: ({ frontmatter, git = {}, data = {} }) => {
        // 获取页面信息
        const info: Record<string, any> = {
          author: frontmatter.author || "",
          categories: frontmatter.categories || [],
          date: frontmatter.date || git.createdTime || null,
          tags: frontmatter.tags || [],
          excerpt: data.excerpt || "",
        };

        return info;
      },
    }),
    // 其他插件 ...
  ],
};

自定义类别和类型

基本上,你的博客中需要两种类型的收藏:

  • 类别:

    “类别”是用文章的标签 (或类别) 对它们进行分组。

    例如,每篇文章可能都有对应的“分类”和“标签”。

  • 类型:

    “类型”是过滤不同条件的文章。

    例如,你的帖子中可能有日记或笔记。当帖子带有写作日期信息时,它可以称为“时间线项目”。

了解这两种类型的描述后,你可以设置 categorytype 选项,它们都接受一个数组,每个元素代表一个配置。

让我们从此处 2 个例子开始。

假设你想为每篇文章设置标签,并且你正在通过 frontmatter.tag 设置它们。同时,你想要在 /tag/ 中使用 TagMap 布局的标签页面,并在/tag/标签名称 中使用 TagList 布局对标签按名称进行分组,你可能需要这样的配置:

// 主题入口
import { blogPlugin } from "vuepress-plugin-blog2";

export default {
  name: "vuepress-theme-xxx",
  plugins: [
    blogPlugin({
      // 其他配置 ...
      category: [
        {
          key: "tag",
          getter: ({ frontmatter }) => frontmatter.tag || [],
          path: "/tag/",
          layout: "TagMap",
          frontmatter: () => ({ title: "标签页" }),
          itemPath: "/tag/:name/",
          itemLayout: "TagList",
          itemFrontmatter: (name) => ({ title: `${name}标签` }),
        },
      ],
    }),
    // 其他插件 ...
  ],
};

此外,你可能希望为你的一些文章加注星标,并将其展示给访问者。当你在 frontmatter 中设置 star: true 来标记它们时,你可能需要这样的配置来在 /star/ 路径中以 StarList 布局显示它们:

// 主题入口
import { blogPlugin } from "vuepress-plugin-blog2";

export default {
  name: "vuepress-theme-xxx",
  plugins: [
    blogPlugin({
      // 其他配置 ...
      type: [
        {
          key: "star",
          filter: ({ frontmatter }) => frontmatter.star,
          path: "/star/",
          layout: "StarList",
          frontmatter: () => ({ title: "收藏页" }),
        },
      ],
    }),
    // 其他插件 ...
  ],
};

看,设置这两种类型很容易。有关完整选项,请参阅 博客分类配置博客分类配置

在客户端使用组合 API

当生成每个页面时,插件将在 frontmatter.blog 中设置如下信息

interface BlogFrontmatterOptions {
  /** 当前页面的类型 */
  type: "category" | "type";
  /** 在当前分类或类别下全局唯一的 key */
  key: string;
  /**
   * 当前的分类名称
   *
   * @description 仅在分类子项目页面中可用
   */
  name?: string;
}

所以你可以直接调用 useBlogCategory()useBlogType(),结果将是当前路由绑定的类别或类型。

此外,你可以通过传递所需的 key 作为参数,来将获得绑定到该 key 的信息。

有关返回类型,请参阅 Composition API 返回类型

多语言支持

该插件添加了原生多语言支持,因此你的设置将自动应用于每种语言。

例如,如果用户进行了以下 locales 配置,并且你正在设置上面的“star”示例:

// .vuepress/config.ts
export default {
  locales: {
    "/": {
      lang: "en-US",
    },
    "/zh/": {
      lang: "zh-CN",
    },
  },
};

那么 /zh/star//star/ 都将可用,并且只会显示对应语言下的文章。

摘要生成

这个插件提供了一个内置的摘要生成器,可以通过将 excerpt 选项设置为 true 来启用。

摘要介绍

摘要是一个 HTML 片段,被用于在博客列表中显示文章的简短描述,所以摘要有如下限制:

  • 摘要不支持 Vue 组件以及其他 Vue 语法,所以此类内容会在生成时被移除。如果你有自定义组件 (非 Vue 组件),请配置 isCustomElement 选项。
  • 由于摘要是一个 HTML 片段,所以你将无法通过相对路径或别名引入任何图片,这些图片会被直接移除。如果你想要保留图片,请使用基于 .vuepress/public 的绝对路径或完整路径以确保它们可以在其他地址被访问。

摘要生成器将尝试从 Frontmatter 内容中找到有效的摘要分隔符,如果找到,它将使用分隔符之前的内容,分隔符默认为 <!-- more -->,并且你可以通过 excerptSeparator 选项来自定义它。

如果找不到有效的分隔符,它将从 Markdown 文件的开头开始解析内容,直到长度达到预设值时停止。该值默认为 300,你可以通过设置 excerptLength 选项来自定义它。

要选择哪个页面应该生成摘要,你可以使用 excerptFilter 选项。

示例

通常,如果用户设置了 frontmatter.description,你可能希望使用它们,因此如果 frontmatter.description 不为空,你可以让过滤器函数返回 false

Loading...