use collections and provide rss feed for the blog

This commit is contained in:
2024-07-22 19:37:18 +02:00
parent 0bca511144
commit 3cc883d082
13 changed files with 1876 additions and 1486 deletions
+1779 -1442
View File
File diff suppressed because it is too large Load Diff
+9 -4
View File
@@ -9,12 +9,17 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/mdx": "^2.0.0",
"@astrojs/svelte": "^5.0.0",
"astro": "^4.0.1",
"@astrojs/mdx": "^2.3.1",
"@astrojs/rss": "^4.0.7",
"@astrojs/svelte": "^5.7.0",
"astro": "^4.12.2",
"markdown-it": "^14.1.0",
"marked": "^13.0.2",
"reading-time": "^1.5.0",
"rehype-external-links": "^3.0.0",
"remark-gfm": "^4.0.0",
"remark-smartypants": "^2.0.0"
"remark-smartypants": "^2.1.0",
"sanitize-html": "^2.13.0",
"zod": "^3.23.8"
}
}
View File
+6
View File
@@ -17,6 +17,12 @@ const socialUrl = Astro.site.href + 'assets/yht_logo.png'
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link
rel="alternate"
type="application/rss+xml"
title="YouHaveBlog RSS Feed"
href={new URL("rss.xml", Astro.site)}
/>
<!-- Primary Meta Tags -->
<title> {title} | YouHaveTrouble's place</title>
+1 -1
View File
@@ -9,5 +9,5 @@
</style>
<a href="/">
<img alt="Blog Logo" src="/assets/yht_logo.png" width="50px" height="50px" />
<img alt="Logo displaying a stylized character with brown hair wearing purple hoodie on a light blue circle background" src="/assets/yht_logo.png" width="50px" height="50px" />
</a>
+14
View File
@@ -0,0 +1,14 @@
import { z, defineCollection } from 'astro:content';
const posts = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
publishDate: z.string(),
tags: z.array(z.string()),
image: z.string().optional(),
}),
});
export const collections = {
posts,
};
+1
View File
@@ -1 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" />
+24 -18
View File
@@ -1,24 +1,32 @@
---
import {getCollection} from "astro:content";
import BaseLayout from '../../layouts/BaseLayout.astro';
import Bio from '../../components/Bio.astro';
import getPostData from '../../utils/getPostData';
import readingTime from 'reading-time';
import { marked } from 'marked';
export async function getStaticPaths() {
let posts = [];
try {
posts = await Astro.glob('../../data/blog-posts/*.md');
} catch (error) {
console.error("No blog posts found");
}
const posts = await getCollection('posts');
return posts.map(p => ({
params: { slug: p.file.split('/').pop().split('.').shift() },
props: { post: p },
params: {
slug: p.slug
},
props: {
title: p.data.title,
publishDate: p.data.publishDate,
slug: p.slug,
tags: "test",
content: marked.parse(p.body),
readingTime: readingTime(p.body).text,
}
}));
}
const { Content, frontmatter } = Astro.props.post;
const { title, description, publishDate, tags } = frontmatter;
const { slug, readingTime } = getPostData(Astro.props.post);
const { slug, title, description, publishDate, tags, content, readingTime } = Astro.props;
const props = Astro.props;
const permalink = `${Astro.site.href}blog/${slug}`;
---
@@ -27,16 +35,14 @@ const permalink = `${Astro.site.href}blog/${slug}`;
<p>{publishDate} ~ {readingTime}</p>
<h1>{title}</h1>
<div class="tags" style="justify-content: center">
{tags.map(item => (
<span class="tag">{item}</span>
))}
<!--{tags.map(item => (-->
<!-- <span class="tag">{item}</span>-->
<!--))}-->
</div>
<hr />
</header>
<div class="container">
<article class="content">
<Content />
</article>
<article class="content" set:html={content}></article>
<hr />
<Bio />
</div>
+2 -2
View File
@@ -2,11 +2,11 @@
import BaseLayout from '../../layouts/BaseLayout.astro';
const title = 'Blog';
const description = 'Latest articles.';
const description = 'Something that\'s supposed to be thoughts';
const permalink = `${Astro.site.href}blog`;
let allPosts = [];
try {
allPosts = await Astro.glob('../../data/blog-posts/*.md');
allPosts = await Astro.glob('../../content/posts/*.md');
} catch (error) {
console.error('No blog posts found');
}
+22
View File
@@ -0,0 +1,22 @@
import rss from '@astrojs/rss';
import sanitizeHtml from 'sanitize-html';
import { marked } from 'marked';
import {getCollection} from "astro:content";
export async function GET(context: { site: any; }) {
const posts = await getCollection('posts');
return rss({
title: 'YouHaveBlog',
description: 'Something that\'s supposed to be thoughts.',
site: context.site,
items: posts.map((post) => ({
link: `/blog/${post.slug}/`,
content: sanitizeHtml(marked.parse(post.body), {
allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img'])
}),
pubDate: new Date(post.data.publishDate),
...post.data,
})),
});
}
+11
View File
@@ -7,6 +7,11 @@
--font-family-sans: 'Fira Sans', sans-serif;
}
/* break comment when time is right */
/*@view-transition {*/
/* navigation: auto;*/
/*}*/
:root.theme-dark {
--background-body: #202122;
--text-main: #fff;
@@ -278,6 +283,12 @@ span.tag::before {
content: '#';
}
iframe {
width: 100%;
aspect-ratio: 16/9;
border: 0;
}
@media (max-width: 1020px) {
h1 {
font-size: 3em;
-14
View File
@@ -1,14 +0,0 @@
import readingTime from 'reading-time'
type Post = {
title: string
file: string
rawContent: () => string
}
export default function getPostData(post: Post) {
return {
slug: post.file.split('/').pop().split('.').shift(),
readingTime: readingTime(post.rawContent()).text,
}
}
+3 -1
View File
@@ -1,4 +1,5 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
// Enable top-level await, and other modern ESM features.
"target": "ESNext",
@@ -10,6 +11,7 @@
// Enable stricter transpilation for better output.
"isolatedModules": true,
// Astro will directly run your TypeScript code, no transpilation needed.
"noEmit": true
"noEmit": true,
"strictNullChecks": true
}
}