From 9f862bab5c56311941a32757ef2243f5f3617fb9 Mon Sep 17 00:00:00 2001 From: Neko Date: Fri, 1 Nov 2024 11:28:03 +0800 Subject: [PATCH] fix: sidebar issue (#324) Signed-off-by: Neko Ayaka --- .../vitepress-plugin-sidebar/index.md | 70 +++++++++++++++++-- .../vitepress-plugin-sidebar/index.md | 67 ++++++++++++++++-- .../vitepress-plugin-sidebar/src/sidebar.ts | 10 ++- 3 files changed, 131 insertions(+), 16 deletions(-) diff --git a/docs/pages/en/integrations/vitepress-plugin-sidebar/index.md b/docs/pages/en/integrations/vitepress-plugin-sidebar/index.md index 0f731322..86a69809 100644 --- a/docs/pages/en/integrations/vitepress-plugin-sidebar/index.md +++ b/docs/pages/en/integrations/vitepress-plugin-sidebar/index.md @@ -2,13 +2,7 @@ import packageJSON from '~/packages/vitepress-plugin-sidebar/package.json' -# Auto Sidebar - -::: warning 🚧 Constructing -Nice to meet you! But sorry, this page is still under construction. If you don’t find the information you are interested in, you can first find the content you are interested in in the navigation in the sidebar to start reading. -::: - -We are still working on it, stay tuned! +# Auto Sidebar ## Installation @@ -33,3 +27,65 @@ yarn add @nolebase/vitepress-plugin-sidebar -D ``` ::: + +## Configuration + +### Integrate with VitePress + +In the VitePress configuration file (usually `docs/.vitepress/config.ts`, the file path and extension may be different), import `@nolebase/markdown-it-bi-directional-links` as a plugin, and use it as a `markdown-it` plugin in the `markdown` option: + + + +```typescript twoslash +import { defineConfigWithTheme } from 'vitepress' +import { calculateSidebar } from '@nolebase/vitepress-plugin-sidebar' // [!code ++] + +export default defineConfigWithTheme({ + lang: 'en', + title: 'Site name', // For reference only, please do not copy directly + description: 'Description', // For reference only, please do not copy directly + themeConfig: { + // Other configurations... + sidebar: calculateSidebar([ // [!code ++] + 'Notes', // [!code ++] + { folderName: 'Articles', separate: true }, // [!code ++] + ]), // [!code ++] + }, +}) +``` + +## Options + +### `calculateSidebar` + +The `calculateSidebar` function takes an array of items as arguments, each item in the array can be a `string` or an `object`. Different types will have different processing logic. Let's take the following practical scenarios to illustrate. + +First of all, it should be noted that filling in `'Notes'` and `{ folderName: 'Notes', separate: false }` in the configuration parameter is exactly equivalent, so a string-only configuration can be seen as a shortcut for `{ folderName: 'notes', separate: false }`. + +Therefore, if you don't want to change types, you can write them all as objects. + +Also, in almost 100% of cases, we generate sidebars with the same structure and form as Obsidian and [Nolebase](https://nolebase.ayaka.io), so in most cases, writing only strings will not be a problem. + +The only difference is the special `separate` attribute. When the user configures `separate: true`, we generate as many sidebars as VitePress is compatible with and supports, which makes it possible to *configure different sidebars for different pages*. + +To put it more bluntly, if you want to be able to show sidebars on page A that are only relevant to the A directory, and on page B that are only relevant to the B directory, then you would need a configuration like `[{ folderName: 'A', separate: true }, { folderName: 'B', separate: true }]`. + +Also note that there are some special handling rules: + +#### Top-level ignored + +If the parameter is filled with a string like `['notes']`, the `notes' directory level will be automatically ignored, and only files and directories under `notes' will be preserved. + +#### Mixin + +If you have both a string configuration and a `separate: true` configuration, for example: + +```typescript +calculateSidebar([ + 'Notes', + 'Tweets', . + { folderName: 'Articles', separate: true }, +]) +``` + +Then the first-level ignore rule will no longer be in effect, and instead `'Notes'` and `'Tweets'` will appear as directory names on pages accessed under `/`, and `'Articles'` will appear as a separate directory on pages accessed under `/articles/`. diff --git a/docs/pages/zh-CN/integrations/vitepress-plugin-sidebar/index.md b/docs/pages/zh-CN/integrations/vitepress-plugin-sidebar/index.md index d4b1bea7..8007a213 100644 --- a/docs/pages/zh-CN/integrations/vitepress-plugin-sidebar/index.md +++ b/docs/pages/zh-CN/integrations/vitepress-plugin-sidebar/index.md @@ -2,13 +2,7 @@ import packageJSON from '~/packages/vitepress-plugin-sidebar/package.json' -# 自动生成侧边栏 - -::: warning 🚧 施工中 -很高兴见到你!但很抱歉,这个页面还在施工中,如果没有找到你感兴趣的信息,你可以先在侧边栏的导航中寻找你感兴趣的内容来开始阅读 -::: - -内容施工中,敬请期待! +# 自动生成侧边栏 ## 安装 @@ -34,3 +28,62 @@ yarn add @nolebase/vitepress-plugin-sidebar -D ::: +## 使用 + +### 为 VitePress 配置 + +在 VitePress 的配置文件中(通常为 `docs/.vitepress/config.ts`,文件路径和拓展名也许会有区别),将 `@nolebase/vitepress-plugin-sidebar` 作为一个插件导入: + + + +```typescript twoslash +import { defineConfigWithTheme } from 'vitepress' +import { calculateSidebar } from '@nolebase/vitepress-plugin-sidebar' // [!code ++] + +export default defineConfigWithTheme({ + lang: 'zh-CN', + title: '网站名称', // 仅供参考,请不要直接复制 + description: '某些介绍', // 仅供参考,请不要直接复制 + themeConfig: { + // 其他各种配置... + sidebar: calculateSidebar([ // [!code ++] + '笔记', // [!code ++] + { folderName: '文章', separate: true }, // [!code ++] + ]), // [!code ++] + }, +}) +``` + +## 参数说明 + +### `calculateSidebar` + +`calculateSidebar` 函数接受一个数组作为参数,数组中的每一项可以是一个字符串或者一个对象。不同的类型会有着不同的处理逻辑。让我们以下面的几种实际应用场景来说明。 + +首先需要指出的是,在配置参数中填写 `'笔记'` 和 `{ folderName: '笔记', separate: false }` 是完全等效的,所以,只书写字符串的配置,可以看作是 `{ folderName: '笔记', separate: false }` 的快捷简写。因此,如果不希望变换着类型写,可以都写成对象的形式。 + +另外,在几乎 100% 的情况下,我们都会按照与 Obsidian 和 [Nolebase](https://nolebase.ayaka.io) 的侧边栏结构和形式去生成侧边栏,所以在绝大多数情况下,只写字符串也不会有问题。 + +唯一的区别就是在于这个特殊的 `separate` 属性。当用户配置了 `separate: true` 之后,我们会生成 VitePress 所兼容和支持的多侧边栏,这使得「为不同的页面配置不同的侧边栏」变成可能。 + +说得更直白一些,如果你希望能够在 A 页面展示仅与 A 目录下相关的侧边栏,B 页面只展示 B 目录下的侧边栏,那么你就需要 `[{ folderName: 'A', separate: true }, { folderName: 'B', separate: true }]` 这样的配置。 + +另外需要注意的是,还有一些特殊的处理规则: + +#### 首级忽略 + +如果参数中只填写了 `['笔记']` 这样的一个字符串的时候,会自动把 `笔记` 目录层级忽略掉,只保留 `笔记` 下的文件和目录。 + +#### 混合配置 + +如果既有 字符串配置 又有 `separate: true` 的配置,比如: + +```typescript +calculateSidebar([ + '笔记', + '短文', + { folderName: '文章', separate: true }, +]) +``` + +那么,首级忽略 的规则将不再生效,取而代之的是,`'笔记'` 和 `'短文'` 会被作为目录的名称出现在访问路径为 `/` 下的页面,而 `文章` 会被作为一个独立的目录出现在访问路径为 `/文章/` 下的页面。 diff --git a/packages/vitepress-plugin-sidebar/src/sidebar.ts b/packages/vitepress-plugin-sidebar/src/sidebar.ts index 2b766744..a70ed3ac 100644 --- a/packages/vitepress-plugin-sidebar/src/sidebar.ts +++ b/packages/vitepress-plugin-sidebar/src/sidebar.ts @@ -152,8 +152,14 @@ export function mergeSidebar(targets: Array item.text === folderName)[0].items ?? [] - sidebar.splice(sidebar.findIndex(item => item.text === folderName), 1) + const matchedSidebarFolders = sidebar.filter(item => item.text === folderName) + if (matchedSidebarFolders.length > 0) { + sidebarMultiple[`/${folderName}/`] = matchedSidebarFolders[0]?.items || [] + sidebar.splice(sidebar.findIndex(item => item.text === folderName), 1) + } + else { + sidebarMultiple[`/${folderName}/`] = [] + } } }