feat: Blog catalog and tags #7
|
@ -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;
|
||||
}
|
|
@ -31,12 +31,12 @@
|
|||
{/if}
|
||||
|
||||
<style>
|
||||
:global(.navbar-link) {
|
||||
:global(.nav-link) {
|
||||
@apply text-lg;
|
||||
font-weight: 500;
|
||||
font-family: serif;
|
||||
}
|
||||
:global(p.navbar-link) {
|
||||
:global(p.nav-link) {
|
||||
color: rgb(128,128,128);
|
||||
}
|
||||
:global(a) {
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
<div id="navbar" class="h-5 space-x-4">
|
||||
{#each routes as item}
|
||||
{#if item.inactive ?? false}
|
||||
<p class="navbar-link"
|
||||
<p class="nav-link"
|
||||
>{item.name}</p>
|
||||
{:else}
|
||||
<a class="navbar-link"
|
||||
<a class="nav-link"
|
||||
class:active-link={isActiveLink($page.url.pathname, item.route)}
|
||||
href={item.route}>{item.name}</a>
|
||||
{/if}
|
||||
|
|
|
@ -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>
|
|
@ -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,
|
||||
};
|
||||
}
|
|
@ -1,30 +1,7 @@
|
|||
import type { PageLoad } from './$types';
|
||||
import { getPosts } from '$lib/posts';
|
||||
|
||||
export const load: PageLoad = async (_) => {
|
||||
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
|
||||
};
|
||||
const allPosts = await getPosts();
|
||||
return { allPosts };
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
export let data: PageData;
|
||||
const { allPosts } = data;
|
||||
import siteMetadata from '$content/metadata.json';
|
||||
import Heading from './Heading.svelte';
|
||||
import PostHeader from '$lib/components/PostHeader.svelte';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
@ -14,7 +14,7 @@
|
|||
<ul id="catalog" class="content">
|
||||
{#each allPosts as post}
|
||||
<li>
|
||||
<Heading metadata={post.meta} link={post.path} />
|
||||
<PostHeader metadata={post.meta} link={post.path} />
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
|
|
Loading…
Reference in New Issue