Skip to content

Commit 32ddcb3

Browse files
committed
chore: simplify sidebar code
1 parent c28141e commit 32ddcb3

3 files changed

Lines changed: 38 additions & 204 deletions

File tree

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,15 @@
1-
import { generateSidebar } from 'vitepress-sidebar';
2-
import {
3-
removeIndexEntries,
4-
sortByWeight,
5-
enhanceDirectoryTitles,
6-
removeEmptyItems,
7-
addTrailingSlashToLinks,
8-
} from './utils/sidebar.ts';
9-
10-
const communitySidbarConfig = {
11-
documentRootPath: '/hugo/content',
12-
scanStartPath: 'community',
13-
resolvePath: '/community/',
14-
collapsed: true,
15-
useTitleFromFileHeading: true,
16-
useTitleFromFrontmatter: true,
17-
useFolderLinkFromIndexFile: true,
18-
includeFolderLinksInFolder: true,
19-
excludeFilesByFrontmatterFieldName: 'exclude',
20-
}
1+
import { generateWeightSortedSidebar } from './utils/sidebar.ts';
212

223
export function communitySidebar(): any {
23-
// Generate the base sidebar
24-
const sidebar = generateSidebar([communitySidbarConfig]);
25-
26-
// Recursively enhance directory titles from frontmatter
27-
const enhancedSidebar = enhanceDirectoryTitles(sidebar, 'community');
28-
29-
// Sort entries by weight from frontmatter
30-
const sortedSidebar = sortByWeight(enhancedSidebar, 'community');
31-
32-
// Filter out all _index.md entries (called last)
33-
const filteredSidebar = removeIndexEntries(sortedSidebar)
34-
35-
const cleandSidebar = removeEmptyItems(filteredSidebar)
36-
37-
addTrailingSlashToLinks(cleandSidebar['/community/'].items);
38-
39-
return cleandSidebar;
4+
return generateWeightSortedSidebar({
5+
documentRootPath: '/hugo/content',
6+
scanStartPath: 'community',
7+
resolvePath: '/community/',
8+
collapsed: true,
9+
useTitleFromFileHeading: true,
10+
useTitleFromFrontmatter: true,
11+
useFolderLinkFromIndexFile: true,
12+
useFolderTitleFromIndexFile: true,
13+
excludeFilesByFrontmatterFieldName: 'exclude',
14+
});
4015
}

.vitepress/theme/docs-sidebar.ts

Lines changed: 11 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,14 @@
1-
import { generateSidebar } from 'vitepress-sidebar';
2-
import {
3-
removeIndexEntries,
4-
sortByWeight,
5-
enhanceDirectoryTitles,
6-
removeEmptyItems,
7-
addTrailingSlashToLinks
8-
} from './utils/sidebar.ts';
1+
import { generateWeightSortedSidebar } from './utils/sidebar.ts';
92

10-
const docsSidbarConfig = {
11-
documentRootPath: '/hugo/content',
12-
scanStartPath: 'docs',
13-
resolvePath: '/docs/',
14-
collapsed: true,
15-
useTitleFromFileHeading: true,
16-
useTitleFromFrontmatter: true,
17-
useFolderLinkFromIndexFile: true,
18-
includeFolderLinksInFolder: true,
19-
}
20-
21-
function generateDocsSidebar(): any {
22-
return generateSidebar([docsSidbarConfig]);
23-
}
24-
25-
/**
26-
* Wrapper function that generates and enhances the docs sidebar
27-
* @returns The enhanced sidebar with updated directory titles
28-
*/
293
export function generateEnhancedDocsSidebar(): any {
30-
// Generate the base sidebar
31-
const sidebar = generateDocsSidebar();
32-
33-
// Recursively enhance directory titles from frontmatter
34-
const enhancedSidebar = enhanceDirectoryTitles(sidebar, 'docs');
35-
36-
// Sort entries by weight from frontmatter
37-
const sortedSidebar = sortByWeight(enhancedSidebar, 'docs');
38-
39-
// Filter out all _index.md entries (called last)
40-
const filteredSidebar = removeIndexEntries(sortedSidebar);
41-
42-
const cleandSidebar = removeEmptyItems(filteredSidebar)
43-
44-
addTrailingSlashToLinks(cleandSidebar['/docs/'].items);
45-
46-
return cleandSidebar;
4+
return generateWeightSortedSidebar({
5+
documentRootPath: '/hugo/content',
6+
scanStartPath: 'docs',
7+
resolvePath: '/docs/',
8+
collapsed: true,
9+
useTitleFromFileHeading: true,
10+
useTitleFromFrontmatter: true,
11+
useFolderLinkFromIndexFile: true,
12+
useFolderTitleFromIndexFile: true,
13+
});
4714
}

.vitepress/theme/utils/sidebar.ts

Lines changed: 15 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
import { readFileSync, existsSync } from 'node:fs';
22
import { join } from 'node:path';
33
import { load } from 'js-yaml';
4+
import { generateSidebar } from 'vitepress-sidebar';
5+
import type { VitePressSidebarOptions } from 'vitepress-sidebar';
46

5-
// Type definitions for sidebar items
6-
export interface SidebarLeaf {
7-
text: string;
8-
link: string;
9-
collapsed?: boolean;
10-
}
7+
/**
8+
* Generates a sidebar with weight-based sorting and standard post-processing.
9+
* Shared pipeline for docs and community sidebars.
10+
*/
11+
export function generateWeightSortedSidebar(config: VitePressSidebarOptions): any {
12+
const sidebar = generateSidebar([config]);
13+
const base = config.scanStartPath || '';
14+
const resolvePath = config.resolvePath || '/';
1115

12-
export interface SidebarBranch {
13-
text: string;
14-
items: (SidebarLeaf | SidebarBranch)[];
15-
collapsed?: boolean;
16+
const sorted = sortByWeight(sidebar, base);
17+
const filtered = removeIndexEntries(sorted);
18+
const cleaned = removeEmptyItems(filtered);
19+
addTrailingSlashToLinks(cleaned[resolvePath].items);
20+
return cleaned;
1621
}
1722

18-
export type SidebarItem = SidebarLeaf | SidebarBranch;
19-
20-
2123
/**
2224
* Recursively removes all _index.md entries from the sidebar
2325
*/
@@ -188,116 +190,6 @@ export function getWeightFromFile(link: string, base?: string): number | null {
188190
}
189191
}
190192

191-
/**
192-
* Recursively enhances directory titles by reading from _index.md frontmatter
193-
*/
194-
export function enhanceDirectoryTitles(sidebar: any, base): any {
195-
if (Array.isArray(sidebar)) {
196-
return sidebar.map(item => enhanceDirectoryTitles(item, base));
197-
}
198-
199-
if (typeof sidebar !== 'object' || sidebar === null) {
200-
return sidebar;
201-
}
202-
203-
// Create a copy of the object
204-
const enhanced = { ...sidebar };
205-
206-
// If this object has items (indicating it's a directory), enhance it
207-
if (enhanced.items && Array.isArray(enhanced.items)) {
208-
// Look for _index.md file in the items
209-
const indexItem = enhanced.items.find((item: any) =>
210-
item.link && (item.link === '_index' || item.link.endsWith('/_index'))
211-
);
212-
213-
if (indexItem) {
214-
// Try to read the frontmatter and update the title
215-
const title = getTitleFromIndexFile(indexItem.link, base);
216-
if (title) {
217-
enhanced.text = title;
218-
}
219-
}
220-
221-
// Recursively process all items
222-
enhanced.items = enhanced.items.map((item: any) => enhanceDirectoryTitles(item, base));
223-
}
224-
225-
// If it's a top-level section with items, process those too
226-
if (enhanced.base && enhanced.items) {
227-
enhanced.items = enhanced.items.map((item: any) => enhanceDirectoryTitles(item, base));
228-
}
229-
230-
// Process other properties recursively
231-
for (const [key, value] of Object.entries(enhanced)) {
232-
if (key !== 'items' && typeof value === 'object') {
233-
enhanced[key] = enhanceDirectoryTitles(value, base);
234-
}
235-
}
236-
237-
return enhanced;
238-
}
239-
240-
/**
241-
* Reads the title from an _index.md file's frontmatter
242-
*/
243-
export function getTitleFromIndexFile(link: string, base?: string): string | null {
244-
try {
245-
// Construct the file path
246-
let filePath: string;
247-
248-
if (link === '_index') {
249-
// For root _index files
250-
filePath = join(process.cwd(), 'hugo', 'content', base, '_index.md');
251-
} else if (link.endsWith('/_index')) {
252-
// For nested _index files
253-
const relativePath = link.replace('/_index', '');
254-
filePath = join(process.cwd(), 'hugo', 'content', base, relativePath, '_index.md');
255-
} else {
256-
return null;
257-
}
258-
259-
// Check if file exists
260-
if (!existsSync(filePath)) {
261-
return null;
262-
}
263-
264-
// Read the file content
265-
const content = readFileSync(filePath, 'utf-8');
266-
267-
// Extract frontmatter
268-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
269-
if (!frontmatterMatch) {
270-
return null;
271-
}
272-
273-
// Parse YAML frontmatter
274-
const frontmatter = load(frontmatterMatch[1]) as any;
275-
276-
// Return the title if it exists
277-
return frontmatter?.title || null;
278-
279-
} catch (error) {
280-
console.warn(`Error reading title from ${link}:`, error);
281-
return null;
282-
}
283-
}
284-
285-
286-
/**
287-
* Function to recursively extract all items from a section
288-
*/
289-
export function extractItems(section: any): SidebarItem[] {
290-
if (Array.isArray(section)) {
291-
return section as SidebarItem[];
292-
}
293-
if (section && typeof section === 'object' && 'items' in section) {
294-
return section.items as SidebarItem[];
295-
}
296-
return [];
297-
}
298-
299-
300-
301193
/**
302194
* Recursively removes all items fields from the sidebar object that are empty arrays
303195
*/

0 commit comments

Comments
 (0)