mirror of
https://github.com/mat-1/matdoesdev.git
synced 2025-08-02 14:46:04 +00:00
try to add blog post content to rss
This commit is contained in:
parent
6049310e2f
commit
53ec4745c1
5 changed files with 90 additions and 76 deletions
|
@ -24,7 +24,7 @@ export async function listBlogPostSlugs(): Promise<string[]> {
|
|||
)
|
||||
}
|
||||
|
||||
interface BlogPost {
|
||||
export interface BlogPost {
|
||||
title: string
|
||||
published: string
|
||||
html: string
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS" href="/blog.rss" />
|
||||
<link rel="alternate" type="application/atom+xml" title="Atom" href="/blog.atom" />
|
||||
</svelte:head>
|
||||
|
||||
<Head />
|
||||
|
||||
<div class="section-container">
|
||||
|
|
|
@ -1,80 +1,10 @@
|
|||
import { getPost, listBlogPostSlugs } from '$lib/blog'
|
||||
import { json, type RequestHandler } from '@sveltejs/kit'
|
||||
import { getPostsUntrimmed } from './preview'
|
||||
|
||||
export const prerender = true
|
||||
|
||||
export interface BlogPostPreview {
|
||||
title: string
|
||||
published: string
|
||||
html: string
|
||||
css: string
|
||||
slug: string
|
||||
}
|
||||
|
||||
function cutOffAtLine(text: string, line: number) {
|
||||
let row = 0
|
||||
let column = 0
|
||||
|
||||
let inHtmlTag = false
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (text[i] === '<') {
|
||||
inHtmlTag = true
|
||||
} else if (text[i] === '>') {
|
||||
inHtmlTag = false
|
||||
continue
|
||||
}
|
||||
if (text[i] === '\n') {
|
||||
row++
|
||||
column = 0
|
||||
} else {
|
||||
column++
|
||||
}
|
||||
if (column > 128 && !inHtmlTag) {
|
||||
row++
|
||||
column = 0
|
||||
}
|
||||
if (row >= line && !inHtmlTag) {
|
||||
return text.slice(0, i) + '...'
|
||||
}
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
async function getPosts() {
|
||||
const existingPosts: string[] = await listBlogPostSlugs()
|
||||
|
||||
const posts = (
|
||||
await Promise.all(
|
||||
existingPosts.map(async (slug): Promise<BlogPostPreview | null> => {
|
||||
const blogPost = await getPost(slug)
|
||||
|
||||
// theoretically it's possible a blog post was deleted while we were reading the directory, so just ignore it if it's null
|
||||
if (blogPost === null) return null
|
||||
|
||||
return {
|
||||
title: blogPost.title,
|
||||
published: blogPost.published,
|
||||
// HACK: remove images, i WILL parse html with regex and you won't stop me
|
||||
html: cutOffAtLine(
|
||||
blogPost.html.replace(/<(img|iframe).+?\/?>|<\/?(img|iframe)>/g, ''),
|
||||
6
|
||||
),
|
||||
css: blogPost.css,
|
||||
slug: blogPost.slug,
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
.filter((p) => p)
|
||||
.sort((a, b) => (new Date(a!.published) > new Date(b!.published) ? -1 : 1))
|
||||
|
||||
// typescript thinks posts is (BlogPostPreview | null)[] but it's not because of the .filter
|
||||
return posts as BlogPostPreview[]
|
||||
}
|
||||
|
||||
export const GET: RequestHandler = async () => {
|
||||
const posts = await getPosts()
|
||||
const posts = await getPostsUntrimmed()
|
||||
|
||||
return json(posts)
|
||||
}
|
||||
|
|
68
src/routes/blog.json/preview.ts
Normal file
68
src/routes/blog.json/preview.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import { listBlogPostSlugs, type BlogPost, getPost } from '$lib/blog'
|
||||
|
||||
export interface BlogPostPreview {
|
||||
title: string
|
||||
published: string
|
||||
html: string
|
||||
css: string
|
||||
slug: string
|
||||
}
|
||||
|
||||
function cutOffAtLine(text: string, line: number) {
|
||||
let row = 0
|
||||
let column = 0
|
||||
|
||||
let inHtmlTag = false
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (text[i] === '<') {
|
||||
inHtmlTag = true
|
||||
} else if (text[i] === '>') {
|
||||
inHtmlTag = false
|
||||
continue
|
||||
}
|
||||
if (text[i] === '\n') {
|
||||
row++
|
||||
column = 0
|
||||
} else {
|
||||
column++
|
||||
}
|
||||
if (column > 128 && !inHtmlTag) {
|
||||
row++
|
||||
column = 0
|
||||
}
|
||||
if (row >= line && !inHtmlTag) {
|
||||
return text.slice(0, i) + '...'
|
||||
}
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
export async function getPostsUntrimmed(): Promise<BlogPost[]> {
|
||||
const existingPosts: string[] = await listBlogPostSlugs()
|
||||
|
||||
const posts = (
|
||||
await Promise.all(
|
||||
existingPosts.map(async (slug): Promise<BlogPost | null> => {
|
||||
return await getPost(slug)
|
||||
})
|
||||
)
|
||||
)
|
||||
.filter((p) => p)
|
||||
.sort((a, b) => (new Date(a!.published) > new Date(b!.published) ? -1 : 1))
|
||||
|
||||
// typescript thinks posts is (BlogPost | null)[] but it's not because of the .filter
|
||||
return posts as BlogPost[]
|
||||
}
|
||||
|
||||
export async function getPosts() {
|
||||
const posts = await getPostsUntrimmed()
|
||||
return posts.map((p) => ({
|
||||
title: p.title,
|
||||
published: p.published,
|
||||
// HACK: remove images, i WILL parse html with regex and you won't stop me
|
||||
html: cutOffAtLine(p.html.replace(/<(img|iframe).+?\/?>|<\/?(img|iframe)>/g, ''), 6),
|
||||
css: p.css,
|
||||
slug: p.slug,
|
||||
}))
|
||||
}
|
|
@ -1,16 +1,27 @@
|
|||
import type { RequestHandler } from '@sveltejs/kit'
|
||||
import type { BlogPostPreview } from '../blog.json/+server'
|
||||
import { getPostsUntrimmed } from '../blog.json/preview'
|
||||
import type { BlogPost } from '$lib/blog'
|
||||
|
||||
export const prerender = true
|
||||
|
||||
export const GET: RequestHandler = async ({ fetch }) => {
|
||||
const posts = (await fetch('/blog.json').then((r) => r.json())) as BlogPostPreview[]
|
||||
function item(post: BlogPostPreview) {
|
||||
const posts = await getPostsUntrimmed()
|
||||
function item(post: BlogPost) {
|
||||
const escapedPostHtml = post.html
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
return `
|
||||
<item>
|
||||
<title>${post.title}</title>
|
||||
<link>https://matdoes.dev/${post.slug}</link>
|
||||
<pubDate>${post.published}</pubDate>
|
||||
<description>
|
||||
${escapedPostHtml}
|
||||
<style>
|
||||
${post.css}
|
||||
</style>
|
||||
</description>
|
||||
</item>
|
||||
`
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue