Skip to content

Commit cd55478

Browse files
authored
Big sidebar refactor (#110)
1 parent b38f8cd commit cd55478

File tree

11 files changed

+963
-66
lines changed

11 files changed

+963
-66
lines changed

astro.config.mjs

Lines changed: 116 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,125 @@ import starlight from "@astrojs/starlight";
33
import * as fs from "fs";
44
import rehypeMermaid from "rehype-mermaid";
55
import starlightBlog from "starlight-blog";
6-
import starlightSidebarTopics from "starlight-sidebar-topics";
76
import tailwindcss from "@tailwindcss/vite";
87

98
// Helper function to check if an edition is the latest
109
const isLatestEdition = (edition) => edition.folder === ".";
1110

12-
let sidebar = JSON.parse(
13-
fs.readFileSync("generated/sidebar-from-site-structure.json"),
11+
// Load site structure and transform it into Starlight sidebar format
12+
const siteStructure = JSON.parse(
13+
fs.readFileSync("generated/site-structure.json", "utf-8"),
1414
);
15+
16+
// Helper function to get the latest edition from site structure
17+
function getLatestEditionName(siteStructure) {
18+
const editionNames = Object.keys(siteStructure.aeps.editions);
19+
if (editionNames.length === 0) return null;
20+
21+
// Check for edition with folder = "." (latest edition)
22+
const currentFolderEdition = editionNames.find(
23+
(name) => siteStructure.aeps.editions[name].folder === ".",
24+
);
25+
if (currentFolderEdition) return currentFolderEdition;
26+
27+
// Check for standard names
28+
const standardEdition = editionNames.find((name) =>
29+
["general", "main", "default"].includes(name.toLowerCase()),
30+
);
31+
if (standardEdition) return standardEdition;
32+
33+
// Fall back to first edition
34+
return editionNames[0];
35+
}
36+
37+
// Transform site structure into Starlight sidebar format
38+
function transformSiteStructureToSidebar(siteStructure) {
39+
const sidebar = [];
40+
41+
// Overview section
42+
sidebar.push({
43+
label: siteStructure.overview.metadata.label,
44+
items: siteStructure.overview.pages.map((page) => page.link),
45+
});
46+
47+
// AEPs section
48+
const latestEditionName = getLatestEditionName(siteStructure);
49+
const aepItems = [];
50+
if (latestEditionName) {
51+
const latestEdition = siteStructure.aeps.editions[latestEditionName];
52+
for (const category of latestEdition.categories) {
53+
aepItems.push({
54+
label: category.title,
55+
items: category.aeps.map((aep) => ({
56+
label: `${aep.id}. ${aep.title}`,
57+
link: aep.id.toString(),
58+
})),
59+
});
60+
}
61+
}
62+
sidebar.push({
63+
label: siteStructure.aeps.metadata.label,
64+
items: aepItems,
65+
});
66+
67+
// Tooling section
68+
const toolingItems = [];
69+
for (const page of siteStructure.tooling.pages) {
70+
toolingItems.push({
71+
label: page.label,
72+
link: page.link,
73+
});
74+
}
75+
76+
// Add Protobuf Linter section
77+
if (siteStructure.tooling.linterRules?.length > 0) {
78+
toolingItems.push({
79+
label: "Protobuf Linter",
80+
items: [
81+
"tooling/linter",
82+
{
83+
label: "Rules",
84+
collapsed: true,
85+
items: siteStructure.tooling.linterRules.map(
86+
(rule) => `tooling/linter/rules/${rule}`,
87+
),
88+
},
89+
],
90+
});
91+
}
92+
93+
// Add OpenAPI Linter section
94+
if (siteStructure.tooling.openAPILinterRules?.length > 0) {
95+
toolingItems.push({
96+
label: "OpenAPI Linter",
97+
items: [
98+
"tooling/openapi-linter",
99+
{
100+
label: "Rules",
101+
collapsed: true,
102+
items: siteStructure.tooling.openAPILinterRules
103+
.sort((a, b) => a.localeCompare(b))
104+
.map((rule) => `tooling/openapi-linter/rules/${rule}`),
105+
},
106+
],
107+
});
108+
}
109+
110+
sidebar.push({
111+
label: siteStructure.tooling.metadata.label,
112+
items: toolingItems,
113+
});
114+
115+
// Blog section - content is populated by starlight-blog plugin middleware
116+
sidebar.push({
117+
label: siteStructure.blog.metadata.label,
118+
items: [],
119+
});
120+
121+
return sidebar;
122+
}
123+
124+
let sidebar = transformSiteStructureToSidebar(siteStructure);
15125
let redirects = JSON.parse(fs.readFileSync("generated/redirects.json"));
16126
let config = JSON.parse(fs.readFileSync("generated/config.json"));
17127
let aepEditions = JSON.parse(fs.readFileSync("aep-editions.json"));
@@ -32,29 +142,8 @@ export default defineConfig({
32142
// Path to your Tailwind base styles:
33143
"./src/styles/global.css",
34144
],
35-
plugins: [
36-
starlightBlog({ navigation: "none" }),
37-
starlightSidebarTopics(sidebar, {
38-
topics: {
39-
aeps: aepEditions.editions
40-
.filter((edition) => !isLatestEdition(edition))
41-
.flatMap((edition) => [
42-
`/${edition.folder}`,
43-
`/${edition.folder}/**/*`,
44-
]),
45-
},
46-
exclude: [
47-
"/blog",
48-
"/blog/**/*",
49-
...aepEditions.editions
50-
.filter((edition) => !isLatestEdition(edition))
51-
.flatMap((edition) => [
52-
`/${edition.folder}`,
53-
`/${edition.folder}/**/*`,
54-
]),
55-
],
56-
}),
57-
],
145+
sidebar: sidebar,
146+
plugins: [starlightBlog({ navigation: "none" })],
58147
social: [
59148
{ icon: "github", label: "GitHub", href: config.urls.repo },
60149
{
@@ -71,6 +160,7 @@ export default defineConfig({
71160
components: {
72161
Banner: "./src/components/overrides/Banner.astro",
73162
Head: "./src/components/overrides/Head.astro",
163+
Sidebar: "./src/components/overrides/Sidebar.astro",
74164
SkipLink: "./src/components/overrides/SkipLink.astro",
75165
TableOfContents: "./src/components/overrides/TableOfContents.astro",
76166
ThemeSelect: "./src/components/overrides/ThemeSelect.astro",

package-lock.json

Lines changed: 0 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"rehype-mermaid": "^3.0.0",
2828
"sharp": "^0.32.5",
2929
"starlight-blog": "^0.24.0",
30-
"starlight-sidebar-topics": "^0.6.0",
3130
"tailwindcss": "^4.1.4",
3231
"vite-plugin-radar": "^0.9.6"
3332
},

scripts/generate.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ import {
3434
writeSiteStructure,
3535
type SiteStructure,
3636
} from "../src/utils/site-structure";
37-
import { assembleSidebarFromSiteStructure } from "../src/utils/sidebar-from-site-structure";
3837

3938
const AEP_LOC = process.env.AEP_LOCATION || "";
4039
const AEP_LINTER_LOC = process.env.AEP_LINTER_LOC || "";
@@ -143,14 +142,16 @@ async function writePage(
143142
filename: string,
144143
outputPath: string,
145144
title?: string,
146-
) {
145+
): Promise<string> {
147146
const filePath = path.join(dirPath, filename);
148147
logFileRead(filePath, "Page content");
149148
let contents = new Markdown(fs.readFileSync(filePath, "utf-8"), {});
149+
const pageTitle = title ?? getTitle(contents.contents);
150150
contents.frontmatter = {
151-
title: title ?? getTitle(contents.contents),
151+
title: pageTitle,
152152
};
153153
writeFile(outputPath, contents.removeTitle().build());
154+
return pageTitle;
154155
}
155156

156157
async function writePagesToSiteStructure(
@@ -167,21 +168,21 @@ async function writePagesToSiteStructure(
167168
);
168169

169170
for (var file of files) {
170-
writePage(
171+
const title = await writePage(
171172
path.join(dirPath, "pages/general"),
172173
file.name,
173174
path.join("src/content/docs", file.name),
174175
);
175176
const link = file.name.replace(".md", "");
176-
addOverviewPage(siteStructure, { label: link, link });
177+
addOverviewPage(siteStructure, { label: title, link });
177178
}
178-
writePage(
179+
const contributingTitle = await writePage(
179180
dirPath,
180181
"CONTRIBUTING.md",
181182
path.join("src/content/docs", "contributing.md"),
182183
);
183184
addOverviewPage(siteStructure, {
184-
label: "contributing",
185+
label: contributingTitle,
185186
link: "contributing",
186187
});
187188
return siteStructure;
@@ -489,7 +490,3 @@ if (AEP_EDITION_2026 != "") {
489490

490491
// Write site structure to JSON
491492
writeSiteStructure(siteStructure, "generated/site-structure.json");
492-
493-
// Assemble sidebar from site structure and write it
494-
const sidebar = assembleSidebarFromSiteStructure(siteStructure);
495-
writeSidebar(sidebar, "sidebar-from-site-structure.json");

0 commit comments

Comments
 (0)