From 56e6efc795777f5c74768886553091fb6c2efabe Mon Sep 17 00:00:00 2001 From: Leni Aniva <v@leni.sh> Date: Sat, 25 Jan 2025 15:06:09 -0800 Subject: [PATCH] feat: Implement series --- src/lib/posts.ts | 2 +- src/routes/post/[slug]/+page.svelte | 39 ++++++++++++++++++++++++++- src/routes/post/[slug]/+page.ts | 42 +++++++++++++++++++++++++++-- 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/lib/posts.ts b/src/lib/posts.ts index 9984e6d..ecfc429 100644 --- a/src/lib/posts.ts +++ b/src/lib/posts.ts @@ -15,7 +15,7 @@ export function transformPostMeta(metadata: PostMetadata, slug: string) : Post { }; } -// Generates a list of all posts filtering by tags and series +// Generates a list of all posts filtering by tags and series, reverse chronologically ordered. export async function getPosts(filter: { tag?: string, series?: string }) : Promise<Post[]> { const allPostFiles = import.meta.glob('$content/post/*.md'); const iterablePostFiles = Object.entries(allPostFiles); diff --git a/src/routes/post/[slug]/+page.svelte b/src/routes/post/[slug]/+page.svelte index 22fcab7..f7609be 100644 --- a/src/routes/post/[slug]/+page.svelte +++ b/src/routes/post/[slug]/+page.svelte @@ -1,7 +1,8 @@ <script lang="ts"> + import { TrackPrevious, TrackNext } from 'svelte-radix'; import type { PageData } from './$types'; export let data: PageData; - const { post, Content } = data; + const { post, Content, seriesNeighbours } = data; import siteMetadata from '$content/metadata.json'; import PostHeader from '$lib/components/PostHeader.svelte'; </script> @@ -17,3 +18,39 @@ <Content /> </article> <hr /> +<ul id="series"> + {#each seriesNeighbours as { name, prevSlug, prevTitle, nextSlug, nextTitle }} + <li class="series-neighbour"> + {#if prevTitle} + <a href="/post/{prevSlug}">{prevTitle}</a> + <p class="dummy"><TrackPrevious /></p> + {/if} + <p class="series-tag">{name}</p> + {#if nextTitle} + <p class="dummy"><TrackNext /></p> + <a href="/post/{nextSlug}">{nextTitle}</a> + {/if} + </li> + {/each} +</ul> + +<style> + #series { + text-align: center; + } + .series-tag { + color: var(--series); + display: inline-block; + } + .dummy { + display: inline-block; + color: rgba(128,128,128, .6); + vertical-align: middle; + padding-left: 1em; + padding-right: 1em; + } + .series-neighbour { + padding-left: 2em; + padding-right: 2em; + } +</style> diff --git a/src/routes/post/[slug]/+page.ts b/src/routes/post/[slug]/+page.ts index 974b02e..a974f60 100644 --- a/src/routes/post/[slug]/+page.ts +++ b/src/routes/post/[slug]/+page.ts @@ -1,16 +1,54 @@ import { error } from '@sveltejs/kit'; import type { PageLoad } from './$types'; -import { transformPostMeta } from '$lib/posts'; +import type { Post } from '$lib/types' +import { getPosts, transformPostMeta } from '$lib/posts'; export const load: PageLoad = async ({ params }) => { try { const post = await import(`$content/post/${params.slug}.md`); if (!post) throw error(404); + const metadata: Post = transformPostMeta(post.metadata, params.slug); const Content = post.default; + const seriesNeighbours : { + name: string, + prevSlug?: string, + prevTitle?: string, + nextSlug?: string, + nextTitle?: string, + }[] = await Promise.all(post.metadata.series.map(async (series: string) => { + const postInSeries: Post[] = await getPosts({ series }); + + let prevSlug = null; + let prevTitle = null; + let nextSlug = null; + let nextTitle = null; + + for (const p of postInSeries) { + if (p.date > metadata.date) { + nextSlug = p.slug; + nextTitle = p.title; + } + if (p.date < metadata.date) { + prevSlug = p.slug; + prevTitle = p.title; + break; + } + } + + return { + name: series, + prevSlug, + prevTitle, + nextSlug, + nextTitle, + }; + })); + return { - post: transformPostMeta(post.metadata, params.slug), + post: metadata, Content, + seriesNeighbours, }; } catch {