Restructure routes, add tests and make pathmap dynamic
This commit is contained in:
84
__tests__/path-map.spec.js
Normal file
84
__tests__/path-map.spec.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const guides = require('../data/guides');
|
||||||
|
const roadmaps = require('../data/roadmaps');
|
||||||
|
|
||||||
|
const {
|
||||||
|
getPageRoutes,
|
||||||
|
getGuideRoutes,
|
||||||
|
getRoadmapRoutes
|
||||||
|
} = require("../path-map");
|
||||||
|
|
||||||
|
describe("Build scripts tests", () => {
|
||||||
|
test('it should generate valid pathmap for pages', () => {
|
||||||
|
const pageRoutes = getPageRoutes();
|
||||||
|
|
||||||
|
expect(pageRoutes).toEqual({
|
||||||
|
'/': { page: '/index' },
|
||||||
|
'/about': { page: '/about' },
|
||||||
|
'/privacy': { page: '/privacy' },
|
||||||
|
'/terms': { page: '/terms' },
|
||||||
|
'/guides': { page: '/guides/index' },
|
||||||
|
'/roadmaps': { page: '/roadmaps' },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it should generate valid guides pathmap', () => {
|
||||||
|
const expectedGuideRoutes = guides.reduce((acc, guide) => {
|
||||||
|
const [,, slug] = guide.url.split('/');
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
[guide.url]: {
|
||||||
|
page: '/guides/[guide]',
|
||||||
|
query: slug,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
// Valid path map is generated
|
||||||
|
expect(expectedGuideRoutes).toEqual(getGuideRoutes());
|
||||||
|
|
||||||
|
const pageFilePath = path.join(__dirname, '../pages/guides/[guide].js');
|
||||||
|
const foundFilePath = fs.existsSync(pageFilePath) ? pageFilePath : '';
|
||||||
|
|
||||||
|
// Given page component exists
|
||||||
|
expect(foundFilePath).toEqual(pageFilePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it should have markdown file for each guide', () => {
|
||||||
|
guides.forEach(guide => {
|
||||||
|
const [,, slug] = guide.url.split('/');
|
||||||
|
|
||||||
|
const expectedFile = path.join(__dirname, `../data/guides/${slug}.md`);
|
||||||
|
const foundFile = fs.existsSync(expectedFile) ? expectedFile : '';
|
||||||
|
|
||||||
|
expect(foundFile).toEqual(expectedFile);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it should generate valid roadmap routes', () => {
|
||||||
|
const expectedPathMap = roadmaps.reduce((roadmapAcc, roadmap) => {
|
||||||
|
// Routes for each of the versions of this roadmap
|
||||||
|
const versionRoutes = roadmap.versions.reduce((versionAcc, version) => ({
|
||||||
|
...versionAcc,
|
||||||
|
[`${roadmap.url}/${version}`]: {
|
||||||
|
page: '/[roadmap]/[version]',
|
||||||
|
query: `${roadmap.url.split('/')[1]}/${version}`,
|
||||||
|
}
|
||||||
|
}), {});
|
||||||
|
|
||||||
|
// Route for the route roadmap itself
|
||||||
|
return {
|
||||||
|
...roadmapAcc,
|
||||||
|
[roadmap.url]: {
|
||||||
|
page: '/[roadmap]/index',
|
||||||
|
query: roadmap.url.split('/')[1]
|
||||||
|
},
|
||||||
|
// Expected roadmap for versions
|
||||||
|
...versionRoutes
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
expect(getRoadmapRoutes()).toEqual(expectedPathMap);
|
||||||
|
})
|
||||||
|
});
|
@ -16,7 +16,7 @@ const FeaturedGuides = () => (
|
|||||||
{ guides
|
{ guides
|
||||||
.filter(({ featured }) => featured)
|
.filter(({ featured }) => featured)
|
||||||
.map(guide => (
|
.map(guide => (
|
||||||
<GuideBlock guide={ guide } key={ guide.slug } />
|
<GuideBlock guide={ guide } key={ guide.url } />
|
||||||
)) }
|
)) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,7 +21,7 @@ const FeaturedRoadmaps = () => (
|
|||||||
{ roadmaps
|
{ roadmaps
|
||||||
.filter(({ featured }) => featured)
|
.filter(({ featured }) => featured)
|
||||||
.map(roadmap => (
|
.map(roadmap => (
|
||||||
<RoadmapBlock roadmap={ roadmap } key={ roadmap.slug } />
|
<RoadmapBlock roadmap={ roadmap } key={ roadmap.url } />
|
||||||
)) }
|
)) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,7 +6,7 @@ const GuideBlock = ({ guide }) => {
|
|||||||
const author = findByUsername(guide.author) || {};
|
const author = findByUsername(guide.author) || {};
|
||||||
return (
|
return (
|
||||||
<div className="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12 grid-item-container">
|
<div className="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12 grid-item-container">
|
||||||
<Link href={ guide.slug } passHref>
|
<Link href={ guide.url } passHref>
|
||||||
<BlockLink>
|
<BlockLink>
|
||||||
<BlockTitle>{ guide.title }</BlockTitle>
|
<BlockTitle>{ guide.title }</BlockTitle>
|
||||||
<BlockSubtitle>{ guide.featuredDescription || guide.description }</BlockSubtitle>
|
<BlockSubtitle>{ guide.featuredDescription || guide.description }</BlockSubtitle>
|
||||||
|
@ -3,7 +3,7 @@ import { BlockLink, BlockSubtitle, BlockTitle } from './style';
|
|||||||
|
|
||||||
const RoadmapBlock = ({ roadmap }) => (
|
const RoadmapBlock = ({ roadmap }) => (
|
||||||
<div className="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12 grid-item-container">
|
<div className="col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12 grid-item-container">
|
||||||
<Link href={ roadmap.slug } passHref>
|
<Link href={ roadmap.url } passHref>
|
||||||
<BlockLink>
|
<BlockLink>
|
||||||
<BlockTitle>{ roadmap.title }</BlockTitle>
|
<BlockTitle>{ roadmap.title }</BlockTitle>
|
||||||
<BlockSubtitle>{ roadmap.featuredDescription || roadmap.description }</BlockSubtitle>
|
<BlockSubtitle>{ roadmap.featuredDescription || roadmap.description }</BlockSubtitle>
|
||||||
@ -12,4 +12,4 @@ const RoadmapBlock = ({ roadmap }) => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default RoadmapBlock;
|
export default RoadmapBlock;
|
||||||
|
@ -24,7 +24,7 @@ const RoadmapSummary = ({ roadmap }) => (
|
|||||||
<Description>{ roadmap.description }</Description>
|
<Description>{ roadmap.description }</Description>
|
||||||
<VersionList className="border-bottom">
|
<VersionList className="border-bottom">
|
||||||
{ (roadmap.versions || []).map(versionItem => (
|
{ (roadmap.versions || []).map(versionItem => (
|
||||||
<Link href={ `${roadmap.slug}/${versionItem}` } passHref key={ versionItem }>
|
<Link href={ `${roadmap.url}/${versionItem}` } passHref key={ versionItem }>
|
||||||
<VersionLink className={ classNames({
|
<VersionLink className={ classNames({
|
||||||
active: isActiveRoadmap(versionItem, roadmap.version),
|
active: isActiveRoadmap(versionItem, roadmap.version),
|
||||||
}) }>{ versionItem } Version</VersionLink>
|
}) }>{ versionItem } Version</VersionLink>
|
||||||
@ -40,4 +40,4 @@ const RoadmapSummary = ({ roadmap }) => (
|
|||||||
</SummaryContainer>
|
</SummaryContainer>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default RoadmapSummary;
|
export default RoadmapSummary;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Design Patterns for Humans",
|
"title": "Design Patterns for Humans",
|
||||||
"description": "A language agnostic, ultra-simplified explanation to design patterns",
|
"description": "A language agnostic, ultra-simplified explanation to design patterns",
|
||||||
"slug": "/guides/design-patterns-for-humans",
|
"url": "/guides/design-patterns-for-humans",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"author": "kamranahmedse",
|
"author": "kamranahmedse",
|
||||||
"createdAt": "June 12, 2019",
|
"createdAt": "June 12, 2019",
|
||||||
@ -11,7 +11,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Learn Regex",
|
"title": "Learn Regex",
|
||||||
"description": "An easy to understand guide on regular expressions with real world examples",
|
"description": "An easy to understand guide on regular expressions with real world examples",
|
||||||
"slug": "/guides/learn-regex",
|
"url": "/guides/learn-regex",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"author": "ziishaned",
|
"author": "ziishaned",
|
||||||
"createdDate": "June 19, 2019",
|
"createdDate": "June 19, 2019",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Bash Guide",
|
"title": "Bash Guide",
|
||||||
"description": "Easy to understand guide for bash with real world usage examples.",
|
"description": "Easy to understand guide for bash with real world usage examples.",
|
||||||
"slug": "/guides/bash-guide",
|
"url": "/guides/bash-guide",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"author": "idnan",
|
"author": "idnan",
|
||||||
"createdAt": "May 18, 2018",
|
"createdAt": "May 18, 2018",
|
||||||
@ -29,7 +29,7 @@
|
|||||||
{
|
{
|
||||||
"title": "DNS in One Picture",
|
"title": "DNS in One Picture",
|
||||||
"description": "Quick illustrative guide on how a website is found on the internet.",
|
"description": "Quick illustrative guide on how a website is found on the internet.",
|
||||||
"slug": "/guides/dns-in-one-picture",
|
"url": "/guides/dns-in-one-picture",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"author": "kamranahmedse",
|
"author": "kamranahmedse",
|
||||||
"createdAt": "May 11, 2018",
|
"createdAt": "May 11, 2018",
|
||||||
@ -38,7 +38,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Using React Hooks",
|
"title": "Using React Hooks",
|
||||||
"description": "Start using React hooks in your react applications today with this guide.",
|
"description": "Start using React hooks in your react applications today with this guide.",
|
||||||
"slug": "/guides/using-react-hooks",
|
"url": "/guides/using-react-hooks",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"author": "kamranahmedse",
|
"author": "kamranahmedse",
|
||||||
"createdAt": "October 22, 2019",
|
"createdAt": "October 22, 2019",
|
||||||
@ -47,7 +47,7 @@
|
|||||||
{
|
{
|
||||||
"title": "HTTP Caching",
|
"title": "HTTP Caching",
|
||||||
"description": "Everything you need to know about web caching",
|
"description": "Everything you need to know about web caching",
|
||||||
"slug": "/guides/http-caching",
|
"url": "/guides/http-caching",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"author": "kamranahmedse",
|
"author": "kamranahmedse",
|
||||||
"updatedAt": "November 01, 2019",
|
"updatedAt": "November 01, 2019",
|
||||||
|
0
data/guides/bash-guide.md
Normal file
0
data/guides/bash-guide.md
Normal file
0
data/guides/dns-in-one-picture.md
Normal file
0
data/guides/dns-in-one-picture.md
Normal file
0
data/guides/http-caching.md
Normal file
0
data/guides/http-caching.md
Normal file
0
data/guides/using-react-hooks.md
Normal file
0
data/guides/using-react-hooks.md
Normal file
@ -3,7 +3,7 @@
|
|||||||
"title": "Frontend Developer",
|
"title": "Frontend Developer",
|
||||||
"description": "Step by step guide to becoming a modern frontend developer",
|
"description": "Step by step guide to becoming a modern frontend developer",
|
||||||
"featuredDescription": "Step by step guide to becoming a modern frontend developer in 2019",
|
"featuredDescription": "Step by step guide to becoming a modern frontend developer in 2019",
|
||||||
"slug": "/roadmaps/frontend",
|
"url": "/frontend",
|
||||||
"picture": "/static/roadmaps/{version}/frontend.png",
|
"picture": "/static/roadmaps/{version}/frontend.png",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"versions": [
|
"versions": [
|
||||||
@ -16,7 +16,7 @@
|
|||||||
"title": "Backend Developer",
|
"title": "Backend Developer",
|
||||||
"description": "Step by step guide to becoming a modern backend developer",
|
"description": "Step by step guide to becoming a modern backend developer",
|
||||||
"featuredDescription": "Step by step guide to becoming a modern backend developer in 2019",
|
"featuredDescription": "Step by step guide to becoming a modern backend developer in 2019",
|
||||||
"slug": "/roadmaps/backend",
|
"url": "/backend",
|
||||||
"picture": "/static/roadmaps/{version}/backend.png",
|
"picture": "/static/roadmaps/{version}/backend.png",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"versions": [
|
"versions": [
|
||||||
@ -29,7 +29,7 @@
|
|||||||
"title": "DevOps Roadmap",
|
"title": "DevOps Roadmap",
|
||||||
"description": "Step by step guide for DevOps or any other Operations Role",
|
"description": "Step by step guide for DevOps or any other Operations Role",
|
||||||
"featuredDescription": "Step by step guide to become an SRE or for any operations role in 2019",
|
"featuredDescription": "Step by step guide to become an SRE or for any operations role in 2019",
|
||||||
"slug": "/roadmaps/devops",
|
"url": "/devops",
|
||||||
"picture": "/static/roadmaps/{version}/devops.png",
|
"picture": "/static/roadmaps/{version}/devops.png",
|
||||||
"featured": true,
|
"featured": true,
|
||||||
"versions": [
|
"versions": [
|
||||||
@ -38,4 +38,4 @@
|
|||||||
"2017"
|
"2017"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import guides from "data/guides";
|
import guides from "data/guides";
|
||||||
|
|
||||||
export const getRequestedGuide = req => {
|
export const getRequestedGuide = req => {
|
||||||
const guide = guides.find(guide => guide.slug === req.url);
|
const guide = guides.find(guide => guide.url === req.url);
|
||||||
if (!guide) {
|
if (!guide) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ export const getRequestedGuide = req => {
|
|||||||
// We will use this URL format to find the relevant markdown
|
// We will use this URL format to find the relevant markdown
|
||||||
// file inside the `/data` directory. For example `/guides/learn-regex`
|
// file inside the `/data` directory. For example `/guides/learn-regex`
|
||||||
// has to have `/guides/learn-regex.md` file inside the `data` directory
|
// has to have `/guides/learn-regex.md` file inside the `data` directory
|
||||||
const path = guide.slug.replace(/^\//, '');
|
const path = guide.url.replace(/^\//, '');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return {
|
return {
|
||||||
|
@ -3,23 +3,18 @@ import roadmaps from "data/roadmaps";
|
|||||||
export const getRequestedRoadmap = req => {
|
export const getRequestedRoadmap = req => {
|
||||||
// Considering it a new roadmap URL e.g. `/roadmaps/frontend`
|
// Considering it a new roadmap URL e.g. `/roadmaps/frontend`
|
||||||
const currentUrl = req.url.replace(/\/$/, '');
|
const currentUrl = req.url.replace(/\/$/, '');
|
||||||
// Considering it a legacy URL e.g. converting `/frontend` to `roadmap.sh/roadmaps/frontend`
|
|
||||||
const legacyUrl = `/roadmaps${currentUrl}`;
|
|
||||||
// Get the roadmap version out of the URL e.g. `/roadmaps/frontend/2019`
|
// Get the roadmap version out of the URL e.g. `/roadmaps/frontend/2019`
|
||||||
const [foundVersion = ''] = currentUrl.match(/(\d+|latest)$/) || ['latest'];
|
const [foundVersion = ''] = currentUrl.match(/(\d+|latest)$/) || ['latest'];
|
||||||
const foundVersionRegex = new RegExp(`\/?${foundVersion}$`);
|
const foundVersionRegex = new RegExp(`\/?${foundVersion}$`);
|
||||||
// Remove version from the URL because slugs in roadmaps list don't have versions
|
// Remove version from the URL because urls in roadmaps list don't have versions
|
||||||
const newUrlWithoutVersion = currentUrl.replace(foundVersionRegex, '');
|
const urlWithoutVersion = currentUrl.replace(foundVersionRegex, '');
|
||||||
const legacyUrlWithoutVersion = legacyUrl.replace(foundVersionRegex, '');
|
|
||||||
|
|
||||||
const urlToSlugList = [
|
const urlToSlugList = [
|
||||||
currentUrl,
|
currentUrl,
|
||||||
legacyUrl,
|
urlWithoutVersion,
|
||||||
newUrlWithoutVersion,
|
|
||||||
legacyUrlWithoutVersion,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const foundRoadmap = roadmaps.find(roadmap => urlToSlugList.includes(roadmap.slug));
|
const foundRoadmap = roadmaps.find(roadmap => urlToSlugList.includes(roadmap.url));
|
||||||
if (!foundRoadmap) {
|
if (!foundRoadmap) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,11 @@ const path = require('path');
|
|||||||
const withSass = require('@zeit/next-sass');
|
const withSass = require('@zeit/next-sass');
|
||||||
const withCSS = require('@zeit/next-css');
|
const withCSS = require('@zeit/next-css');
|
||||||
const rehypePrism = require('@mapbox/rehype-prism');
|
const rehypePrism = require('@mapbox/rehype-prism');
|
||||||
|
const {
|
||||||
|
getPageRoutes,
|
||||||
|
getGuideRoutes,
|
||||||
|
getRoadmapRoutes,
|
||||||
|
} = require("./path-map");
|
||||||
|
|
||||||
const withMDX = require('@next/mdx')({
|
const withMDX = require('@next/mdx')({
|
||||||
extension: /\.(md|mdx)?$/,
|
extension: /\.(md|mdx)?$/,
|
||||||
@ -12,22 +17,10 @@ const withMDX = require('@next/mdx')({
|
|||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
exportPathMap: () => {
|
exportPathMap: () => {
|
||||||
// @todo make it dynamic for pages, authors and guides
|
|
||||||
return {
|
return {
|
||||||
'/': { page: '/' },
|
...getPageRoutes(),
|
||||||
'/about': { page: '/about' },
|
...getGuideRoutes(),
|
||||||
'/privacy': { page: '/privacy' },
|
...getRoadmapRoutes(),
|
||||||
'/terms': { page: '/terms' },
|
|
||||||
'/roadmaps': { page: '/roadmaps' },
|
|
||||||
'/guides': { page: '/guides' },
|
|
||||||
|
|
||||||
'/guides/design-patterns-for-humans': { page: '/guides/[guide]', query: "design-patterns-for-humans" },
|
|
||||||
'/frontend': { page: '/[fallback]', query: "frontend" },
|
|
||||||
'/backend': { page: '/[fallback]', query: "backend" },
|
|
||||||
'/devops': { page: '/[fallback]', query: "devops" },
|
|
||||||
'/roadmaps/frontend': { page: '/roadmaps/[roadmap]', query: "frontend" },
|
|
||||||
'/roadmaps/backend': { page: '/roadmaps/[roadmap]', query: "backend" },
|
|
||||||
'/roadmaps/devops': { page: '/roadmaps/[roadmap]', query: "devops" },
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
"dev": "next",
|
"dev": "next",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"html": "next export"
|
"html": "next export",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.22",
|
"@fortawesome/fontawesome-svg-core": "^1.2.22",
|
||||||
@ -35,6 +37,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-plugin-styled-components": "^1.10.6",
|
"babel-plugin-styled-components": "^1.10.6",
|
||||||
"glob": "^7.1.5"
|
"glob": "^7.1.5",
|
||||||
|
"jest": "^24.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
import OldRoadmap from './index';
|
|
||||||
|
|
||||||
export default OldRoadmap;
|
|
@ -1,22 +0,0 @@
|
|||||||
import Error from 'next/error';
|
|
||||||
import Roadmap from 'pages/roadmaps/[roadmap]/index';
|
|
||||||
import { serverOnlyProps } from 'lib/server';
|
|
||||||
import { getRequestedRoadmap } from 'lib/roadmap';
|
|
||||||
|
|
||||||
// Fallback page to handle the old roadmap pages implementation
|
|
||||||
const OldRoadmap = ({ roadmap }) => {
|
|
||||||
if (roadmap) {
|
|
||||||
return <Roadmap roadmap={ roadmap } />
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Error statusCode={ 404 } />;
|
|
||||||
};
|
|
||||||
|
|
||||||
OldRoadmap.getInitialProps = serverOnlyProps(({ req }) => {
|
|
||||||
return {
|
|
||||||
roadmap: getRequestedRoadmap(req),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default OldRoadmap;
|
|
@ -1,3 +1,3 @@
|
|||||||
import Roadmap from './index';
|
import Roadmap from './index';
|
||||||
|
|
||||||
export default Roadmap;
|
export default Roadmap;
|
@ -1,10 +1,10 @@
|
|||||||
import Error from 'next/error';
|
import Error from 'next/error';
|
||||||
import DefaultLayout from 'layouts/default';
|
import DefaultLayout from 'layouts/default';
|
||||||
import { serverOnlyProps } from 'lib/server';
|
|
||||||
import PageHeader from 'components/page-header';
|
import PageHeader from 'components/page-header';
|
||||||
import PageFooter from 'components/page-footer';
|
import PageFooter from 'components/page-footer';
|
||||||
import { getRequestedRoadmap } from 'lib/roadmap';
|
|
||||||
import RoadmapSummary from 'components/roadmap-summary';
|
import RoadmapSummary from 'components/roadmap-summary';
|
||||||
|
import { serverOnlyProps } from 'lib/server';
|
||||||
|
import { getRequestedRoadmap } from 'lib/roadmap';
|
||||||
|
|
||||||
const Roadmap = ({ roadmap }) => {
|
const Roadmap = ({ roadmap }) => {
|
||||||
if (!roadmap) {
|
if (!roadmap) {
|
@ -1,7 +1,7 @@
|
|||||||
import DefaultLayout from 'layouts/default/index';
|
import DefaultLayout from 'layouts/default/index';
|
||||||
import PageHeader from 'components/page-header/index';
|
import PageHeader from 'components/page-header/index';
|
||||||
|
|
||||||
const Roadmap = () => (
|
const RoadmapsList = () => (
|
||||||
<DefaultLayout>
|
<DefaultLayout>
|
||||||
<PageHeader />
|
<PageHeader />
|
||||||
<div className="container">
|
<div className="container">
|
||||||
@ -10,4 +10,4 @@ const Roadmap = () => (
|
|||||||
</DefaultLayout>
|
</DefaultLayout>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Roadmap;
|
export default RoadmapsList;
|
58
path-map.js
58
path-map.js
@ -1,7 +1,9 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
|
|
||||||
|
const guides = require('./data/guides.json');
|
||||||
|
const roadmaps = require('./data/roadmaps');
|
||||||
|
|
||||||
const PAGES_PATH = path.join(__dirname, 'pages');
|
const PAGES_PATH = path.join(__dirname, 'pages');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +23,6 @@ const getPageRoutes = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const pageRoutes = {};
|
const pageRoutes = {};
|
||||||
|
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
const pageName = file.replace(PAGES_PATH, '').replace('.js', '');
|
const pageName = file.replace(PAGES_PATH, '').replace('.js', '');
|
||||||
const pagePath = pageName.replace('/index', '') || '/';
|
const pagePath = pageName.replace('/index', '') || '/';
|
||||||
@ -32,4 +33,55 @@ const getPageRoutes = () => {
|
|||||||
return pageRoutes;
|
return pageRoutes;
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(getPageRoutes());
|
/**
|
||||||
|
* Generates routes for guide pages
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
const getGuideRoutes = () => {
|
||||||
|
return guides.reduce((acc, guide) => {
|
||||||
|
const [, , slug] = guide.url.split('/');
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
[guide.url]: {
|
||||||
|
page: '/guides/[guide]',
|
||||||
|
query: slug,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates routes for each of the roadmap and it's respective versions
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
const getRoadmapRoutes = () => {
|
||||||
|
return roadmaps.reduce((roadmapRoutes, roadmap) => {
|
||||||
|
const [, slug] = roadmap.url.split('/');
|
||||||
|
|
||||||
|
return {
|
||||||
|
...roadmapRoutes,
|
||||||
|
// Default roadmap path i.e. `{ '/frontend': { page: '/[roadmap]/index', query: 'frontend' }`
|
||||||
|
[roadmap.url]: {
|
||||||
|
page: '/[roadmap]/index',
|
||||||
|
query: slug
|
||||||
|
},
|
||||||
|
// Route for each of the versions of this roadmap i.e.
|
||||||
|
// `{ '/frontend/2019': { page: '/[roadmap]/[version]', query: 'frontend/2019' } }`
|
||||||
|
...(roadmap.versions.reduce((versionRoutes, version) => {
|
||||||
|
return {
|
||||||
|
...versionRoutes,
|
||||||
|
[`${roadmap.url}/${version}`]: {
|
||||||
|
page: '/[roadmap]/[version]',
|
||||||
|
query: `${slug}/${version}`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, {})),
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getPageRoutes,
|
||||||
|
getGuideRoutes,
|
||||||
|
getRoadmapRoutes,
|
||||||
|
};
|
||||||
|
Reference in New Issue
Block a user