feat: Blog catalog and tags #7

Merged
aniva merged 11 commits from post/page into main 2024-10-10 14:49:18 -07:00
8 changed files with 97 additions and 32 deletions
Showing only changes of commit 16d767cf76 - Show all commits

26
src/lib/posts.ts Normal file
View File

@ -0,0 +1,26 @@
export async function getPosts() {
const allPostFiles = import.meta.glob('$content/post/*.md');
const iterablePostFiles = Object.entries(allPostFiles);
const allPosts = await Promise.all(
iterablePostFiles.map(async ([pathMarkdown, resolver]) => {
const { metadata } = await resolver();
const pathPost = pathMarkdown.slice(pathMarkdown.lastIndexOf("/") + 1, -".md".length);
return {
meta: {
...metadata,
date: new Date(metadata.date),
},
path: pathPost
};
})
);
allPosts.sort((post1, post2) => {
const date1: Date = post1.meta.date;
const date2: Date = post2.meta.date;
return date2.getTime() - date1.getTime();
});
return allPosts;
}

View File

@ -31,12 +31,12 @@
{/if} {/if}
<style> <style>
:global(.navbar-link) { :global(.nav-link) {
@apply text-lg; @apply text-lg;
font-weight: 500; font-weight: 500;
font-family: serif; font-family: serif;
} }
:global(p.navbar-link) { :global(p.nav-link) {
color: rgb(128,128,128); color: rgb(128,128,128);
} }
:global(a) { :global(a) {

View File

@ -10,10 +10,10 @@
<div id="navbar" class="h-5 space-x-4"> <div id="navbar" class="h-5 space-x-4">
{#each routes as item} {#each routes as item}
{#if item.inactive ?? false} {#if item.inactive ?? false}
<p class="navbar-link" <p class="nav-link"
>{item.name}</p> >{item.name}</p>
{:else} {:else}
<a class="navbar-link" <a class="nav-link"
class:active-link={isActiveLink($page.url.pathname, item.route)} class:active-link={isActiveLink($page.url.pathname, item.route)}
href={item.route}>{item.name}</a> href={item.route}>{item.name}</a>
{/if} {/if}

View File

@ -0,0 +1,40 @@
<script lang="ts">
import type { PageData } from './$types';
export let data: PageData;
const { posts, pageN, maxPageN } = data;
import siteMetadata from '$content/metadata.json';
import { DoubleArrowLeft, DoubleArrowRight, ChevronLeft, ChevronRight, DotsHorizontal } from 'svelte-radix';
import PostHeader from '$lib/components/PostHeader.svelte';
</script>
<svelte:head>
<title>Page {pageN } | {siteMetadata.blogName}</title>
</svelte:head>
<hr class="separator" />
<ul id="catalog" class="content">
{#each posts as post}
<li>
<PostHeader metadata={post.meta} link={post.path} />
</li>
{/each}
</ul>
<hr class="separator" />
<div id="pagenum">
<a class="nav-link icon" href="/page/1"><DoubleArrowLeft /></a>
<a class="nav-link icon" href="/page/{pageN-1}"><ChevronLeft /></a>
<p class="nav-link icon"><DotsHorizontal/></p>
<a class="nav-link icon" href="/page/{pageN+1}"><ChevronRight /></a>
<a class="nav-link icon" href="/page/{maxPageN}"><DoubleArrowRight /></a>
</div>
<style>
#pagenum {
display: flex;
flex-direction: horizontal;
justify-content: space-between;
margin-left: 6em;
margin-right: 6em;
}
</style>

View File

@ -0,0 +1,22 @@
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
import { getPosts } from '$lib/posts';
import siteMetadata from '$content/metadata.json';
export const load: PageLoad = async ({ params }) => {
const pageN: number = +params.slug;
if (!pageN) throw error(404);
const posts = await getPosts();
const pageSize = siteMetadata?.pageSize || 3;
const maxPageN = Math.ceil(posts.length / pageSize);
if (pageN < 0 || pageN > maxPageN) throw error(404);
return {
pageN,
posts: posts.slice((pageN - 1) * pageSize, pageN * pageSize),
maxPageN,
};
}

View File

@ -1,30 +1,7 @@
import type { PageLoad } from './$types'; import type { PageLoad } from './$types';
import { getPosts } from '$lib/posts';
export const load: PageLoad = async (_) => { export const load: PageLoad = async (_) => {
const allPostFiles = import.meta.glob('$content/post/*.md'); const allPosts = await getPosts();
const iterablePostFiles = Object.entries(allPostFiles); return { allPosts };
const allPosts = await Promise.all(
iterablePostFiles.map(async ([pathMarkdown, resolver]) => {
const { metadata } = await resolver();
const pathPost = pathMarkdown.slice(pathMarkdown.lastIndexOf("/") + 1, -".md".length);
return {
meta: {
...metadata,
date: new Date(metadata.date),
},
path: pathPost
};
})
);
allPosts.sort((post1, post2) => {
const date1: Date = post1.meta.date;
const date2: Date = post2.meta.date;
return date2.getTime() - date1.getTime();
});
return {
allPosts
};
}; };

View File

@ -3,7 +3,7 @@
export let data: PageData; export let data: PageData;
const { allPosts } = data; const { allPosts } = data;
import siteMetadata from '$content/metadata.json'; import siteMetadata from '$content/metadata.json';
import Heading from './Heading.svelte'; import PostHeader from '$lib/components/PostHeader.svelte';
</script> </script>
<svelte:head> <svelte:head>
@ -14,7 +14,7 @@
<ul id="catalog" class="content"> <ul id="catalog" class="content">
{#each allPosts as post} {#each allPosts as post}
<li> <li>
<Heading metadata={post.meta} link={post.path} /> <PostHeader metadata={post.meta} link={post.path} />
</li> </li>
{/each} {/each}
</ul> </ul>