-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
cesalberca
committed
Jul 3, 2024
1 parent
452b57d
commit 5621053
Showing
46 changed files
with
250 additions
and
269 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import Link from 'next/link' | ||
import { getTalks } from '../utils-talks' | ||
|
||
export function Talks() { | ||
const allTalks = getTalks() | ||
|
||
return ( | ||
<div> | ||
{allTalks.map(post => ( | ||
<Link key={post.slug} className="flex flex-col space-y-1 mb-4" href={`/blog/${post.slug}`}> | ||
<div className="w-full flex flex-col md:flex-row space-x-0 md:space-x-2"> | ||
<p className="text-neutral-600 dark:text-neutral-400 w-[100px] tabular-nums"></p> | ||
<p className="text-neutral-900 dark:text-neutral-100 tracking-tight">{post.metadata.title}</p> | ||
</div> | ||
</Link> | ||
))} | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { notFound } from 'next/navigation' | ||
import { getBlogPosts } from '../../utils' | ||
import { baseUrl } from '../../sitemap' | ||
import { CustomMDX } from '../../components/mdx' | ||
import type { Metadata } from 'next' | ||
|
||
interface Params { | ||
params: { | ||
slug: string | ||
} | ||
} | ||
|
||
export async function generateStaticParams() { | ||
let posts = getBlogPosts() | ||
|
||
return posts.map(post => ({ | ||
slug: post.slug, | ||
})) | ||
} | ||
|
||
export function generateMetadata({ params }: Params): Metadata | void { | ||
let post = getBlogPosts().find(post => post.slug === params.slug) | ||
if (!post) { | ||
return | ||
} | ||
|
||
let { title, date: publishedTime, image, summary } = post.metadata | ||
let ogImage = image ? image : `${baseUrl}/og?title=${encodeURIComponent(title)}` | ||
|
||
return { | ||
title, | ||
description: summary, | ||
openGraph: { | ||
title, | ||
description: summary, | ||
type: 'article', | ||
publishedTime, | ||
url: `${baseUrl}/blog/${post.slug}`, | ||
images: [ | ||
{ | ||
url: ogImage, | ||
}, | ||
], | ||
}, | ||
twitter: { | ||
card: 'summary_large_image', | ||
title, | ||
description: summary, | ||
images: [ogImage], | ||
}, | ||
} | ||
} | ||
|
||
export default function Blog({ params }: Params) { | ||
let post = getBlogPosts().find(post => post.slug === params.slug) | ||
|
||
if (!post) { | ||
notFound() | ||
} | ||
|
||
return ( | ||
<section> | ||
<script | ||
type="application/ld+json" | ||
suppressHydrationWarning | ||
dangerouslySetInnerHTML={{ | ||
__html: JSON.stringify({ | ||
'@context': 'https://schema.org', | ||
'@type': 'BlogPosting', | ||
headline: post.metadata.title, | ||
datePublished: post.metadata.date, | ||
dateModified: post.metadata.date, | ||
description: post.metadata.summary, | ||
image: post.metadata.image | ||
? `${baseUrl}${post.metadata.image}` | ||
: `/og?title=${encodeURIComponent(post.metadata.title)}`, | ||
url: `${baseUrl}/blog/${post.slug}`, | ||
author: { | ||
'@type': 'Person', | ||
name: 'My Portfolio', | ||
}, | ||
}), | ||
}} | ||
/> | ||
<h1 className="title font-semibold text-2xl tracking-tighter">{post.metadata.title}</h1> | ||
<div className="flex justify-between items-center mt-2 mb-8 text-sm"> | ||
<p className="text-sm text-neutral-600 dark:text-neutral-400">{post.metadata.date}</p> | ||
</div> | ||
<article className="prose"> | ||
<CustomMDX source={post.content} /> | ||
</article> | ||
</section> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Talks } from '../components/talks' | ||
|
||
export const metadata = { | ||
title: 'Talks', | ||
description: `Here are all the talks I've given.`, | ||
} | ||
|
||
export default function Page() { | ||
return ( | ||
<section> | ||
<h1 className="font-semibold text-2xl mb-8 tracking-tighter">My Blog</h1> | ||
<Talks /> | ||
</section> | ||
) | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import fs from 'fs' | ||
import path from 'path' | ||
|
||
interface Metadata { | ||
title: string | ||
length: string | ||
difficulty: string | ||
language: string | ||
// topics: string[] | ||
|
||
image: string | ||
// events: { | ||
// name: string | ||
// date: string | ||
// slides: string | ||
// video: string | ||
// }[] | ||
} | ||
|
||
// TODO: Parse frontmatter array | ||
function parseFrontmatter(fileContent: string) { | ||
let frontmatterRegex = /---\s*([\s\S]*?)\s*---/ | ||
let match = frontmatterRegex.exec(fileContent) | ||
let frontMatterBlock = match![1] | ||
let content = fileContent.replace(frontmatterRegex, '').trim() | ||
let frontMatterLines = frontMatterBlock.trim().split('\n') | ||
let metadata: Partial<Metadata> = {} | ||
|
||
frontMatterLines.forEach(line => { | ||
let [key, ...valueArr] = line.split(': ') | ||
let value = valueArr.join(': ').trim() | ||
value = value.replace(/^['"](.*)['"]$/, '$1') // Remove quotes | ||
metadata[key.trim() as keyof Metadata] = value | ||
}) | ||
|
||
return { metadata: metadata as Metadata, content } | ||
} | ||
|
||
function getMDXFiles(dir: string) { | ||
return fs.readdirSync(dir).filter(file => path.extname(file) === '.mdx') | ||
} | ||
|
||
function readMDXFile(filePath: string) { | ||
let rawContent = fs.readFileSync(filePath, 'utf-8') | ||
return parseFrontmatter(rawContent) | ||
} | ||
|
||
function getMDXData(dir: string) { | ||
let mdxFiles = getMDXFiles(dir) | ||
return mdxFiles.map(file => { | ||
let { metadata, content } = readMDXFile(path.join(dir, file)) | ||
let slug = path.basename(file, path.extname(file)) | ||
|
||
return { | ||
metadata, | ||
slug, | ||
content, | ||
} | ||
}) | ||
} | ||
|
||
export function getTalks() { | ||
return getMDXData(path.join(process.cwd(), 'src', 'app', 'talks', 'talks')) | ||
} |
Oops, something went wrong.