mirror of
https://github.com/andwati/personal-website.git
synced 2026-10-22 20:42:15 +00:00
Add book, engineering, and writing content handling with MDX support
This commit is contained in:
+40
@@ -0,0 +1,40 @@
|
||||
import { getMdxContent, MaybeContent } from "./mdx";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
export interface Book {
|
||||
title: string;
|
||||
author: string;
|
||||
date: string;
|
||||
rating: number;
|
||||
coverImage: string;
|
||||
spineColor: string;
|
||||
textColor: string;
|
||||
slug: string;
|
||||
summary: string;
|
||||
}
|
||||
|
||||
export function getAllBooks(): Book[] {
|
||||
return JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(process.cwd(), "content", "books", "index.json"),
|
||||
"utf8",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function getAllSlugs(): string[] {
|
||||
const data = getAllBooks();
|
||||
return data.map((item) => item.slug);
|
||||
}
|
||||
|
||||
export async function getBook(slug: string): Promise<MaybeContent<Book>> {
|
||||
const book = await getMdxContent<Book>("books", `${slug}.mdx`);
|
||||
if (!book) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
...book,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { getMdxContent, MaybeContent } from "./mdx";
|
||||
|
||||
export interface Build {
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
date: string;
|
||||
url: string;
|
||||
external: boolean;
|
||||
source: string;
|
||||
}
|
||||
|
||||
export function getAllBuildData(): Build[] {
|
||||
return JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(process.cwd(), "content", "engineering", "index.json"),
|
||||
"utf8",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function getAllSlugs(): string[] {
|
||||
const data = getAllBuildData();
|
||||
|
||||
return data.filter((item) => !item.external).map((item) => item.url);
|
||||
}
|
||||
|
||||
export async function getBuil(slug: string): Promise<MaybeContent<Build>> {
|
||||
return getMdxContent<Build>("engineering", `${slug}.mdx`);
|
||||
}
|
||||
+11
-13
@@ -5,7 +5,7 @@ import remarkGfm from "remark-gfm";
|
||||
|
||||
export interface Content<TMetadata = { [key: string]: any }> {
|
||||
metadata: TMetadata;
|
||||
content: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
export type MaybeContent<TMetadata> = Content<TMetadata> | undefined;
|
||||
@@ -14,29 +14,27 @@ export async function getMdxContent<TMetadata>(
|
||||
...paths: string[]
|
||||
): Promise<MaybeContent<TMetadata>> {
|
||||
const contentPath = path.join(process.cwd(), "content", ...paths);
|
||||
|
||||
if (!fs.existsSync(contentPath)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(contentPath, "utf-8");
|
||||
|
||||
const content = fs.readFileSync(contentPath, "utf8");
|
||||
const source = await serialize(content, {
|
||||
parseFrontmatter: true,
|
||||
mdxOptions: {
|
||||
remarkPlugins: [remarkGfm],
|
||||
development: false,
|
||||
remarkPlugins: [remarkGfm],
|
||||
},
|
||||
});
|
||||
|
||||
// Remove the ugly footnotes heading from react-gfm
|
||||
const footnotes =
|
||||
/_jsx\(_components.h2, {.*?children: "Footnotes".*?}\), "\\n", /gs;
|
||||
const hr = ``;
|
||||
const compiledSource = source.compiledSource.replaceAll(footnotes, hr);
|
||||
|
||||
const footnotes = /_jsx\(_components.h2, {.*?children: "Footnotes".*?}\), "\\n", /gs;
|
||||
const hr = ``
|
||||
const compiledSource = source.compiledSource.replace(footnotes, hr);
|
||||
|
||||
return{
|
||||
return {
|
||||
metadata: source.frontmatter as TMetadata,
|
||||
content: compiledSource,
|
||||
}
|
||||
|
||||
source: compiledSource,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { getMdxContent, MaybeContent } from "./mdx";
|
||||
|
||||
export interface DeepDive {
|
||||
title: string;
|
||||
image: string;
|
||||
description: string;
|
||||
links: {
|
||||
label: string;
|
||||
href: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function getDeepDives(): DeepDive[] {
|
||||
return JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(process.cwd(), "content", "deep-dives", "index.json"),
|
||||
"utf8"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export interface Post {
|
||||
title: string;
|
||||
description: string;
|
||||
image: string;
|
||||
date: string;
|
||||
url: string;
|
||||
external: boolean;
|
||||
source: string;
|
||||
}
|
||||
|
||||
export function getAllPostData(): Post[] {
|
||||
return JSON.parse(
|
||||
fs.readFileSync(
|
||||
path.join(process.cwd(), "content", "writing", "index.json"),
|
||||
"utf8"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function getAllSlugs(): string[] {
|
||||
const data = getAllPostData();
|
||||
|
||||
return data.filter((item) => !item.external).map((item) => item.url);
|
||||
}
|
||||
|
||||
export async function getPost(slug: string): Promise<MaybeContent<Post>> {
|
||||
return getMdxContent<Post>("writing", `${slug}.mdx`);
|
||||
}
|
||||
Reference in New Issue
Block a user