mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-08 18:26:57 +02:00
Add support for link-groups
This commit is contained in:
@@ -9,13 +9,14 @@ async function getBestPracticesIds() {
|
|||||||
return fs.readdir(path.join(process.cwd(), 'src/best-practices'));
|
return fs.readdir(path.join(process.cwd(), 'src/best-practices'));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldIndexPage(page) {
|
export function shouldIndexPage(pageUrl) {
|
||||||
return ![
|
return ![
|
||||||
'https://roadmap.sh/404',
|
'https://roadmap.sh/404',
|
||||||
'https://roadmap.sh/terms',
|
'https://roadmap.sh/terms',
|
||||||
'https://roadmap.sh/privacy',
|
'https://roadmap.sh/privacy',
|
||||||
'https://roadmap.sh/pdfs',
|
'https://roadmap.sh/pdfs',
|
||||||
].includes(page);
|
'https://roadmap.sh/g',
|
||||||
|
].includes(pageUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function serializeSitemap(item) {
|
export async function serializeSitemap(item) {
|
||||||
|
@@ -11,6 +11,7 @@ import Analytics from '../components/Analytics/Analytics.astro';
|
|||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
redirectUrl?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
keywords?: string[];
|
keywords?: string[];
|
||||||
noIndex?: boolean;
|
noIndex?: boolean;
|
||||||
@@ -29,6 +30,7 @@ const {
|
|||||||
canonicalUrl: givenCanonical = '',
|
canonicalUrl: givenCanonical = '',
|
||||||
sponsor,
|
sponsor,
|
||||||
jsonLd = [],
|
jsonLd = [],
|
||||||
|
redirectUrl = '',
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
|
|
||||||
// Remove trailing slashes to consider the page as canonical
|
// Remove trailing slashes to consider the page as canonical
|
||||||
@@ -49,6 +51,7 @@ const commitUrl = `https://github.com/kamranahmedse/developer-roadmap/commit/${i
|
|||||||
<meta name='description' content={description} />
|
<meta name='description' content={description} />
|
||||||
<meta name='author' content='Kamran Ahmed' />
|
<meta name='author' content='Kamran Ahmed' />
|
||||||
<meta name='keywords' content={keywords.join(', ')} />
|
<meta name='keywords' content={keywords.join(', ')} />
|
||||||
|
{redirectUrl && <meta http-equiv='refresh' content={`1;url=${redirectUrl}`} />}
|
||||||
{noIndex && <meta name='robots' content='noindex' />}
|
{noIndex && <meta name='robots' content='noindex' />}
|
||||||
<meta
|
<meta
|
||||||
name='viewport'
|
name='viewport'
|
||||||
@@ -92,14 +95,19 @@ const commitUrl = `https://github.com/kamranahmedse/developer-roadmap/commit/${i
|
|||||||
{jsonLd.length > 0 && <script type='application/ld+json' set:html={JSON.stringify(jsonLd)} />}
|
{jsonLd.length > 0 && <script type='application/ld+json' set:html={JSON.stringify(jsonLd)} />}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<slot name='page-header'>
|
||||||
<YouTubeBanner />
|
<YouTubeBanner />
|
||||||
<Navigation />
|
<Navigation />
|
||||||
|
</slot>
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
|
<slot name='page-footer'>
|
||||||
<OpenSourceBanner />
|
<OpenSourceBanner />
|
||||||
<Footer />
|
<Footer />
|
||||||
{sponsor && <Sponsor sponsor={sponsor} />}
|
{sponsor && <Sponsor sponsor={sponsor} />}
|
||||||
<slot name='after-footer' />
|
<slot name='after-footer' />
|
||||||
<Analytics />
|
<Analytics />
|
||||||
|
</slot>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -5,7 +5,7 @@ const { frontmatter = {} } = Astro.props;
|
|||||||
const { title, description, noIndex = false } = frontmatter;
|
const { title, description, noIndex = false } = frontmatter;
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={title} description={description} noIndex={noIndex}>
|
<BaseLayout {...frontmatter}>
|
||||||
<div class='container prose py-12'>
|
<div class='container prose py-12'>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
13
src/layouts/SkeletonLayout.astro
Normal file
13
src/layouts/SkeletonLayout.astro
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout, { Props as BaseLayoutProps } from './BaseLayout.astro';
|
||||||
|
|
||||||
|
export interface Props extends BaseLayoutProps {}
|
||||||
|
|
||||||
|
const props = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<BaseLayout {...props}>
|
||||||
|
<div slot='page-header'></div>
|
||||||
|
<slot />
|
||||||
|
<div slot='page-footer'></div>
|
||||||
|
</BaseLayout>
|
39
src/lib/link-group.ts
Normal file
39
src/lib/link-group.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import type { MarkdownFileType } from './file';
|
||||||
|
|
||||||
|
export interface LinkGroupFrontmatter {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LinkGroupFileType = MarkdownFileType<LinkGroupFrontmatter> & {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates id from the given linkGroup file
|
||||||
|
* @param filePath Markdown file path
|
||||||
|
*
|
||||||
|
* @returns unique linkGroup identifier
|
||||||
|
*/
|
||||||
|
function linkGroupPathToId(filePath: string): string {
|
||||||
|
const fileName = filePath.split('/').pop() || '';
|
||||||
|
|
||||||
|
return fileName.replace('.md', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the linkGroups sorted by the publishing date
|
||||||
|
* @returns Promisifed linkGroup files
|
||||||
|
*/
|
||||||
|
export async function getAllLinkGroups(): Promise<LinkGroupFileType[]> {
|
||||||
|
const linkGroups = await import.meta.glob<LinkGroupFileType>('/src/link-groups/*.md', {
|
||||||
|
eager: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const linkGroupFiles = Object.values(linkGroups);
|
||||||
|
const enrichedLinkGroups = linkGroupFiles.map((linkGroupFile) => ({
|
||||||
|
...linkGroupFile,
|
||||||
|
id: linkGroupPathToId(linkGroupFile.file),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return enrichedLinkGroups;
|
||||||
|
}
|
7
src/link-groups/1.md
Normal file
7
src/link-groups/1.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
speedup-js: https://marvinh.dev/blog/speeding-up-javascript-ecosystem/
|
||||||
|
23-min-ts: https://www.youtube.com/watch?v=YmxwicpROps
|
||||||
|
bun-vs-node: https://www.youtube.com/watch?v=qCX8rw4qOSA
|
||||||
|
aws-2023: https://cs.fyi/guide/how-to-learn-aws/
|
||||||
|
db-playground: https://github.com/kamranahmedse/db-playground
|
||||||
|
---
|
39
src/pages/g/[linkGroupId]/[linkId].astro
Normal file
39
src/pages/g/[linkGroupId]/[linkId].astro
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../../../layouts/BaseLayout.astro';
|
||||||
|
import SkeletonLayout from '../../../layouts/SkeletonLayout.astro';
|
||||||
|
import { getAllLinkGroups } from '../../../lib/link-group';
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const linkGroups = await getAllLinkGroups();
|
||||||
|
|
||||||
|
return linkGroups.flatMap((linkGroup) => {
|
||||||
|
const linkGroupLinks = linkGroup.frontmatter;
|
||||||
|
|
||||||
|
return Object.keys(linkGroupLinks).map((slug) => {
|
||||||
|
return {
|
||||||
|
params: {
|
||||||
|
linkGroupId: linkGroup.id,
|
||||||
|
linkId: slug,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
linkGroup,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const { linkId } = Astro.params;
|
||||||
|
const { linkGroup } = Astro.props;
|
||||||
|
|
||||||
|
const fullUrl = linkGroup.frontmatter[linkId!];
|
||||||
|
---
|
||||||
|
|
||||||
|
<SkeletonLayout title='Redirecting..' noIndex={true} redirectUrl={fullUrl}>
|
||||||
|
<div class='p-8'>
|
||||||
|
<h2 class='text-xl font-bold'>Redirecting ..</h2>
|
||||||
|
<p>Click the link below if you are not redirected automatically.</p>
|
||||||
|
|
||||||
|
<p><a href={fullUrl} class='underline text-blue-700'>{fullUrl}</a></p>
|
||||||
|
</div>
|
||||||
|
</SkeletonLayout>
|
Reference in New Issue
Block a user