From 4279d7512a8261b576056471f5aa1ede1e6aae4a Mon Sep 17 00:00:00 2001 From: HiDeoo Date: Thu, 22 Jun 2023 18:19:38 +0200 Subject: Use file-system path in auto-generated sidebar item configuration (#237) --- .changeset/five-cooks-develop.md | 14 ++++++++++++++ packages/starlight/utils/navigation.ts | 27 ++++++++++++++++----------- 2 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 .changeset/five-cooks-develop.md diff --git a/.changeset/five-cooks-develop.md b/.changeset/five-cooks-develop.md new file mode 100644 index 00000000..e93e289a --- /dev/null +++ b/.changeset/five-cooks-develop.md @@ -0,0 +1,14 @@ +--- +"@astrojs/starlight": minor +--- + +Use path instead of slugified path for auto-generated sidebar item configuration + +⚠️ Potentially breaking change. If your docs directory names don’t match their URLs, for example they contain whitespace like `docs/my docs/`, and you were referencing these in an `autogenerate` sidebar group as `my-docs`, update your config to reference these with the directory name instead of the slugified version: + +```diff +autogenerate: { +- directory: 'my-docs', ++ directory: 'my docs', +} +``` diff --git a/packages/starlight/utils/navigation.ts b/packages/starlight/utils/navigation.ts index 0228d4a0..8e9fea3e 100644 --- a/packages/starlight/utils/navigation.ts +++ b/packages/starlight/utils/navigation.ts @@ -69,9 +69,9 @@ function groupFromAutogenerateConfig( const dirDocs = routes.filter( (doc) => // Match against `foo.md` or `foo/index.md`. - doc.slug === localeDir || + stripExtension(doc.entry.id) === localeDir || // Match against `foo/anything/else.md`. - doc.slug.startsWith(localeDir + '/') + doc.entry.id.startsWith(localeDir + '/') ); const tree = treeify(dirDocs, localeDir); return { @@ -115,16 +115,18 @@ function makeLink(href: string, label: string, currentPathname: string): Link { } /** Get the segments leading to a page. */ -function getBreadcrumbs(slug: string, baseDir: string): string[] { - // Index slugs will match `baseDir` and don’t include breadcrumbs. - if (slug === baseDir) return []; +function getBreadcrumbs(path: string, baseDir: string): string[] { + // Strip extension from path. + const pathWithoutExt = stripExtension(path); + // Index paths will match `baseDir` and don’t include breadcrumbs. + if (pathWithoutExt === baseDir) return []; // Ensure base directory ends in a trailing slash. if (!baseDir.endsWith('/')) baseDir += '/'; - // Strip base directory from slug if present. - const relativeSlug = slug.startsWith(baseDir) - ? slug.replace(baseDir, '') - : slug; - let dir = dirname(relativeSlug); + // Strip base directory from path if present. + const relativePath = pathWithoutExt.startsWith(baseDir) + ? pathWithoutExt.replace(baseDir, '') + : pathWithoutExt; + let dir = dirname(relativePath); // Return no breadcrumbs for items in the root directory. if (dir === '.') return []; return dir.split('/'); @@ -134,7 +136,7 @@ function getBreadcrumbs(slug: string, baseDir: string): string[] { function treeify(routes: Route[], baseDir: string): Dir { const treeRoot: Dir = {}; routes.forEach((doc) => { - const breadcrumbs = getBreadcrumbs(doc.slug, baseDir); + const breadcrumbs = getBreadcrumbs(doc.entry.id, baseDir); // Walk down the route’s path to generate the tree. let currentDir = treeRoot; @@ -236,3 +238,6 @@ export function getPrevNextLinks(sidebar: SidebarEntry[]): { const next = currentIndex > -1 ? entries[currentIndex + 1] : undefined; return { prev, next }; } + +/** Remove the extension from a path. */ +const stripExtension = (path: string) => path.replace(/\.\w+$/, ''); -- cgit