feat: move all functionality for blog pages to the server
This commit is contained in:
parent
5ca7fc1ced
commit
1fd055c38f
6 changed files with 99 additions and 72 deletions
|
|
@ -1 +1,42 @@
|
|||
import { BlogController } from '$lib/blog/BlogController.js';
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
import { differenceInCalendarDays, getYear } from 'date-fns';
|
||||
|
||||
export const prerender = true;
|
||||
|
||||
export const load: Load = async ({ params, url }) => {
|
||||
const controller = await BlogController.singleton();
|
||||
const tags = url.searchParams.getAll('tag');
|
||||
let posts = [];
|
||||
|
||||
if (tags.length > 0) {
|
||||
posts = await controller.getBlogPostsByTags(tags);
|
||||
} else {
|
||||
posts = await controller.getAllBlogPosts();
|
||||
}
|
||||
|
||||
const currentYear = getYear(new Date());
|
||||
console.log({ posts });
|
||||
const mostRecentPost = posts[0];
|
||||
|
||||
const daysSinceLastPublish = differenceInCalendarDays(new Date(), new Date(mostRecentPost.date));
|
||||
|
||||
const numberOfPosts = posts.length;
|
||||
const firstPost = posts[numberOfPosts - 1];
|
||||
const daysSinceFirstPost = differenceInCalendarDays(new Date(), new Date(firstPost.date));
|
||||
const averageDaysBetweenPosts = Number(daysSinceFirstPost / numberOfPosts).toFixed(2);
|
||||
const numberOfBlogPostsThisYear: number = posts.filter(
|
||||
(post) => getYear(new Date(post.date)) === currentYear
|
||||
).length;
|
||||
|
||||
return {
|
||||
tags,
|
||||
posts,
|
||||
firstPost,
|
||||
averageDaysBetweenPosts,
|
||||
daysSinceFirstPost,
|
||||
daysSinceLastPublish,
|
||||
numberOfPosts,
|
||||
numberOfBlogPostsThisYear,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,7 +71,11 @@
|
|||
</section>
|
||||
|
||||
<section class="section">
|
||||
{#if data.tags.length > 0}
|
||||
<h2>Tags: {data.tags.join(", ")}</h2>
|
||||
{:else}
|
||||
<h2>All Writing</h2>
|
||||
{/if}
|
||||
<ul class="posts">
|
||||
{#each posts as post, index}
|
||||
<BlogPostListItem
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
import type { LoadEvent } from '@sveltejs/kit';
|
||||
import { differenceInCalendarDays, getYear } from 'date-fns';
|
||||
export const prerender = false;
|
||||
|
||||
interface BlogPostListItem {
|
||||
title: string;
|
||||
author: string;
|
||||
book_review: boolean;
|
||||
content: string;
|
||||
date: string;
|
||||
preview: string;
|
||||
slug: string;
|
||||
content_type: 'blog' | 'book_review' | 'snout_street_studios';
|
||||
}
|
||||
|
||||
export async function load({ fetch }: LoadEvent) {
|
||||
const posts: BlogPostListItem[] = await fetch('/api/blog.json')
|
||||
.then((res) => res.json())
|
||||
.then((res) => res.posts);
|
||||
|
||||
const currentYear = getYear(new Date());
|
||||
console.log({ posts });
|
||||
const mostRecentPost = posts[0];
|
||||
console.log({ ...mostRecentPost });
|
||||
|
||||
const daysSinceLastPublish = differenceInCalendarDays(new Date(), new Date(mostRecentPost.date));
|
||||
|
||||
const numberOfPosts = posts.length;
|
||||
const firstPost = posts[numberOfPosts - 1];
|
||||
const daysSinceFirstPost = differenceInCalendarDays(new Date(), new Date(firstPost.date));
|
||||
const averageDaysBetweenPosts = Number(daysSinceFirstPost / numberOfPosts).toFixed(2);
|
||||
const numberOfBlogPostsThisYear: number = posts.filter(
|
||||
(post) => getYear(new Date(post.date)) === currentYear
|
||||
).length;
|
||||
|
||||
return {
|
||||
posts,
|
||||
firstPost,
|
||||
averageDaysBetweenPosts,
|
||||
daysSinceFirstPost,
|
||||
daysSinceLastPublish,
|
||||
numberOfPosts,
|
||||
numberOfBlogPostsThisYear,
|
||||
};
|
||||
}
|
||||
14
src/routes/blog/[slug]/+page.server.ts
Normal file
14
src/routes/blog/[slug]/+page.server.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { error, type Load, type LoadEvent } from '@sveltejs/kit';
|
||||
import { BlogController } from '../../../lib/blog/BlogController.js';
|
||||
|
||||
export const load: Load = async ({ params, fetch }) => {
|
||||
const controller = await BlogController.singleton();
|
||||
const slug = params['slug'] as string;
|
||||
const post = await controller.getBlogPostBySlug(slug);
|
||||
|
||||
if (!post) {
|
||||
return error(404, 'Post not found');
|
||||
}
|
||||
|
||||
return { post, date: new Date(post.date) };
|
||||
};
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import type { PageData } from "./$types.js";
|
||||
import type { PageData, PageServerData } from "./$types.js";
|
||||
import { intlFormat } from "date-fns";
|
||||
import Navbar from "$lib/components/Navbar.svelte";
|
||||
import { onMount } from "svelte";
|
||||
|
|
@ -9,11 +9,7 @@
|
|||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
let { date, post } = $derived(data);
|
||||
|
||||
onMount(() => {
|
||||
console.log({ date, post });
|
||||
});
|
||||
const post = data.post;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
|
@ -41,14 +37,14 @@
|
|||
<header class="blog__header">
|
||||
<h1 class="title post-title">{post.title}</h1>
|
||||
<p class="post-author">
|
||||
{#if post.autor}
|
||||
{#if post.author}
|
||||
{post.author}
|
||||
{:else}
|
||||
Thomas Wilson
|
||||
{/if}
|
||||
</p>
|
||||
<p class="post-date">
|
||||
{intlFormat(date, {
|
||||
{intlFormat(post.date, {
|
||||
weekday: "long",
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
|
|
@ -56,6 +52,16 @@
|
|||
localeMatcher: "best fit",
|
||||
})}
|
||||
</p>
|
||||
{#if post}
|
||||
<div class="post-tags">
|
||||
{#each post.tags as tag}
|
||||
<a
|
||||
href={`/blog?tag=${encodeURIComponent(tag)}`}
|
||||
class="post-tags__tag">#{tag}</a
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</header>
|
||||
|
||||
<article id="article">
|
||||
|
|
@ -64,7 +70,7 @@
|
|||
</article>
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
<style>
|
||||
.blog {
|
||||
background-color: var(--colour-scheme-background);
|
||||
display: flex;
|
||||
|
|
@ -80,6 +86,7 @@
|
|||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.post-title {
|
||||
|
|
@ -87,6 +94,14 @@
|
|||
line-height: 125%;
|
||||
max-width: 30ch;
|
||||
font-family: var(--font-family-serif);
|
||||
font-size: clamp(2rem, 10vw, 4rem);
|
||||
max-width: 95%;
|
||||
}
|
||||
|
||||
@container (min-width: 550px) {
|
||||
.post-title {
|
||||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.post-author {
|
||||
|
|
@ -104,6 +119,21 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.post-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin-top: 8px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.post-tags__tag {
|
||||
border: 2px solid var(--brand-orange);
|
||||
border-radius: 8px;
|
||||
padding: 4px 8px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
:global(#article p) {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
import type { LoadEvent } from '@sveltejs/kit';
|
||||
import type { Post } from '$lib/Post.js';
|
||||
|
||||
export async function load({ params, fetch }: LoadEvent): Promise<{ post: Post; date: Date }> {
|
||||
const { slug } = params;
|
||||
const { post } = await fetch(`/api/blog/${slug}.json`)
|
||||
.then((res) => res.json())
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
return { post: null };
|
||||
});
|
||||
|
||||
return {
|
||||
post,
|
||||
date: new Date(post.date),
|
||||
};
|
||||
}
|
||||
Loading…
Reference in a new issue