mirror of
https://github.com/YouHaveTrouble/youhavetrouble.github.io.git
synced 2026-05-11 22:06:56 +00:00
use collections and provide rss feed for the blog
This commit is contained in:
Generated
+1782
-1445
File diff suppressed because it is too large
Load Diff
+9
-4
@@ -9,12 +9,17 @@
|
|||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^2.0.0",
|
"@astrojs/mdx": "^2.3.1",
|
||||||
"@astrojs/svelte": "^5.0.0",
|
"@astrojs/rss": "^4.0.7",
|
||||||
"astro": "^4.0.1",
|
"@astrojs/svelte": "^5.7.0",
|
||||||
|
"astro": "^4.12.2",
|
||||||
|
"markdown-it": "^14.1.0",
|
||||||
|
"marked": "^13.0.2",
|
||||||
"reading-time": "^1.5.0",
|
"reading-time": "^1.5.0",
|
||||||
"rehype-external-links": "^3.0.0",
|
"rehype-external-links": "^3.0.0",
|
||||||
"remark-gfm": "^4.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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,12 @@ const socialUrl = Astro.site.href + 'assets/yht_logo.png'
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
<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 -->
|
<!-- Primary Meta Tags -->
|
||||||
<title> {title} | YouHaveTrouble's place</title>
|
<title> {title} | YouHaveTrouble's place</title>
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<a href="/">
|
<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>
|
</a>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
};
|
||||||
Vendored
+1
@@ -1 +1,2 @@
|
|||||||
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
/// <reference types="astro/client" />
|
/// <reference types="astro/client" />
|
||||||
|
|||||||
+24
-18
@@ -1,24 +1,32 @@
|
|||||||
---
|
---
|
||||||
|
import {getCollection} from "astro:content";
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
import Bio from '../../components/Bio.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() {
|
export async function getStaticPaths() {
|
||||||
let posts = [];
|
|
||||||
try {
|
const posts = await getCollection('posts');
|
||||||
posts = await Astro.glob('../../data/blog-posts/*.md');
|
|
||||||
} catch (error) {
|
|
||||||
console.error("No blog posts found");
|
|
||||||
}
|
|
||||||
return posts.map(p => ({
|
return posts.map(p => ({
|
||||||
params: { slug: p.file.split('/').pop().split('.').shift() },
|
params: {
|
||||||
props: { post: p },
|
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 { slug, title, description, publishDate, tags, content, readingTime } = Astro.props;
|
||||||
const { title, description, publishDate, tags } = frontmatter;
|
const props = Astro.props;
|
||||||
const { slug, readingTime } = getPostData(Astro.props.post);
|
|
||||||
const permalink = `${Astro.site.href}blog/${slug}`;
|
const permalink = `${Astro.site.href}blog/${slug}`;
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -27,16 +35,14 @@ const permalink = `${Astro.site.href}blog/${slug}`;
|
|||||||
<p>{publishDate} ~ {readingTime}</p>
|
<p>{publishDate} ~ {readingTime}</p>
|
||||||
<h1>{title}</h1>
|
<h1>{title}</h1>
|
||||||
<div class="tags" style="justify-content: center">
|
<div class="tags" style="justify-content: center">
|
||||||
{tags.map(item => (
|
<!--{tags.map(item => (-->
|
||||||
<span class="tag">{item}</span>
|
<!-- <span class="tag">{item}</span>-->
|
||||||
))}
|
<!--))}-->
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
</header>
|
</header>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<article class="content">
|
<article class="content" set:html={content}></article>
|
||||||
<Content />
|
|
||||||
</article>
|
|
||||||
<hr />
|
<hr />
|
||||||
<Bio />
|
<Bio />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
|
|
||||||
const title = 'Blog';
|
const title = 'Blog';
|
||||||
const description = 'Latest articles.';
|
const description = 'Something that\'s supposed to be thoughts';
|
||||||
const permalink = `${Astro.site.href}blog`;
|
const permalink = `${Astro.site.href}blog`;
|
||||||
let allPosts = [];
|
let allPosts = [];
|
||||||
try {
|
try {
|
||||||
allPosts = await Astro.glob('../../data/blog-posts/*.md');
|
allPosts = await Astro.glob('../../content/posts/*.md');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('No blog posts found');
|
console.error('No blog posts found');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -7,6 +7,11 @@
|
|||||||
--font-family-sans: 'Fira Sans', sans-serif;
|
--font-family-sans: 'Fira Sans', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* break comment when time is right */
|
||||||
|
/*@view-transition {*/
|
||||||
|
/* navigation: auto;*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
:root.theme-dark {
|
:root.theme-dark {
|
||||||
--background-body: #202122;
|
--background-body: #202122;
|
||||||
--text-main: #fff;
|
--text-main: #fff;
|
||||||
@@ -278,6 +283,12 @@ span.tag::before {
|
|||||||
content: '#';
|
content: '#';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
width: 100%;
|
||||||
|
aspect-ratio: 16/9;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 1020px) {
|
@media (max-width: 1020px) {
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 3em;
|
font-size: 3em;
|
||||||
|
|||||||
@@ -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
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"extends": "astro/tsconfigs/base",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
// Enable top-level await, and other modern ESM features.
|
// Enable top-level await, and other modern ESM features.
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
// Enable stricter transpilation for better output.
|
// Enable stricter transpilation for better output.
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
// Astro will directly run your TypeScript code, no transpilation needed.
|
// Astro will directly run your TypeScript code, no transpilation needed.
|
||||||
"noEmit": true
|
"noEmit": true,
|
||||||
|
"strictNullChecks": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user