Add types and don't show unlisted posts in HTML, feeds and sitemap. Fix JSON feed URLs.

This commit is contained in:
Jade Ellis 2025-01-06 19:17:57 +00:00
parent d6a648b6e7
commit 8dabe60322
No known key found for this signature in database
GPG key ID: 8705A2A3EBF77BD2
7 changed files with 72 additions and 31 deletions

28
packages/website/src/lib/pageTypes.d.ts vendored Normal file
View file

@ -0,0 +1,28 @@
export interface MdsvexPage {
readingTime: ReadingTime
flattenedHeadings: FlattenedHeading[]
headings: NestedHeading[]
[key: string]: unknown
}
export interface ReadingTime {
text: string
minutes: number
time: number
words: number
}
export interface FlattenedHeading {
level: number
title: string
id: string
}
export interface NestedHeading {
level: number
title: string
id: string
children: NestedHeading[]
}

View file

@ -3,6 +3,6 @@ import { pages } from './posts'
export async function load({ params }) {
return {
pages
pages: pages.filter((page) => page.listed !== "false")
}
}

View file

@ -4,12 +4,11 @@
import SvelteSeo from "svelte-seo";
import type { WithContext, Thing } from "schema-dts";
interface Props {
data: any;
}
import type { BlogPage } from "./posts";
let { data }: Props = $props();
const { data }: { data: { pages: BlogPage[] } } = $props();
const { pages } = data;
console.log(data)
const jsonLd = {
"@context": "https://schema.org",
@ -23,15 +22,15 @@
"@type": "ListItem",
position: 1,
name: "Blog",
item: SITE_URL + "/blog",
item: `${SITE_URL}/blog`,
},
],
},
mainEntity: {
"@type": "Blog",
"@id": SITE_URL + "/blog",
"@id": `${SITE_URL}/blog`,
name: "Jade's Blog",
mainEntityOfPage: SITE_URL + "/blog",
mainEntityOfPage: `${SITE_URL}/blog`,
},
} as WithContext<Thing>;
</script>

View file

@ -1,4 +1,4 @@
import { pages } from '../posts'
import { pages, type BlogPage } from '../posts'
import type Feed from '@json-feed-types/1_1'
import {
@ -23,9 +23,9 @@ export async function GET({ params, url}) {
.filter((post) => {
const date = new Date(post.date)
return (
(!dateParts[0] || date.getFullYear() == dateParts[0]) &&
(!dateParts[1] || date.getMonth()+1 == dateParts[1]) &&
(!dateParts[2] || date.getDate() == dateParts[2])
(!dateParts[0] || date.getFullYear() === dateParts[0]) &&
(!dateParts[1] || date.getMonth()+1 === dateParts[1]) &&
(!dateParts[2] || date.getDate() === dateParts[2])
)
}) : pages;
const headers = {
@ -37,7 +37,7 @@ export async function GET({ params, url}) {
const AUTHOR = "Jade Ellis"
// prettier-ignore
async function getJsonFeed(selfUrl: string, pages: any[]): Promise<string> {
async function getJsonFeed(selfUrl: string, pages: BlogPage[]): Promise<string> {
const feed: Feed = {
version: 'https://jsonfeed.org/version/1.1',
@ -51,14 +51,16 @@ async function getJsonFeed(selfUrl: string, pages: any[]): Promise<string> {
],
}
for await (const post of pages) {
const shownPages = pages.filter((page) => page.listed !== "false")
for await (const post of shownPages) {
const title = post.title;
const pubDate = post.date
const postUrl = SITE_URL + "/blog/" + post.canonical
const postUrl = `${SITE_URL}/blog/${post.canonical}`
// const postHtml =
const summary = post.description;
const item: typeof feed.items[number] = {
id: post.postUrl,
id: postUrl,
title,
url: postUrl,
date_published: pubDate,

View file

@ -2,11 +2,12 @@ import { browser } from '$app/environment'
// import { format } from 'date-fns'
import slugify from 'slugify';
import { parse, format, relative } from "node:path";
import { parse, type ParsedPath } from "node:path";
import type { MdsvexPage } from '$lib/pageTypes';
// we require some server-side APIs to parse all metadata
if (browser) {
throw new Error(`posts can only be imported server-side`)
throw new Error("posts can only be imported server-side")
}
// import { browser } from '$app/environment'
// import { format } from 'date-fns'
@ -66,7 +67,17 @@ if (browser) {
// }))
const dateRegex = /^((?<year>\d{4})-(?<month>[0][1-9]|1[0-2])-(?<day>[0][1-9]|[1-2]\d|3[01]))\s*/
export const pages = (await Promise.all(Object.entries(import.meta.glob('$notes/Blogs/*.md', { eager: true}))
export interface BlogPage extends MdsvexPage {
title: string
date: string
canonical: string
slug: string
description: string
filepath: ParsedPath
syndication?: string[]
listed?: string
}
export const pages: BlogPage[] = (await Promise.all(Object.entries(import.meta.glob('$notes/Blogs/*.md', { eager: true }))
.map(async ([filepath, post]) => {
const path = parse(filepath);
const title = path.name.replace(dateRegex, "")
@ -79,14 +90,15 @@ export const pages = (await Promise.all(Object.entries(import.meta.glob('$notes/
const datePath = date.replaceAll("-", "/")
const slug = slugify(title, { lower: true })
return {
title,
date,
canonical: datePath + "/" + slug,
canonical: `${datePath}/${slug}`,
slug,
// @ts-ignore
...post.metadata,
slug,
filepath: path
}
})))
@ -99,8 +111,6 @@ export const pages = (await Promise.all(Object.entries(import.meta.glob('$notes/
// next: allPosts[index - 1],
// previous: allPosts[index + 1]
// }))
// function addTimezoneOffset(date) {
// const offsetInMilliseconds = new Date().getTimezoneOffset() * 60 * 1000
// return new Date(new Date(date).getTime() + offsetInMilliseconds)

View file

@ -1,4 +1,4 @@
import { pages } from '../posts'
import { pages, type BlogPage } from '../posts'
import {
SITE_DEFAULT_DESCRIPTION,
@ -25,9 +25,9 @@ export async function GET({ url, params }) {
.filter((post) => {
const date = new Date(post.date)
return (
(!dateParts[0] || date.getFullYear() == dateParts[0]) &&
(!dateParts[1] || date.getMonth()+1 == dateParts[1]) &&
(!dateParts[2] || date.getDate() == dateParts[2])
(!dateParts[0] || date.getFullYear() === dateParts[0]) &&
(!dateParts[1] || date.getMonth()+1 === dateParts[1]) &&
(!dateParts[2] || date.getDate() === dateParts[2])
)
}) : pages;
const headers = {
@ -40,7 +40,7 @@ export async function GET({ url, params }) {
const AUTHOR = "Jade Ellis"
// prettier-ignore
async function getRssXml(selfUrl: string, pages: any[]): Promise<string> {
async function getRssXml(selfUrl: string, pages: BlogPage[]): Promise<string> {
// const rssUrl = `${SITE_URL}/rss.xml`;
const root = create({ version: '1.0', encoding: 'utf-8' })
.ins('xml-stylesheet', `type="text/xsl" href="${rssStyle}"`)
@ -58,11 +58,13 @@ async function getRssXml(selfUrl: string, pages: any[]): Promise<string> {
.ele('name').txt(AUTHOR).up()
.up()
.ele('subtitle').txt(SITE_DEFAULT_DESCRIPTION).up()
const shownPages = pages.filter((page) => page.listed !== "false")
for await (const post of pages) {
for await (const post of shownPages) {
const title = post.title;
const pubDate = post.date
const postUrl = SITE_URL + "/blog/" + post.canonical
const postUrl = `${SITE_URL}/blog/${post.canonical}`
// const postHtml =
const summary = post.description;

View file

@ -28,7 +28,7 @@ export const GET: RequestHandler = async ({ params }) => {
page: params.page,
paramValues: {
'/projects/[slug]': projects,
'/blog/[...date]/[slug]': blogPosts.map((post) => post.canonical)
'/blog/[...date]/[slug]': blogPosts.filter((page) => page.listed !== "false").map((post) => post.canonical)
}
});
};