feat: Tag system
This commit is contained in:
parent
636a00f826
commit
22787eceda
|
@ -33,7 +33,7 @@ npm run dev [-- --open]
|
||||||
### Formatting
|
### Formatting
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
npx run eslint
|
npx eslint
|
||||||
```
|
```
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<DividerVertical />
|
<DividerVertical />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<a href="/">{tag}</a>
|
<a href="/tag/{tag}">{tag}</a>
|
||||||
{/each}
|
{/each}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-l text-gray-500">{date}</p>
|
<p class="text-l text-gray-500">{date}</p>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
export async function getPosts() {
|
export async function getPosts(tag: string | null = null) {
|
||||||
const allPostFiles = import.meta.glob('$content/post/*.md');
|
const allPostFiles = import.meta.glob('$content/post/*.md');
|
||||||
const iterablePostFiles = Object.entries(allPostFiles);
|
const iterablePostFiles = Object.entries(allPostFiles);
|
||||||
|
|
||||||
const allPosts = await Promise.all(
|
let posts = await Promise.all(
|
||||||
iterablePostFiles.map(async ([pathMarkdown, resolver]) => {
|
iterablePostFiles.map(async ([pathMarkdown, resolver]) => {
|
||||||
const { metadata } = await resolver();
|
const { metadata } = await resolver();
|
||||||
const pathPost = "/post/" + pathMarkdown.slice(pathMarkdown.lastIndexOf("/") + 1, -".md".length);
|
const pathPost = "/post/" + pathMarkdown.slice(pathMarkdown.lastIndexOf("/") + 1, -".md".length);
|
||||||
|
@ -16,11 +16,26 @@ export async function getPosts() {
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
if (tag)
|
||||||
|
posts = posts.filter(obj => obj.meta.tags.includes(tag))
|
||||||
|
|
||||||
allPosts.sort((post1, post2) => {
|
posts.sort((post1, post2) => {
|
||||||
const date1: Date = post1.meta.date;
|
const date1: Date = post1.meta.date;
|
||||||
const date2: Date = post2.meta.date;
|
const date2: Date = post2.meta.date;
|
||||||
return date2.getTime() - date1.getTime();
|
return date2.getTime() - date1.getTime();
|
||||||
});
|
});
|
||||||
return allPosts;
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getTags() {
|
||||||
|
const allPostFiles = import.meta.glob('$content/post/*.md');
|
||||||
|
const iterablePostFiles = Object.entries(allPostFiles);
|
||||||
|
|
||||||
|
const allPosts: string[][] = await Promise.all(
|
||||||
|
iterablePostFiles.map(async ([_, resolver]) => {
|
||||||
|
const { metadata } = await resolver();
|
||||||
|
return metadata.tags;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return new Set(allPosts.flat());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export const routes: { route: string, name: string, disabled?: boolean }[] = [
|
export const routes: { route: string, name: string, disabled?: boolean }[] = [
|
||||||
{ route: "/", name: "Home" },
|
{ route: "/", name: "Home" },
|
||||||
{ route: "/post", name: "Blog" },
|
{ route: "/post", name: "Blog" },
|
||||||
{ route: "/tag", name: "Tags", disabled: true },
|
{ route: "/tag", name: "Tags" },
|
||||||
{ route: "/gallery", name: "Gallery", disabled: true },
|
{ route: "/gallery", name: "Gallery", disabled: true },
|
||||||
{ route: "/archives", name: "Archives" },
|
{ route: "/archives", name: "Archives" },
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import type { PageLoad } from './$types';
|
||||||
|
import { getTags } from '$lib/posts';
|
||||||
|
|
||||||
|
export const load: PageLoad = async (_) => {
|
||||||
|
const allTags = await getTags();
|
||||||
|
return { allTags };
|
||||||
|
};
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { PageData } from './$types';
|
||||||
|
export let data: PageData;
|
||||||
|
const { allTags } = data;
|
||||||
|
import siteMetadata from '$content/metadata.json';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Tags | {siteMetadata.blogName}</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<h1>Tags</h1>
|
||||||
|
|
||||||
|
<hr class="separator" />
|
||||||
|
<ul id="catalog" class="content">
|
||||||
|
{#each allTags as tag}
|
||||||
|
<li>
|
||||||
|
<a href="/tag/{tag}">{tag}</a>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
<hr class="separator" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#catalog li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { PageData } from './$types';
|
||||||
|
export let data: PageData;
|
||||||
|
const { name, posts } = data;
|
||||||
|
import siteMetadata from '$content/metadata.json';
|
||||||
|
import PostHeader from '$lib/components/PostHeader.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{name} | {siteMetadata.blogName}</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<h1>{name}</h1>
|
||||||
|
|
||||||
|
<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" />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#catalog li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type { PageLoad } from './$types';
|
||||||
|
import { getPosts } from '$lib/posts';
|
||||||
|
|
||||||
|
export const load: PageLoad = async ({ params }) => {
|
||||||
|
const posts = await getPosts(params.slug);
|
||||||
|
return {
|
||||||
|
name: params.slug,
|
||||||
|
posts,
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue