initial commit
This commit is contained in:
commit
d799808203
126 changed files with 16265 additions and 0 deletions
94
pages/blog/[...slug].tsx
Normal file
94
pages/blog/[...slug].tsx
Normal file
|
@ -0,0 +1,94 @@
|
|||
import fs from 'fs'
|
||||
import PageTitle from '@/components/PageTitle'
|
||||
import generateRss from '@/lib/generate-rss'
|
||||
import { MDXLayoutRenderer } from '@/components/MDXComponents'
|
||||
import { formatSlug, getAllFilesFrontMatter, getFileBySlug, getFiles } from '@/lib/mdx'
|
||||
import { GetStaticProps, InferGetStaticPropsType } from 'next'
|
||||
import { AuthorFrontMatter } from 'types/AuthorFrontMatter'
|
||||
import { PostFrontMatter } from 'types/PostFrontMatter'
|
||||
import { Toc } from 'types/Toc'
|
||||
|
||||
const DEFAULT_LAYOUT = 'PostLayout'
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = getFiles('blog')
|
||||
return {
|
||||
paths: posts.map((p) => ({
|
||||
params: {
|
||||
slug: formatSlug(p).split('/'),
|
||||
},
|
||||
})),
|
||||
fallback: false,
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
export const getStaticProps: GetStaticProps<{
|
||||
post: { mdxSource: string; toc: Toc; frontMatter: PostFrontMatter }
|
||||
authorDetails: AuthorFrontMatter[]
|
||||
prev?: { slug: string; title: string }
|
||||
next?: { slug: string; title: string }
|
||||
}> = async ({ params }) => {
|
||||
const slug = (params.slug as string[]).join('/')
|
||||
const allPosts = await getAllFilesFrontMatter('blog')
|
||||
const postIndex = allPosts.findIndex((post) => formatSlug(post.slug) === slug)
|
||||
const prev: { slug: string; title: string } = allPosts[postIndex + 1] || null
|
||||
const next: { slug: string; title: string } = allPosts[postIndex - 1] || null
|
||||
const post = await getFileBySlug<PostFrontMatter>('blog', slug)
|
||||
// @ts-ignore
|
||||
const authorList = post.frontMatter.authors || ['default']
|
||||
const authorPromise = authorList.map(async (author) => {
|
||||
const authorResults = await getFileBySlug<AuthorFrontMatter>('authors', [author])
|
||||
return authorResults.frontMatter
|
||||
})
|
||||
const authorDetails = await Promise.all(authorPromise)
|
||||
|
||||
// rss
|
||||
if (allPosts.length > 0) {
|
||||
const rss = generateRss(allPosts)
|
||||
fs.writeFileSync('./public/feed.xml', rss)
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
post,
|
||||
authorDetails,
|
||||
prev,
|
||||
next,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default function Blog({
|
||||
post,
|
||||
authorDetails,
|
||||
prev,
|
||||
next,
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
const { mdxSource, toc, frontMatter } = post
|
||||
|
||||
return (
|
||||
<>
|
||||
{'draft' in frontMatter && frontMatter.draft !== true ? (
|
||||
<MDXLayoutRenderer
|
||||
layout={frontMatter.layout || DEFAULT_LAYOUT}
|
||||
toc={toc}
|
||||
mdxSource={mdxSource}
|
||||
frontMatter={frontMatter}
|
||||
authorDetails={authorDetails}
|
||||
prev={prev}
|
||||
next={next}
|
||||
/>
|
||||
) : (
|
||||
<div className="mt-24 text-center">
|
||||
<PageTitle>
|
||||
Under Construction{' '}
|
||||
<span role="img" aria-label="roadwork sign">
|
||||
🚧
|
||||
</span>
|
||||
</PageTitle>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
66
pages/blog/page/[page].tsx
Normal file
66
pages/blog/page/[page].tsx
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { PageSEO } from '@/components/SEO'
|
||||
import siteMetadata from '@/data/siteMetadata'
|
||||
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
||||
import ListLayout from '@/layouts/ListLayout'
|
||||
import { POSTS_PER_PAGE } from '../../blog'
|
||||
import { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from 'next'
|
||||
import { PostFrontMatter } from 'types/PostFrontMatter'
|
||||
|
||||
export const getStaticPaths: GetStaticPaths<{ page: string }> = async () => {
|
||||
const totalPosts = await getAllFilesFrontMatter('blog')
|
||||
const totalPages = Math.ceil(totalPosts.length / POSTS_PER_PAGE)
|
||||
const paths = Array.from({ length: totalPages }, (_, i) => ({
|
||||
params: { page: (i + 1).toString() },
|
||||
}))
|
||||
|
||||
return {
|
||||
paths,
|
||||
fallback: false,
|
||||
}
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps<{
|
||||
posts: PostFrontMatter[]
|
||||
initialDisplayPosts: PostFrontMatter[]
|
||||
pagination: { currentPage: number; totalPages: number }
|
||||
}> = async (context) => {
|
||||
const {
|
||||
params: { page },
|
||||
} = context
|
||||
const posts = await getAllFilesFrontMatter('blog')
|
||||
const pageNumber = parseInt(page as string)
|
||||
const initialDisplayPosts = posts.slice(
|
||||
POSTS_PER_PAGE * (pageNumber - 1),
|
||||
POSTS_PER_PAGE * pageNumber
|
||||
)
|
||||
const pagination = {
|
||||
currentPage: pageNumber,
|
||||
totalPages: Math.ceil(posts.length / POSTS_PER_PAGE),
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
posts,
|
||||
initialDisplayPosts,
|
||||
pagination,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default function PostPage({
|
||||
posts,
|
||||
initialDisplayPosts,
|
||||
pagination,
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
return (
|
||||
<>
|
||||
<PageSEO title={siteMetadata.title} description={siteMetadata.description} />
|
||||
<ListLayout
|
||||
posts={posts}
|
||||
initialDisplayPosts={initialDisplayPosts}
|
||||
pagination={pagination}
|
||||
title="All Posts"
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue