Start the blog

This commit is contained in:
Dave Smith-Hayes 2024-07-02 22:35:01 -04:00
commit 2e7b5da0f9
12 changed files with 157 additions and 0 deletions

3
.editorconfig Normal file
View File

@ -0,0 +1,3 @@
[*.{js,ts,jsx,tsx,json}]
indent_style = space
indent_size = 2

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# deps
node_modules/

11
README.md Normal file
View File

@ -0,0 +1,11 @@
To install dependencies:
```sh
bun install
```
To run:
```sh
bun run dev
```
open http://localhost:3000

BIN
bun.lockb Executable file

Binary file not shown.

16
package.json Normal file
View File

@ -0,0 +1,16 @@
{
"name": "blog",
"scripts": {
"dev": "bun run --hot src/index.tsx"
},
"dependencies": {
"@types/yaml-front-matter": "^4.1.3",
"hono": "^4.4.10",
"marked": "^13.0.1",
"remark": "^15.0.1",
"yaml-front-matter": "^4.1.1"
},
"devDependencies": {
"@types/bun": "latest"
}
}

10
src/Model/Post.ts Normal file
View File

@ -0,0 +1,10 @@
import { Tag } from '@blog/Model/Tag';
export type Post = {
title: string,
slug: string,
description: string,
content: string,
date: Date,
tags: string[]
};

38
src/index.tsx Normal file
View File

@ -0,0 +1,38 @@
import { Hono } from 'hono';
import { jsxRenderer, useRequestContext } from 'hono/jsx-renderer';
import { Page } from '@blog/templates/Page';
import { Home } from '@blog/templates/Pages/Home';
import { readdir } from 'node:fs/promises';
const app = new Hono();
app.get(
'*',
jsxRenderer(
({ children }) => {
return (<Page>{children}</Page>);
},
{
docType: true
}
)
);
// read all posts
// create listing of posts
app.get('/', async (c) => {
const files = await readdir('../posts', { recursive: true });
const posts = files.filter(f => f === '.' || f === '..');
return c.render(<Home posts={posts}/>);
});
app.get('/posts/:slug', (c) => {
const postSlug: string = c.req.param("slug");
// render post
// send to Post layout
});
export default app;

21
src/readPostMarkdown.ts Normal file
View File

@ -0,0 +1,21 @@
import { marked } from 'marked';
import type { Post } from '@blog/Model/Post';
import * as yamlFront from 'yaml-front-matter';
export async function readPostMarkdown(filename: string): Promise<Post> {
const file = Bun.file(filename);
const contents = await file.text();
const parsedData = yamlFront.loadFront(contents);
const parsedPost = await marked.parse(parsedData.__content);
return {
title: parsedData.title,
slug: filename.slice(0, -3),
description: parsedData.description,
date: new Date(parsedData.date),
tags: parsedData.tags,
content: parsedPost
};
}

20
src/templates/Page.tsx Normal file
View File

@ -0,0 +1,20 @@
export function Page({ children }: { children: any }) {
return (
<html lang="en">
<head>
<title>davesmithhayes.com</title>
</head>
<body>
<header>
<div class="logo">davesmithhayes.com</div>
</header>
<main>
{children}
</main>
<footer>
<div class="copyright">&copy; 2024 Dave Smith-Hayes</div>
</footer>
</body>
</html>
);
}

View File

@ -0,0 +1,11 @@
import { PostList } from '@blog/templates/components/PostList';
export function Home({ posts }: { posts: string[] }) {
return (
<div class="main">
<h1>davesmithhayes.com</h1>
{posts.length ? <PostList posts={posts} /> : <div>No posts.</div>}
</div>
);
}

View File

@ -0,0 +1,15 @@
import type { Post } from '@blog/Model/Post';
export function PostList(postList: Post[]) {
return(
<ul>
{postList.map(p => {
return (
<li>
<a href={p.slug}>{p.name}</a>
</li>
);
})}
</ul>
);
}

10
tsconfig.json Normal file
View File

@ -0,0 +1,10 @@
{
"compilerOptions": {
"strict": true,
"jsx": "react-jsx",
"jsxImportSource": "hono/jsx",
"paths": {
"@blog/*": [ "./src/*" ]
}
}
}