Most all posts into memory at startup and render those on requests.
This commit is contained in:
parent
3c4be7f78f
commit
6e400f4263
@ -1,17 +1,25 @@
|
||||
import { Hono } from 'hono';
|
||||
import { Home } from '@blog/templates/Pages/Home';
|
||||
import { getPostList } from '@blog/post/post-reader';
|
||||
import { PostMeta } from '@blog/model/PostMeta';
|
||||
import { Hono } from "hono";
|
||||
import { Home } from "@blog/templates/Pages/Home";
|
||||
import { PostMeta } from "@blog/models/PostMeta";
|
||||
import { Post } from '@blog/models/Post';
|
||||
import { PostFileService } from '@blog/services/post-file';
|
||||
|
||||
const app = new Hono();
|
||||
type Posts = {
|
||||
postService: PostFileService
|
||||
};
|
||||
|
||||
app.get('/', async (c) => {
|
||||
const postDir = __dirname + '/../../posts';
|
||||
const postList: PostMeta[] = await getPostList(postDir);
|
||||
const app = new Hono<{ Variables: Posts }>();
|
||||
|
||||
return c.render(<Home posts={postList}/>, { meta: {
|
||||
description: "The blog for Dave Smith-Hayes, a dad and developer."
|
||||
}});
|
||||
app.get("/", async (c) => {
|
||||
const postService: PostFileService = c.get('postService');
|
||||
const posts = postService.getPosts();
|
||||
const postList: PostMeta[] = Array.from(posts.values()).map((p: Post) => p.meta);
|
||||
|
||||
return c.render(<Home posts={postList} />, {
|
||||
meta: {
|
||||
description: "The blog for Dave Smith-Hayes, a dad and developer.",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
@ -1,34 +1,37 @@
|
||||
import { Hono } from 'hono';
|
||||
import { PostPage } from '@blog/templates/Pages/PostPage';
|
||||
import { FourOhFour } from '@blog/templates/Pages/FourOhFour';
|
||||
import { readdir } from 'node:fs/promises';
|
||||
import { SiteMeta } from '@blog/model/SiteMeta';
|
||||
import { readPostMarkdown } from '@blog/post/post-reader';
|
||||
import { SiteMeta } from '@blog/models/SiteMeta';
|
||||
import { PostFileService } from '@blog/services/post-file';
|
||||
|
||||
const app = new Hono();
|
||||
type Posts = {
|
||||
postService: PostFileService
|
||||
}
|
||||
|
||||
const app = new Hono<{ Variables: Posts }>();
|
||||
|
||||
app.get('/:slug', async (c) => {
|
||||
const postSlug: string = c.req.param("slug");
|
||||
const fileName: string = postSlug + '.md';
|
||||
const files = await readdir(__dirname + "/../../posts");
|
||||
const postService: PostFileService = c.get('postService');
|
||||
|
||||
const postFile = files.find(f => f === fileName);
|
||||
if (!postFile) {
|
||||
c.status(404);
|
||||
try {
|
||||
const post = postService.getPost(postSlug);
|
||||
const meta: SiteMeta = {
|
||||
description: "Page does not exist."
|
||||
description: post.meta.description,
|
||||
tags: post.meta.tags,
|
||||
author: "Dave Smith-Hayes"
|
||||
};
|
||||
|
||||
return c.render(<PostPage post={post} />, { meta });
|
||||
} catch (e) {
|
||||
const description: string = "Page does not exist.";
|
||||
console.error(description);
|
||||
console.error(e);
|
||||
|
||||
c.status(404);
|
||||
const meta: SiteMeta = { description };
|
||||
return c.render(<FourOhFour />, { meta });
|
||||
}
|
||||
|
||||
const post = await readPostMarkdown(__dirname + "/../../posts/" + postFile);
|
||||
const meta: SiteMeta = {
|
||||
description: post.meta.description,
|
||||
tags: post.meta.tags,
|
||||
author: "Dave Smith-Hayes"
|
||||
};
|
||||
|
||||
return c.render(<PostPage post={post} />, { meta });
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
@ -4,6 +4,8 @@ import { Page } from '@blog/templates/Page';
|
||||
import home from '@blog/handlers/home';
|
||||
import posts from '@blog/handlers/posts';
|
||||
import type { SiteMeta } from '@blog/models/SiteMeta';
|
||||
import { postFileMiddleware } from '@blog/middleware/post-service';
|
||||
import { logger } from 'hono/logger';
|
||||
|
||||
declare module 'hono' {
|
||||
interface ContextRenderer {
|
||||
@ -13,7 +15,10 @@ declare module 'hono' {
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
// Render the JSX views
|
||||
app.use(postFileMiddleware);
|
||||
app.use(logger());
|
||||
|
||||
// JSX Rendering for Templates
|
||||
app.get(
|
||||
'*',
|
||||
jsxRenderer(
|
||||
@ -22,7 +27,7 @@ app.get(
|
||||
)
|
||||
);
|
||||
|
||||
console.log({ message: "Bootstrapping the routes..." });
|
||||
console.log(JSON.stringify({ message: "Bootstrapping the routes..." }));
|
||||
app.route('/', home);
|
||||
app.route('/posts', posts);
|
||||
|
||||
|
14
src/middleware/post-service.ts
Normal file
14
src/middleware/post-service.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { createFactory } from 'hono/factory';
|
||||
import { PostFileService } from '@blog/services/post-file';
|
||||
|
||||
const factory = createFactory();
|
||||
let postFileService: PostFileService;
|
||||
|
||||
export const postFileMiddleware = factory.createMiddleware(async (c, next) => {
|
||||
if (!postFileService) {
|
||||
postFileService = await PostFileService.create();
|
||||
}
|
||||
|
||||
c.set('postService', postFileService);
|
||||
await next();
|
||||
});
|
@ -1,7 +1,7 @@
|
||||
import { PostMeta } from '@blog/model/PostMeta';
|
||||
import { PostMeta } from "@blog/models/PostMeta";
|
||||
|
||||
export type Post = {
|
||||
meta: PostMeta,
|
||||
content: string,
|
||||
html?: string
|
||||
meta: PostMeta;
|
||||
content: string;
|
||||
html?: string;
|
||||
};
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { Database } from "bun:sqlite";
|
||||
import { SQLITE_DATABASE_FILE } from "@blog/config";
|
||||
export const db = new Database(SQLITE_DATABASE_FILE);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { POST_PATH, POST_ROUTE_PREFIX } from '@blog/config';
|
||||
import { readdir } from 'node:fs/promises';
|
||||
import type { Post } from '@blog/models/Post';
|
||||
import * as yamlFront from 'yaml-front-matter';
|
||||
import { marked } from 'marked';
|
||||
import { POST_PATH } from "@blog/config";
|
||||
import { readdir } from "node:fs/promises";
|
||||
import type { Post } from "@blog/models/Post";
|
||||
import * as yamlFront from "yaml-front-matter";
|
||||
import { marked } from "marked";
|
||||
|
||||
export async function readPostFile(path: string): Promise<Post> {
|
||||
const file = Bun.file(path);
|
||||
@ -13,7 +13,7 @@ export async function readPostFile(path: string): Promise<Post> {
|
||||
let slug = parsedData.slug;
|
||||
|
||||
if (!slug) {
|
||||
slug = path.split('/').pop().slice(0, -3);
|
||||
slug = path.split("/").pop()?.slice(0, -3);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -23,10 +23,10 @@ export async function readPostFile(path: string): Promise<Post> {
|
||||
date: new Date(parsedData.date),
|
||||
draft: parsedData?.draft || false,
|
||||
tags: parsedData.tags,
|
||||
slug: slug
|
||||
slug: slug,
|
||||
},
|
||||
content: parsedData.__content,
|
||||
html: postHtml
|
||||
html: postHtml,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,16 @@ WHERE id = $id
|
||||
const query = db.query(queryString);
|
||||
const results = query.get({ $id: id });
|
||||
|
||||
return {}
|
||||
return {
|
||||
meta: {
|
||||
title: results.title,
|
||||
slug: results.slug,
|
||||
description: results.description,
|
||||
date: new Date(results.published_date),
|
||||
draft: results.is_draft,
|
||||
},
|
||||
content: results.raw_content,
|
||||
}
|
||||
}
|
||||
|
||||
public async getPostBySlug(slug: string): Post {
|
||||
|
@ -6,7 +6,7 @@ export function PostList({ posts }: { posts: PostMeta[] }) {
|
||||
{posts.map(p => {
|
||||
return (
|
||||
<li>
|
||||
<a href={p.slug}>{p.title}</a>
|
||||
<a href={"/posts/" + p.slug}>{p.title}</a>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
|
Loading…
Reference in New Issue
Block a user