Add RSS feed, add links for direct md editing on GitHub and update favicon

This commit is contained in:
thiloho
2025-04-26 22:48:37 +02:00
parent c06006d24b
commit 480ddd1e68
24 changed files with 484 additions and 23 deletions

View File

@@ -6,7 +6,7 @@ interface Props {
const { date } = Astro.props;
---
<time datetime={date.toISOString()}>
<time datetime={date.toISOString()} class="underline decoration-dotted">
{
date.toLocaleString("en-us", {
year: "numeric",

View File

@@ -4,10 +4,10 @@ import "../styles/global.css";
interface Props {
title: string;
metaDescription: string;
description: string;
}
const { title, metaDescription } = Astro.props;
const { title, description } = Astro.props;
---
<head>
@@ -21,7 +21,14 @@ const { title, metaDescription } = Astro.props;
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<meta name="description" content={metaDescription} />
<meta name="description" content={description} />
<meta name="color-scheme" content="light dark" />
<link
rel="alternate"
type="application/rss+xml"
title="Your Site's Title"
href={new URL("rss.xml", Astro.site)}
/>
<ClientRouter />
<script is:inline>
const setTheme = () => {

View File

@@ -5,9 +5,10 @@ interface Props {
title: string;
pubDate?: Date;
modDate?: Date;
slug?: string;
}
const { title, pubDate, modDate } = Astro.props;
const { title, pubDate, modDate, slug } = Astro.props;
---
<header class="bg-white dark:bg-neutral-800">
@@ -24,6 +25,21 @@ const { title, pubDate, modDate } = Astro.props;
Last modified:{" "}
{modDate ? <Date date={modDate} /> : <span>No modifications</span>}
</p>
<a
href={`https://github.com/thiloho/thiloho.github.io/edit/main/src/content/blog/${slug}/index.md`}
class="text-blue-800 dark:text-blue-300 inline-flex items-center gap-1 hover:no-underline"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-5"
>
<path d="m5.433 13.917 1.262-3.155A4 4 0 0 1 7.58 9.42l6.92-6.918a2.121 2.121 0 0 1 3 3l-6.92 6.918c-.383.383-.84.685-1.343.886l-3.154 1.262a.5.5 0 0 1-.65-.65Z" />
<path d="M3.5 5.75c0-.69.56-1.25 1.25-1.25H10A.75.75 0 0 0 10 3H4.75A2.75 2.75 0 0 0 2 5.75v9.5A2.75 2.75 0 0 0 4.75 18h9.5A2.75 2.75 0 0 0 17 15.25V10a.75.75 0 0 0-1.5 0v5.25c0 .69-.56 1.25-1.25 1.25h-9.5c-.69 0-1.25-.56-1.25-1.25v-9.5Z" />
</svg>
Edit this page
</a>
</hgroup>
) : (
<h1>{title}</h1>

View File

@@ -6,7 +6,7 @@ const routes = ["blog"];
<nav class="max-w-none bg-neutral-100 dark:bg-neutral-900 sticky top-0 z-10">
<div
class="dark:text-neutral-300 flex items-center justify-between max-w-screen-lg mx-auto ps-4 pe-2"
class="text-neutral-700 dark:text-neutral-300 flex items-center justify-between max-w-screen-lg mx-auto ps-4 pe-2"
>
<a href="/" title="Home">
<Logo width={42} height={42} />
@@ -54,6 +54,26 @@ const routes = ["blog"];
></path>
</svg>
</button>
<a
class="inline-grid place-content-center p-2 cursor-pointer border-b-2 border-transparent hover:bg-neutral-200 hover:border-neutral-400 hover:dark:bg-neutral-700 hover:dark:border-neutral-600"
title="RSS feed"
href="/rss.xml"
>
<!-- RSS -->
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="size-5"
>
<path
d="M3.75 3a.75.75 0 0 0-.75.75v.5c0 .414.336.75.75.75H4c6.075 0 11 4.925 11 11v.25c0 .414.336.75.75.75h.5a.75.75 0 0 0 .75-.75V16C17 8.82 11.18 3 4 3h-.25Z"
></path>
<path
d="M3 8.75A.75.75 0 0 1 3.75 8H4a8 8 0 0 1 8 8v.25a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1-.75-.75V16a6 6 0 0 0-6-6h-.25A.75.75 0 0 1 3 9.25v-.5ZM7 15a2 2 0 1 1-4 0 2 2 0 0 1 4 0Z"
></path>
</svg>
</a>
</div>
</div>
</nav>

View File

@@ -8,7 +8,6 @@ const index = defineCollection({
const blog = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
schema: z.object({
id: z.number().positive(),
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),

View File

@@ -1,5 +1,4 @@
---
id: 1
title: "Steps to install NixOS on a system with ext4 and LUKS"
description: "A guide to installing NixOS with full disk encryption using LUKS and LVM, showing the complete process from disk partitioning to system configuration"
pubDate: "2025-01-04"

View File

@@ -1,5 +1,4 @@
---
id: 2
title: "Privacy-focused operating systems"
description: "Good choices for privacy-focused operating systems for desktop and mobile phones."
pubDate: "2025-01-16"

View File

@@ -6,19 +6,20 @@ import Footer from "../components/Footer.astro";
interface Props {
title: string;
metaDescription: string;
description: string;
pubDate?: Date;
modDate?: Date;
slug?: string;
}
const { title, metaDescription, pubDate, modDate } = Astro.props;
const { title, description, pubDate, modDate, slug } = Astro.props;
---
<html lang="en" class="light">
<Head {title} {metaDescription} />
<Head {title} {description} />
<body class="min-h-screen flex flex-col">
<Nav />
<Header {title} {pubDate} {modDate} />
<Header {title} {pubDate} {modDate} {slug} />
<main class="flex-1 bg-white dark:bg-neutral-800">
<div
class={`relative prose prose-neutral dark:prose-invert mx-auto px-4 ${pubDate ? "pt-0" : "pt-8"} pb-16 prose-headings:scroll-mt-16 prose-h1:font-bold prose-pre:!bg-neutral-700 prose-a:text-blue-800 prose-a:dark:text-blue-300 prose-a:hover:no-underline`}

View File

@@ -22,9 +22,10 @@ const { Content, headings } = await render(article);
<PageLayout
title={article.data.title}
metaDescription="Blog"
description="Blog"
pubDate={article.data.pubDate}
modDate={article.data.modDate}
{slug}
>
<details class="toc sticky top-0 z-20">
<summary

View File

@@ -9,11 +9,11 @@ const sortedArticles = allArticles.sort((a, b) => {
});
---
<PageLayout title="Blog" metaDescription="Blog">
<PageLayout title="Blog" description="Blog">
<ul>
{
sortedArticles.map((article) => (
<li class="gap-1">
<li class="flex gap-2">
<Date date={article.data.pubDate} />
<span>&raquo;</span>
<a

View File

@@ -2,6 +2,6 @@
import PageLayout from "../layouts/PageLayout.astro";
---
<PageLayout title="Contact" metaDescription="Contact">
<PageLayout title="Contact" description="Contact">
<p>Example content</p>
</PageLayout>

View File

@@ -11,6 +11,6 @@ if (!indexContent) {
const { Content } = await render(indexContent);
---
<PageLayout title="Thilo Hohlt" metaDescription="Thilo Hohlt">
<PageLayout title="Thilo Hohlt" description="Thilo Hohlt">
<Content />
</PageLayout>

View File

@@ -11,6 +11,6 @@ if (!legalContent) {
const { Content } = await render(legalContent);
---
<PageLayout title="Legal Disclosure" metaDescription="Legal Disclosure">
<PageLayout title="Legal Disclosure" description="Legal Disclosure">
<Content />
</PageLayout>

23
src/pages/rss.xml.js Normal file
View File

@@ -0,0 +1,23 @@
import rss from "@astrojs/rss";
import { getCollection } from "astro:content";
import sanitizeHtml from "sanitize-html";
import MarkdownIt from "markdown-it";
const parser = new MarkdownIt();
export const GET = async (context) => {
const blog = await getCollection("blog");
return rss({
title: "Thilo Hohlts Blog",
description: "Thilo Hohlts Blog",
site: context.site,
trailingSlash: false,
stylesheet: "pretty-feed-v3.xsl",
items: blog.map((article) => ({
link: `/blog/${article.id}/`,
content: sanitizeHtml(parser.render(article.body), {
allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
}),
...article.data,
})),
});
};