Improving post - blog and projects unification of logic
This commit is contained in:
parent
a15c475051
commit
f7d7ac8810
|
@ -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>
|
|
|
@ -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}
|
||||||
|
@ -56,13 +57,7 @@
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<hr class="opacity-50" />
|
<hr class="opacity-50" />
|
||||||
<footer class="p-4 flex justify-start items-center space-x-4" />
|
<footer class="p-4 flex justify-start items-center space-x-4" />
|
||||||
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<style lang="postcss">
|
|
||||||
.prose :global(nav.toc) {
|
|
||||||
@apply hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
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 }));
|
||||||
|
@ -10,5 +10,5 @@ export const entries = async () => {
|
||||||
|
|
||||||
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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
Loading…
Reference in New Issue