Skip to content

Commit

Permalink
chore: create a common file for rendering [...slug] and [component]
Browse files Browse the repository at this point in the history
  • Loading branch information
okadurin committed Dec 14, 2023
1 parent 9ace4dc commit 6b3825a
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 214 deletions.
221 changes: 7 additions & 214 deletions src/pages/[top]/[...slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import { fundamentalsEntries, allPages } from '../../content';
import { blogEntries } from '../../content';
import { guideEntries } from '../../content';
import { maxDepthForNonComponentsNavigation } from '../../../config.mjs';
let pages = [];
const inPageNavData = [];
let mdjsStoriesJsPath = '';
let dirPath;
import { getPages, getInPageNavData, getPagesByDir, getPathForMdjsStroriesFile } from '../../utils/pages/render-entries.ts';
export async function getStaticPaths() {
const fundamentalsArr = fundamentalsEntries.map(entry => ({
Expand Down Expand Up @@ -75,221 +70,19 @@ export async function getStaticPaths() {
const { entry } = Astro.props;
const renderDir = async (directoryPath) => {
const entries = getEntriesByDir(directoryPath);
return await concatenateEntries(entries);
};
const convertHeadingsToInPageNavData = (headings, componentSlug) => {
const arePagesConcatenated = !entry;
let mainPathPart = arePagesConcatenated ? dirPath : componentSlug;
return headings.map(header => {
const anchor = header.slug;
return {
name: header.text,
url: `/${mainPathPart}#${anchor}`
};
});
};
const parseEntries = async (entries) => {
const contents = [];
for (const componentEntry of entries) {
const { Content, headings, remarkPluginFrontmatter } = await componentEntry.render();
const order = remarkPluginFrontmatter.order;
const slug = componentEntry.slug;
const content = {Content, headings, order, slug};
contents.push(content);
}
return contents;
};
const updateHeadings = (contentItems) => {
const parentDirToNavDataMap = new Map();
for (const contentItem of contentItems) {
const headersH2 = contentItem.headings.filter(header => header.depth === 2);
const parentDirName = path.dirname(contentItem.slug);
if (headersH2.length !== 0) {
const entryInPageNavData = convertHeadingsToInPageNavData(headersH2, contentItem.slug)[0];
const headersH3 = contentItem.headings.filter(header => header.depth === 3);
if (headersH3.length !== 0) {
entryInPageNavData.children = convertHeadingsToInPageNavData(headersH3, contentItem.slug);
}
inPageNavData.push(entryInPageNavData);
parentDirToNavDataMap.set(parentDirName, entryInPageNavData);
} else {
const headersH3 = contentItem.headings.filter(header => header.depth === 3);
if (headersH3.length !== 0) {
const entryInPageNavData = parentDirToNavDataMap.get(parentDirName);
if (entryInPageNavData) {
entryInPageNavData.children = entryInPageNavData.children || [];
entryInPageNavData.children = [...entryInPageNavData.children, ...convertHeadingsToInPageNavData(headersH3, contentItem.slug)];
}
}
}
}
};
const directoriesOrder = new Map();
function getOrder(content, contents) {
const dir = path.dirname(content.slug);
const dirIndex = path.join(dir, 'dir-index');
let dirOrder;
if (directoriesOrder.has(dir)) {
dirOrder = directoriesOrder.get(dir);
} else {
dirOrder = contents.find(item => item.slug === dirIndex).order;
directoriesOrder.set(dir, dirOrder);
}
return dirOrder;
}
function getContentsWithParentDepth(contents, parentDepth) {
return contents.filter(content => {
const dirDepth = path.dirname(content.slug).split('/').length;
return dirDepth >= parentDepth;
});
}
function getSlugForParentDepth(slug, depth) {
const slugParts = slug.split('/');
const slugPartsForParentDepth = slugParts.slice(0, depth);
return slugPartsForParentDepth.join('/');
}
function getUniqueParentDirs(contents, parentDepth) {
const dirs = new Set();
contents.forEach(content => {
dirs.add(getSlugForParentDepth(content.slug, parentDepth));
});
return [...dirs];
}
function sortDirs(dirs, contents) {
dirs.sort((a, b) => {
const aDirOrder = contents.find(content => content.slug === path.join(a, 'dir-index')).order;
const bDirOrder = contents.find(content => content.slug === path.join(b, 'dir-index')).order;
return aDirOrder < bDirOrder ? -1 : 1;
});
}
function sortDirectoriesForParentDepth(contents, parentDepth) {
const reducedContents = getContentsWithParentDepth(contents, parentDepth);
const uniqueParentDirs = getUniqueParentDirs(reducedContents, parentDepth);
sortDirs(uniqueParentDirs, reducedContents);
contents.sort((a, b) => {
const aParentDir = getSlugForParentDepth(a.slug, parentDepth);
const bParentDir = getSlugForParentDepth(b.slug, parentDepth);
if (uniqueParentDirs.indexOf(aParentDir) > uniqueParentDirs.indexOf(bParentDir)) {
return 1;
} else if (uniqueParentDirs.indexOf(aParentDir) < uniqueParentDirs.indexOf(bParentDir)) {
return -1;
} else {
return 0;
}
});
}
function sortDirectories(contents) {
let parentDepth = maxDepthForNonComponentsNavigation + 1;
let hasParentWithDepth = contents.some(content => path.dirname(content.slug).split('/').length === parentDepth);
while(hasParentWithDepth) {
sortDirectoriesForParentDepth(contents, parentDepth);
parentDepth++;
hasParentWithDepth = contents.some(content => path.dirname(content.slug).split('/').length === parentDepth);
}
}
function sort(contents) {
contents.sort((a, b) => {
// Get paths with fewer depth first
if (a.slug.split('/').length < b.slug.split('/').length) {
return -1;
} else if (a.slug.split('/').length > b.slug.split('/').length) {
return 1;
}
// same depth
else {
// same parent
if (path.dirname(a.slug) === path.dirname(b.slug)) {
if (path.basename(a.slug) === 'dir-index') {
return -1;
} else if (path.basename(b.slug) === 'dir-index') {
return 1;
} else {
return a.order < b.order ? -1 : 1;
}
}
}
});
}
async function concatenateEntries(entries) {
const contents = await parseEntries(entries);
sortDirectories(contents);
sort(contents);
updateHeadings(contents);
return contents;
}
const getEntriesByDir = (dirname) => {
//return allPages.filter(childEntry => childEntry.slug.startsWith(dirname));
return allPages.filter(childEntry => {
return childEntry.slug.startsWith(dirname)});
};
const getMdjsStories = (fullDirPath) => {
return new Promise((resolve, reject) => {
glob(fullDirPath + '/**/__mdjs-stories--*.js', {}, (err, files)=>{
const relativePaths = files.map(file => {
return path.relative(fullDirPath, file);
});
resolve(relativePaths);
})
});
};
if (entry) {
pages = await concatenateEntries([entry]);
} else {
dirPath = path.join(Astro.params.top, Astro.params.slug);
pages = await renderDir(dirPath);
const fullDirPath = path.join(process.cwd(), 'public/docs', dirPath);
const files = await getMdjsStories(fullDirPath);
let imports = '';
files.forEach(file => {
imports += `import('./${file}');\n`
});
if (imports) {
mdjsStoriesJsPath = path.join(fullDirPath, '__mdjs-stories.js');
fs.writeFileSync(mdjsStoriesJsPath, imports, 'utf8');
}
}
const getPathMdjsStroriesFile = () => {
if (entry) {
const mdjsStroriesFileDirectory = path.dirname(entry.slug);
return `/docs/${mdjsStroriesFileDirectory}/__mdjs-stories--${path.basename(entry.slug)}.js`;
}
if (mdjsStoriesJsPath) {
return '/docs' + mdjsStoriesJsPath.split('/docs')[1];
}
return null;
}
// URL path as a base for in-page navigation. It is used to add anchors to. F.e. "host://urlPath#header1"
const urlPath = entry ? entry.slug : path.join(Astro.params.top, Astro.params.slug);
const pages = entry ? await getPages([entry]) : await getPagesByDir(urlPath);
const pathForMdjsStroriesFile = await getPathForMdjsStroriesFile(entry?.slug, urlPath);
---

<MainLayout title={entry?.slug}>
<UIPortalInpageNav nav-data={JSON.stringify(inPageNavData)} />
<UIPortalInpageNav nav-data={JSON.stringify(getInPageNavData(pages, urlPath))} />
{
pages.map((page) => (
<page.Content />
))
}
<script is:inline src="/docs/_assets/scoped-custom-element-registry.min.js"></script>
{getPathMdjsStroriesFile() && <script type="module" src={getPathMdjsStroriesFile()} mdjs-setup></script>}
{pathForMdjsStroriesFile && <script type="module" src={pathForMdjsStroriesFile} mdjs-setup></script>}
</MainLayout>
Loading

0 comments on commit 6b3825a

Please sign in to comment.