Improving post - blog and projects unification of logic

This commit is contained in:
matthieu42morin 2024-04-04 20:16:02 +02:00
parent a15c475051
commit f7d7ac8810
11 changed files with 48 additions and 93 deletions

View File

@ -1,11 +0,0 @@
<script lang="ts">
import PostLayout from './PostLayout.svelte';
import type { BlogPost } from '$lib/types/blog';
export let post: BlogPost;
</script>
<PostLayout {...post} imagesDirectoryName="blog">
<slot />
</PostLayout>

View File

@ -9,6 +9,7 @@
export let title: string; export let title: string;
export let image: string; export let image: string;
export let tags: string[] = []; export let tags: string[] = [];
export let type: 'blog' | 'projects';
</script> </script>
<svelte:head> <svelte:head>
@ -27,15 +28,15 @@
</svelte:head> </svelte:head>
<article class="flex justify-center mt-4 mb-8"> <article class="flex justify-center mt-4 mb-8">
<div class=" w-full lg:w-[50rem] leading-[177.7%]"> <div class=" w-full md:w-[50rem] leading-[177.7%]">
<header> <header>
<img <img
src="/images/{imagesDirectoryName}/{slug}/{image}" src="/images/{imagesDirectoryName}/{slug}/{image}"
alt={`${title}`} alt={`${title}`}
class=" bg-black/50 w-full aspect-[21/9] max-h-[540px] rounded-t-[1.3rem]" class=" bg-black/50 w-full aspect-[21/9] max-h-[540px] rounded-t-lg"
/> />
</header> </header>
<div class="flex-auto flex justify-between items-center py-4 px-2"> <div class="flex-auto flex justify-between items-center py-4 px-2 bg-surface-900">
{#if tags && tags.length > 0} {#if tags && tags.length > 0}
<div class="flex mb-2 items-center gap-2"> <div class="flex mb-2 items-center gap-2">
tags: {#each tags as tag} tags: {#each tags as tag}
@ -52,17 +53,11 @@
</div> </div>
<div class="space-y-4"> <div class="space-y-4">
<h2 class="h2" data-toc-ignore>{title}</h2> <h2 class="h2" data-toc-ignore>{title}</h2>
<div class=" max-w-none text-token"> <div class="max-w-none text-token">
<slot /> <slot />
</div> </div>
</div> </div>
<hr class="opacity-50" />
<footer class="p-4 flex justify-start items-center space-x-4" />
</div> </div>
<hr class="opacity-50" />
<footer class="p-4 flex justify-start items-center space-x-4" />
</article> </article>
<style lang="postcss">
.prose :global(nav.toc) {
@apply hidden;
}
</style>

View File

@ -1,10 +1,10 @@
<script lang="ts"> <script lang="ts">
import ProjectLayout from '$lib/components/blog/PostLayout.svelte'; import ProjectContentLayout from '$lib/components/blog/PostLayout.svelte';
import type { Post } from '$lib/types/post'; import type { Post } from '$lib/types/post';
export let post: Project; export let post: Post;
</script> </script>
<ProjectLayout {...post} imagesDirectoryName="projects"> <ProjectContentLayout {...post} imagesDirectoryName="projects">
<slot /> <slot />
</ProjectLayout> </ProjectLayout>

17
src/lib/types/post.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
import type { MarkdownMetadata } from '$content/types';
export type Tag = 'DevOps' | 'Philosophy' | 'Updates' | '';
export interface Post extends MarkdownMetadata {
type?: 'Blog' | 'projects' | string;
date?: string;
excerpt: string;
image: string;
slug?: string;
href?: string;
tags?: Tag[];
subtitle?: string;
teaserImage: string;
title: string;
isNotAnActualPost?: boolean;
}

View File

@ -1,59 +1,14 @@
<!-- <script lang="ts">
import CategoryFilter from './../../lib/components/blog/CategoryFilter.svelte';
import { formatDate } from '$src/content/utils.js';
import { BlogPost } from '$lib/components/blog';
import * as config from '$lib/config';
export let data;
</script>
<svelte:head>
<title>{config.title}</title>
</svelte:head>
<section>
<ul class="posts">
{#each data.posts as post}
<li class="post">
<a href={post.slug} class="title"></a>
<p class="date">{formatDate(post.date, 'full', 'en')}</p>
<p class="description"></p>
</li>
{/each}
</ul>
<div class="flex w-3/4">
<BlogPost />
<div>Some shit</div>
</div>
</section>
<section class="flex max-w-[600px]">
{#each data.posts as post}
<li class="posts">
<a href={post.slug}>
<BlogPost>
<svelte:fragment slot="header">{post.title}</svelte:fragment>
<p class="date" />
<svelte:fragment slot="footer"
>{formatDate(post.date)}, {post.description}</svelte:fragment
>
</BlogPost>
</a>
</li>
{/each}
</section> -->
<script lang="ts"> <script lang="ts">
import PostPreview from '$lib/components/blog/PostPreview.svelte'; import PostPreview from '$lib/components/blog/PostPreview.svelte';
import CategoryFilter from '$lib/components/blog/CategoryFilter.svelte'; import CategoryFilter from '$lib/components/blog/CategoryFilter.svelte';
import type { PageData } from './$types'; import type { PageData } from './$types';
import type { BlogTag } from '$lib/types/blog'; import type { Tag } from '$lib/types/post';
import { page } from '$app/stores'; import { page } from '$app/stores';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
export let data: PageData; export let data: PageData;
let filter: BlogTag | null = null; let filter: Tag | null = null;
$: posts = data.posts.filter((post) => (filter ? post.tags?.includes(filter) : true)); $: posts = data.posts.filter((post) => (filter ? post.tags?.includes(filter) : true));
@ -61,7 +16,7 @@
const tagParam = $page.url.searchParams.get('tag'); const tagParam = $page.url.searchParams.get('tag');
if (!filter && typeof tagParam == 'string') { if (!filter && typeof tagParam == 'string') {
filter = tagParam as BlogTag; filter = tagParam as Tag;
} }
}); });

View File

@ -1,4 +1,3 @@
// layout.server.ts
import { listPosts } from '$content/blog'; import { listPosts } from '$content/blog';
import { error } from '@sveltejs/kit'; import { error } from '@sveltejs/kit';
@ -10,7 +9,7 @@ function shuffle<T>(array: T[]) {
} }
export async function load({ params }) { export async function load({ params }) {
const posts = listBlogPosts(); const posts = listPosts();
const currentPost = posts.find((post) => post.slug == params.slug); const currentPost = posts.find((post) => post.slug == params.slug);
if (!currentPost) { if (!currentPost) {
@ -23,6 +22,6 @@ export async function load({ params }) {
featuredPosts: posts featuredPosts: posts
.filter((post) => post.slug != params.slug) .filter((post) => post.slug != params.slug)
.filter((p) => p.tags?.some((t) => currentPost.tags?.includes(t))) .filter((p) => p.tags?.some((t) => currentPost.tags?.includes(t)))
.slice(0, 3), .slice(0, 3)
}; };
} }

View File

@ -1,14 +1,14 @@
import { getBlogPost, listBlogPosts } from '$content/blog.js'; import { getPost, listPosts } from '$content/blog';
import type { PageLoad } from './$types'; import type { PageLoad } from './$types';
export const entries = async () => { export const entries = async () => {
const posts = await listBlogPosts(); const posts = await listPosts();
return posts return posts
.filter((post) => post.slug !== undefined) .filter((post) => post.slug !== undefined)
.map((post) => ({ slug: post.slug as string })); .map((post) => ({ slug: post.slug as string }));
}; };
export const load: PageLoad = async ({ params, parent }) => { export const load: PageLoad = async ({ params, parent }) => {
await parent(); await parent();
return await getBlogPost(params.slug); return await getPost(params.slug);
}; };

View File

@ -1,9 +1,9 @@
import { listBlogPosts } from '$content/blog'; import { listPosts } from '$content/blog';
import RSS from 'rss'; import RSS from 'rss';
import type { BlogPost } from '$lib/types/blog'; import type { Post } from '$lib/types/post';
export const GET = async () => { export const GET = async () => {
const posts = listBlogPosts(); const posts = listPosts();
/* /*
The RSS feed is a JavaScript object that contains information about the blog feed. The RSS feed is a JavaScript object that contains information about the blog feed.
@ -29,7 +29,7 @@ export const GET = async () => {
// This creates an RSS feed. It does so by iterating over all posts and // This creates an RSS feed. It does so by iterating over all posts and
// adding each post to the feed. // adding each post to the feed.
posts.forEach((post: BlogPost) => { posts.forEach((post: Post) => {
feed.item({ feed.item({
title: post.title, title: post.title,
description: post.excerpt, description: post.excerpt,

View File

@ -14,7 +14,7 @@
> >
{#each data.projects as post} {#each data.projects as post}
<div class="flex justify-center min-w-[20rem] max-w-sm"> <div class="flex justify-center min-w-[20rem] max-w-sm">
<PostPreview {post} type="blog" isMostRecent /> <PostPreview {post} type="projects" />
</div> </div>
{/each} {/each}
</div> </div>

View File

@ -5,6 +5,6 @@
export let data: PageData; export let data: PageData;
</script> </script>
<ProjectsContentLayout projects={data.projects} {...data.post}> <ProjectsContentLayout post={data.post} {...data.post}>
<svelte:component this={data.Component} /> <svelte:component this={data.Component} />
</ProjectsContentLayout> </ProjectsContentLayout>

View File

@ -1,5 +1,5 @@
import { removeTrailingSlash } from '$lib/utils/helpers'; import { removeTrailingSlash } from '$lib/utils/helpers';
import { listBlogPosts } from '$content/blog'; import { listPosts } from '$content/blog';
// prettier-ignore // prettier-ignore
const sitemap = (pages: string[]) => `<?xml version="1.0" encoding="UTF-8" ?> const sitemap = (pages: string[]) => `<?xml version="1.0" encoding="UTF-8" ?>
@ -44,8 +44,8 @@ export const GET = async () => {
.replace('/+page', ''); .replace('/+page', '');
}); });
const blogPosts = listBlogPosts().map((post) => `https://www.mattmor.in/blog/${post.slug}`); const Posts = listPosts().map((post) => `https://www.mattmor.in/blog/${post.slug}`);
const renderedSitemap = sitemap([...staticPages, ...blogPosts]); const renderedSitemap = sitemap([...staticPages, ...Posts]);
return new Response(renderedSitemap, { return new Response(renderedSitemap, {
headers: { headers: {