Skip to content

Commit 9a99a71

Browse files
committed
up to dynamic routes
1 parent 4b1fb2b commit 9a99a71

18 files changed

+2371
-140
lines changed

components/date.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { parseISO, format } from 'date-fns';
2+
3+
export default function Date({ dateString }) {
4+
const date = parseISO(dateString);
5+
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>;
6+
}

components/layout.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import Head from 'next/head';
2+
import Image from 'next/image';
3+
import styles from './layout.module.css';
4+
import utilStyles from '../styles/utils.module.css';
5+
import Link from 'next/link';
6+
7+
const name = 'Xitlaly Prado';
8+
export const siteTitle = 'Next.js Sample Website';
9+
10+
export default function Layout({ children, home }) {
11+
return (
12+
<div className={styles.container}>
13+
<Head>
14+
<link rel="icon" href="/favicon.ico" />
15+
<meta
16+
name="description"
17+
content="Learn how to build a personal website using Next.js"
18+
/>
19+
<meta
20+
property="og:image"
21+
content={`https://og-image.vercel.app/${encodeURI(
22+
siteTitle,
23+
)}.png?theme=light&md=0&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg`}
24+
/>
25+
<meta name="og:title" content={siteTitle} />
26+
<meta name="twitter:card" content="summary_large_image" />
27+
</Head>
28+
<header className={styles.header}>
29+
{home ? (
30+
<>
31+
<Image
32+
priority
33+
src="/images/profile.jpg"
34+
className={utilStyles.borderCircle}
35+
height={144}
36+
width={144}
37+
alt=""
38+
/>
39+
<h1 className={utilStyles.heading2Xl}>{name}</h1>
40+
</>
41+
) : (
42+
<>
43+
<Link href="/">
44+
<Image
45+
priority
46+
src="/images/profile.jpg"
47+
className={utilStyles.borderCircle}
48+
height={108}
49+
width={108}
50+
alt=""
51+
/>
52+
</Link>
53+
<h2 className={utilStyles.headingLg}>
54+
<Link href="/" className={utilStyles.colorInherit}>
55+
{name}
56+
</Link>
57+
</h2>
58+
</>
59+
)}
60+
</header>
61+
<main>{children}</main>
62+
{!home && (
63+
<div className={styles.backToHome}>
64+
<Link href="/">← Back to home</Link>
65+
</div>
66+
)}
67+
</div>
68+
);
69+
}

components/layout.module.css

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.container {
2+
max-width: 36rem;
3+
padding: 0 1rem;
4+
margin: 3rem auto 6rem;
5+
}
6+
7+
.header {
8+
display: flex;
9+
flex-direction: column;
10+
align-items: center;
11+
}
12+
13+
.backToHome {
14+
margin: 3rem 0 0;
15+
}

lib/posts.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
import matter from 'gray-matter';
4+
import { remark } from 'remark';
5+
import html from 'remark-html';
6+
7+
const postsDirectory = path.join(process.cwd(), 'posts');
8+
9+
export function getSortedPostsData() {
10+
// Get file names under /posts
11+
const fileNames = fs.readdirSync(postsDirectory);
12+
const allPostsData = fileNames.map((fileName) => {
13+
// Remove ".md" from file name to get id
14+
const id = fileName.replace(/\.md$/, '');
15+
16+
// Read markdown file as string
17+
const fullPath = path.join(postsDirectory, fileName);
18+
const fileContents = fs.readFileSync(fullPath, 'utf8');
19+
20+
// Use gray-matter to parse the post metadata section
21+
const matterResult = matter(fileContents);
22+
23+
// Combine the data with the id
24+
return {
25+
id,
26+
...matterResult.data,
27+
};
28+
});
29+
// Sort posts by date
30+
return allPostsData.sort((a, b) => {
31+
if (a.date < b.date) {
32+
return 1;
33+
} else {
34+
return -1;
35+
}
36+
});
37+
}
38+
39+
export function getAllPostIds() {
40+
const fileNames = fs.readdirSync(postsDirectory);
41+
return fileNames.map((fileName) => {
42+
return {
43+
params: {
44+
id: fileName.replace(/\.md$/, ''),
45+
},
46+
};
47+
});
48+
}
49+
50+
export async function getPostData(id) {
51+
const fullPath = path.join(postsDirectory, `${id}.md`);
52+
const fileContents = fs.readFileSync(fullPath, 'utf8');
53+
54+
// Use gray-matter to parse the post metadata section
55+
const matterResult = matter(fileContents);
56+
57+
// Use remark to convert markdown into HTML string
58+
const processedContent = await remark()
59+
.use(html)
60+
.process(matterResult.content);
61+
const contentHtml = processedContent.toString();
62+
63+
// Combine the data with the id and contentHtml
64+
return {
65+
id,
66+
contentHtml,
67+
...matterResult.data,
68+
};
69+
}

0 commit comments

Comments
 (0)