Skip to content

Instantly share code, notes, and snippets.

@zstix
Last active May 12, 2020 19:04
Show Gist options
  • Save zstix/343dc9d21362bc9eb731ba59da32340a to your computer and use it in GitHub Desktop.
Save zstix/343dc9d21362bc9eb731ba59da32340a to your computer and use it in GitHub Desktop.
Generate a nested navigation from a flat list of markdown edges
const linkWithoutDirs = ({ url, displayName }) => ({ url, displayName });
const linkFromEdge = edge => ({
url: edge?.node?.frontmatter?.path,
displayName: edge?.node?.frontmatter?.title
});
const addDirsToLink = link => ({
...link,
dirs: link.url.split('/').slice(1)
});
const makeDisplayName = str => str
.split('-')
.map(word => word.replace(/\b\w/g, l => l.toUpperCase()))
.join(' ');
const genTree = (links, result = [], level = 0) => {
const linksAtLevel = links.filter(link => level === link.dirs.length - 1);
// if we have nothing below this, just return a flat list of links
if (linksAtLevel.length === links.length) {
return linksAtLevel.map(linkWithoutDirs);
}
// get all the directories at this level
const linksBelowLevel = links.filter(link => level < link.dirs.length - 1);
const dirsAtLevel = linksBelowLevel.map(link => link.dirs[level]);
const uniqueDirsAtLevel = [...new Set(dirsAtLevel)];
return uniqueDirsAtLevel.reduce((acc, dir) => {
// find the index page, or make a non-link item for this
const linksUnderDir = links.filter(link => link.dirs[level] === dir);
const index = linksUnderDir.find(link => link.dirs[level + 1] === 'index');
const childLinks = linksUnderDir.filter(link => link !== index);
return [
...acc,
{
...(index ? linkWithoutDirs(index) : { displayName: makeDisplayName(dir) }),
children: genTree(childLinks, result, level + 1)
}
]
}, []);
};
const genNav = (edges) => {
const links = edges.map(linkFromEdge);
const linksWithDirs = links.map(addDirsToLink);
const nav = genTree(linksWithDirs);
// TODO: sorting?
return nav;
}
@zstix
Copy link
Author

zstix commented May 12, 2020

This work has been cleaned up and submitted in a PR here: newrelic/developer-website#50

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment