Add types and don't show unlisted posts in HTML, feeds and sitemap. Fix JSON feed URLs.
This commit is contained in:
parent
d6a648b6e7
commit
8dabe60322
7 changed files with 72 additions and 31 deletions
28
packages/website/src/lib/pageTypes.d.ts
vendored
Normal file
28
packages/website/src/lib/pageTypes.d.ts
vendored
Normal 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[]
|
||||
}
|
||||
|
|
@ -3,6 +3,6 @@ import { pages } from './posts'
|
|||
export async function load({ params }) {
|
||||
|
||||
return {
|
||||
pages
|
||||
pages: pages.filter((page) => page.listed !== "false")
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
});
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue