Allow renaming labels of nested autogenerated folders in sidebar #972
Replies: 15 comments 14 replies
-
This is indeed something that is still under discussion until a good solution is found. One temporary workaround (which obviously does not scale well) could be moving the {
label: 'Explanations',
items: [
{ label: 'Overview', link: 'explanations/overview' },
{ label: 'Decentralized Storage', link: 'explanations/decentralized-storage' },
{ label: 'Usecases', autogenerate: { directory: 'explanations/usecases' } },
],
} |
Beta Was this translation helpful? Give feedback.
-
Is it possible to pass a general JS function to the configuration like the following? {
label: "Foo bar baz",
autogenerate: {
directory: "foo",
subDirectoryLabel: (path) => capitalize(basename(path).replace("-", " ")),
},
} |
Beta Was this translation helpful? Give feedback.
-
This is not a supported syntax at the moment. To give a bit more context on why this is not supported, the way things work today is the following:
When creating the virtual module, we need to create a string representation of the user's configuration, i.e. serialize it. This means that we can't pass functions across this boundary. |
Beta Was this translation helpful? Give feedback.
-
Hmmm, I see. In that case, I propose simple mapping from {
label: "Foo bar baz",
autogenerate: {
directory: "foo",
labelCase: "sentence",
},
} The type of |
Beta Was this translation helpful? Give feedback.
-
I like this label mechanic, simple and covers most use cases - for me, as long as I can have a one-word directory shown as a correctly cased phrase, I'm good. |
Beta Was this translation helpful? Give feedback.
-
How do we move ahead with this? Who needs to approve it? |
Beta Was this translation helpful? Give feedback.
-
I think we probably need to think if we can come up with a more general solution to labelling here. While changing sentence case is a good start, we also have the issue of sites with multiple languages who want to translate the directory name. One option could be to add a labels map to the [
{
label: 'Examples',
autogenerate: {
directory: 'examples',
directoryLabels: {
'examples/php': 'PHP',
'examples/js': 'JavaScript',
},
},
},
{
label: 'Guides',
autogenerate: {
directory: 'guides',
directoryLabels: {
// Labels for different languages
'guides/styling': {
en: 'Styling',
fr: 'Mise en forme',
},
},
},
},
] |
Beta Was this translation helpful? Give feedback.
-
IMHO a yaml, json or md file with a special name is the way to go. Being able to change the label is only one use-case. In my case I'd like to change the position and the collapsed state as well. Therefore, a mere "labelling mechanic" wouldn't help me. Docusaurus has already been mentioned. I'd like to add that HUGO also takes a similar approach with special files called |
Beta Was this translation helpful? Give feedback.
-
Is there any progress on this? |
Beta Was this translation helpful? Give feedback.
-
Even though I can understand some hesitation due to how collections work, using a configuration file starting with an "_" (a la docusaurus) is the way to go for consistency and convenience. |
Beta Was this translation helpful? Give feedback.
-
I also believe the docusaurus approach is more than fine and was surprised it's not already the case, has the be any further discussion regarding this feature? Would you accept a PR if somebody would implement it? I am willing to implement it if the team is fine with the solution. |
Beta Was this translation helpful? Give feedback.
-
I was looking into this a bit today and re-discovered that Astro's Content Collections (which are the backbone of Starlight) ignore files starting with an
https://docs.astro.build/en/guides/routing/#excluding-pages My initial thought was to use something like |
Beta Was this translation helpful? Give feedback.
-
another option
|
Beta Was this translation helpful? Give feedback.
-
Hi guys! Maybe it will be useful to someone, for me I solved this problem in the following way: I created a function that recursively runs through the directories and generates the corresponding nodes for the sidebar: Caution each folder must contain file import fs from 'fs'
import path from 'path'
const sidebar = []
const root_docs = ["src", "content", "docs"].join(path.sep) + path.sep;
function traverseDirectory(dir, parent) {
try {
// console.log(dir)
parent.label = fs.existsSync(dir + path.sep + "__section.md")
? fs.readFileSync(dir + path.sep + "__section.md", 'utf8').split("\n")[0].replace('#', '').trim() :
dir.replace(root_docs, '');
const entries = fs.readdirSync(dir, {withFileTypes: true});
entries.forEach(entry => {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
const new_section = {
label: entry.name,
collapsed: true,
items: []
}
parent.items.push(new_section)
traverseDirectory(fullPath, new_section);
} else {
if (entry.name.includes("__section")) {
// skip __section.md
return
}
const slug = `${fullPath.replace(root_docs, '').replace(/\\/g, '/')}`.split('.').slice(0, -1).join('.')
parent.items.push(slug)
}
});
} catch (err) {
console.error(`Error reading directory ${dir}:`, err);
}
}
export default function (root, collapsed = true){
sidebar.length = 0;
const _parent = {
label: root,
collapsed,
items: []
}
sidebar.push(_parent)
traverseDirectory(root, _parent);
return sidebar;
} And then I add this to the sidebar: import getSidebar from "./tools/generate-sidebar.js"
export default defineConfig({
base,
trailingSlash: "never",
integrations: [
starlight({
sidebar: [
{label: "Introduction", slug: "introduction"},
...getSidebar("./src/content/docs/getting-started", true),
...getSidebar("./src/content/docs/fundamentals", true),
...getSidebar("./src/content/docs/tutorials", true),
...getSidebar("./src/content/docs/how-to", true),
...getSidebar("./src/content/docs/data-model-editor", true),
...getSidebar("./src/content/docs/release-notes/", true),
...getSidebar("./src/content/docs/api-reference/", true),
],
}),
],
}); |
Beta Was this translation helpful? Give feedback.
-
Could someone explain to me how Clickhouse gets this working? Check out their config: async function autogenSections() {
const sections = (
await readdir("./src/content/docs/", {
withFileTypes: true,
})
)
.filter((x) => x.isDirectory())
.map((x) => x.name);
return sections.map((x) => {
return {
label: x,
autogenerate: {
directory: x,
collapsed: true,
},
};
});
}
const sidebar = await autogenSections(); |
Beta Was this translation helpful? Give feedback.
-
What version of
starlight
are you using?0.11.0
What is your idea?
Currently an autogenerated sidebar inherits the folder name. Obviously, this prevents casing and spaces in the name, which makes it look odd in the sidebar.
We should be able to define subgroup labels and settings per subfolder somehow - either with a
_metadata.json
file in the subfolder, or some moreconfig
options.Why is this feature necessary?
Current inability to do this makes verbosity in the sidebar harder, and can break style / clarity.
Do you have examples of this feature in other projects?
Docusaurus
Participation
Beta Was this translation helpful? Give feedback.
All reactions