Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
f41d77c93a |
@ -9,7 +9,6 @@ COPY tsconfig.json .
|
||||
RUN bun install --frozen-lockfile
|
||||
COPY ./src ./src
|
||||
COPY ./posts ./posts
|
||||
COPY ./config ./config
|
||||
|
||||
USER bun
|
||||
CMD [ "bun", "src/index.tsx" ]
|
||||
|
16
README.md
16
README.md
@ -1,19 +1,3 @@
|
||||
# davesmithhayes.com
|
||||
|
||||
This repository holds the code that deploys into the blog for Dave Smith-Hayes.
|
||||
|
||||
## TODO
|
||||
|
||||
This is an unorganized list of the features left for the blog.
|
||||
|
||||
* Pages Handler
|
||||
* Renders Markdown pages into HTML pages
|
||||
* Dynamic Navigation
|
||||
* Blog Roll
|
||||
* List of blogs I have read and liked
|
||||
* External Links
|
||||
* Links to my git, music, other things
|
||||
* RSS Feed
|
||||
* robots.txt
|
||||
* Site map
|
||||
* Images on posts and pages
|
||||
|
@ -1,12 +0,0 @@
|
||||
title = "davesmithhayes.com"
|
||||
|
||||
[owner]
|
||||
name = "Dave Smith-Hayes"
|
||||
email = "me@davesmithhayes.com"
|
||||
|
||||
[site]
|
||||
description = "Personal website of Dave Smith-Hayes - a father, developer, and musician."
|
||||
url = "https://davesmithhayes.com"
|
||||
repo = "https://git.davesmithhayes.com/dsh/blog"
|
||||
language = "en"
|
||||
copyright = "All rights reserved, Dave Smith-Hayes"
|
@ -5,13 +5,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/yaml-front-matter": "^4.1.3",
|
||||
"feed": "^4.2.2",
|
||||
"highlight.js": "^11.10.0",
|
||||
"hono": "^4.6.13",
|
||||
"marked": "^13.0.3",
|
||||
"marked-highlight": "^2.2.1",
|
||||
"hono": "^4.4.13",
|
||||
"marked": "^13.0.2",
|
||||
"marked-highlight": "^2.1.3",
|
||||
"remark": "^15.0.1",
|
||||
"smol-toml": "^1.3.1",
|
||||
"yaml-front-matter": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1,4 +1,3 @@
|
||||
export const POST_PATH: string = __dirname + '/../posts';
|
||||
export const CONFIG_PATH: string = __dirname + '/../config';
|
||||
export const STATIC_PATH: string = __dirname + '/assets';
|
||||
export const POST_ROUTE_PREFIX: string = '/posts'
|
||||
|
16
src/handlers/about.tsx
Normal file
16
src/handlers/about.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import { Hono, Context } from 'hono';
|
||||
|
||||
const aboutPage = new Hono();
|
||||
|
||||
export async handleAboutPage(c: Context) {
|
||||
const meta: SiteMeta = {
|
||||
title: "About",
|
||||
description: "About Dave Smith-Hayes - a dad, developer, musician.",
|
||||
author: "Dave Smith-Hayes"
|
||||
};
|
||||
|
||||
c.render(<AboutPage />, { meta });
|
||||
}
|
||||
|
||||
aboutPage.get("/about", handleAboutPage);
|
||||
export default aboutPage;
|
@ -1,21 +0,0 @@
|
||||
import { Hono, Context } from 'hono';
|
||||
import { PostService } from '@blog/services/post-file';
|
||||
import { getFeed } from '@blog/services/feed-generator';
|
||||
import { Feed } from 'feed';
|
||||
|
||||
const feed = new Hono<{ Variables: { postService: PostService }}>();
|
||||
let feedBuffer: string = "";
|
||||
|
||||
export async function getFeedFile(c: Context) {
|
||||
if (!feedBuffer) {
|
||||
const postService: PostService = c.get('postService');
|
||||
const feed: Feed = await getFeed(postService);
|
||||
feedBuffer = feed.rss2();
|
||||
}
|
||||
|
||||
c.header('Content-Type', 'text/xml');
|
||||
return c.body(feedBuffer);
|
||||
}
|
||||
|
||||
feed.get('/rss.xml', getFeedFile);
|
||||
export default feed;
|
@ -4,7 +4,6 @@ import { serveStatic } from 'hono/bun';
|
||||
import { Page } from '@blog/templates/Page';
|
||||
import home from '@blog/handlers/home';
|
||||
import posts from '@blog/handlers/posts';
|
||||
import feed from '@blog/handlers/feed';
|
||||
import type { SiteMeta } from '@blog/models/SiteMeta';
|
||||
import { postFileMiddleware } from '@blog/middleware/post-service';
|
||||
import { logger } from 'hono/logger';
|
||||
@ -37,7 +36,6 @@ app.use('/static/*', serveStatic({
|
||||
}));
|
||||
|
||||
app.route('/', home);
|
||||
app.route('/feed', feed)
|
||||
app.route('/posts', posts);
|
||||
|
||||
console.log("Starting the blog");
|
||||
|
@ -1,6 +1,3 @@
|
||||
/**
|
||||
* SiteMeta is often used for the `<meta />` tags in the document header
|
||||
*/
|
||||
export type SiteMeta = {
|
||||
description?: string,
|
||||
tags?: string[],
|
||||
|
@ -1,9 +0,0 @@
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
import { getSiteConfig } from '@blog/services/config';
|
||||
|
||||
describe("Test the global config for the site", () => {
|
||||
test("Parses the Owner", async () => {
|
||||
const siteConfig = await getSiteConfig();
|
||||
expect(siteConfig.owner.email).toBe("me@davesmithhayes.com");
|
||||
})
|
||||
})
|
@ -1,24 +0,0 @@
|
||||
import TOML from 'smol-toml';
|
||||
import { CONFIG_PATH } from '@blog/config';
|
||||
|
||||
export type SiteConfig = {
|
||||
title: string;
|
||||
owner: {
|
||||
name: string;
|
||||
email: string;
|
||||
};
|
||||
site: {
|
||||
description: string;
|
||||
url: string;
|
||||
repo: string;
|
||||
language: string;
|
||||
copyright: string;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSiteConfig(): Promise<SiteConfig> {
|
||||
const siteConfig = CONFIG_PATH + '/site.toml';
|
||||
const file = Bun.file(siteConfig);
|
||||
const data = await file.text();
|
||||
return TOML.parse(data) as SiteConfig;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import { Feed, FeedOptions } from 'feed';
|
||||
import { getSiteConfig } from '@blog/services/config';
|
||||
import { PostService } from '@blog/services/post-file';
|
||||
import type { Post } from '@blog/models/post';
|
||||
|
||||
const updatedDate = new Date();
|
||||
|
||||
export async function getFeed(postService: PostService): Feed {
|
||||
const config = await getSiteConfig();
|
||||
const feed = new Feed({
|
||||
title: config.title,
|
||||
description: config.site.description,
|
||||
link: config.site.link,
|
||||
language: config.site.language,
|
||||
copyright: config.site.copyright,
|
||||
generator: "dsh feed gen",
|
||||
updated: updatedDate,
|
||||
author: {
|
||||
name: "Dave Smith-Hayes",
|
||||
email: "me@davesmithhayes.com",
|
||||
link: "davesmithhayes.com"
|
||||
}
|
||||
});
|
||||
|
||||
postService.getPublishedPosts().map((post: Post) => {
|
||||
feed.addItem({
|
||||
title: post.meta.title,
|
||||
id: post.meta.slug,
|
||||
link: post.meta.slug,
|
||||
description: post.meta.description,
|
||||
content: post.html,
|
||||
author: {
|
||||
name: config.author,
|
||||
email: config.email
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return feed;
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Style } from 'hono/css';
|
||||
import { SiteMeta } from '@blog/models/SiteMeta';
|
||||
import { MetaTags } from '@blog/templates/components/MetaTags';
|
||||
import { Navigation } from '@blog/templates/componennts/Navigation';
|
||||
|
||||
function getPageTitle(title: string|undefined): string {
|
||||
if (!title) {
|
||||
@ -25,6 +26,9 @@ export function Page({ children, meta }: { children: any, meta: SiteMeta }) {
|
||||
<a href="/">davesmithhayes.com</a>
|
||||
</div>
|
||||
</header>
|
||||
<nav>
|
||||
<Navigation />
|
||||
</nav>
|
||||
<main>
|
||||
{children}
|
||||
</main>
|
||||
|
7
src/templates/Pages/AboutPage.tsx
Normal file
7
src/templates/Pages/AboutPage.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
export function AboutPage() {
|
||||
return (
|
||||
<div class="main">
|
||||
<p>Hello! I am Dave Smith-Hayes.</p>
|
||||
</div>
|
||||
);
|
||||
}
|
12
src/templates/components/Navigation.tsx
Normal file
12
src/templates/components/Navigation.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
const pages: Array<{ path: string, title: string }> = [
|
||||
{ path: "/", title: "Home" },
|
||||
{ path: "/about", title: "About" },
|
||||
];
|
||||
|
||||
export function Navigation() {
|
||||
return (
|
||||
<ul>
|
||||
{pages.map(p => <li><a href={p.path}>{p.title}</a></li> )}
|
||||
</ul>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user