Added navigation in posts

This commit is contained in:
ClovertaTheTrilobita 2026-04-18 21:38:42 +03:00
parent 7dd21ea510
commit 804bfbd080
3 changed files with 115 additions and 2 deletions

View file

@ -0,0 +1,109 @@
---
import { getCollection } from "astro:content";
import type { CollectionEntry } from "astro:content";
import type { Lang } from "@/i18n";
interface Props {
post: CollectionEntry<"blog">;
lang: Lang;
}
const { post, lang } = Astro.props;
const allPosts = await getCollection("blog");
// 只保留当前语言
const sameLangPosts = allPosts.filter((p) => {
const [postLang] = p.id.split("/");
return postLang === lang;
});
// 按日期倒序:越新越靠前
const sortedPosts = [...sameLangPosts].sort(
(a, b) =>
new Date(b.data.pubDate).getTime() - new Date(a.data.pubDate).getTime(),
);
// 找当前文章位置
const currentIndex = sortedPosts.findIndex((p) => p.id === post.id);
// 更旧的一篇
const prevPost =
currentIndex < sortedPosts.length - 1
? sortedPosts[currentIndex + 1]
: null;
// 更新的一篇
const nextPost = currentIndex > 0 ? sortedPosts[currentIndex - 1] : null;
const getSlugFromId = (id: string) => id.split("/").slice(1).join("/");
const prevSlug = prevPost ? getSlugFromId(prevPost.id) : null;
const nextSlug = nextPost ? getSlugFromId(nextPost.id) : null;
---
<nav class="post-nav" aria-label="Post navigation">
<div class="post-nav-item post-nav-next">
{
nextPost && nextSlug && (
<a href={`/${lang}/posts/${nextSlug}/`}>
<span class="post-nav-label">
{lang === "zh" ? "上一篇" : "Previous"}
</span>
<span class="post-nav-title">{nextPost.data.title}</span>
</a>
)
}
</div>
<div class="post-nav-item post-nav-prev">
{
prevPost && prevSlug && (
<a href={`/${lang}/posts/${prevSlug}/`}>
<span class="post-nav-label">
{lang === "zh" ? "下一篇" : "Next"}
</span>
<span class="post-nav-title">{prevPost.data.title}</span>
</a>
)
}
</div>
</nav>
<style>
.post-nav {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-top: 3rem;
padding-top: 1.5rem;
border-top: 1px dashed rgba(128, 128, 128, 0.5);
}
.post-nav-item {
min-width: 0;
}
.post-nav-prev {
text-align: right;
}
.post-nav a {
display: block;
text-decoration: none;
color: inherit;
}
.post-nav-label {
display: block;
font-size: 0.9rem;
opacity: 0.65;
margin-bottom: 0.35rem;
}
.post-nav-title {
display: block;
font-size: 1rem;
line-height: 1.5;
}
</style>

View file

@ -1,11 +1,12 @@
--- ---
import BaseLayout from "./BaseLayout.astro"; import BaseLayout from "./BaseLayout.astro";
import Remark42Embed from "@/components/Remark42Embed.astro"; import Remark42Embed from "@/components/Remark42Embed.astro";
import PostNav from "@/components/Posts/PostNav.astro";
import { fade } from "astro:transitions"; import { fade } from "astro:transitions";
import { getLangFromUrl, getTranslations } from "@/i18n"; import { getTranslations } from "@/i18n";
import "@/styles/global.css"; import "@/styles/global.css";
const { frontmatter, lang, slug, postId } = Astro.props; const { post, frontmatter, lang, slug, postId } = Astro.props;
const comments = lang === "zh" ? "评论区" : "comments"; const comments = lang === "zh" ? "评论区" : "comments";
const t = getTranslations(lang); const t = getTranslations(lang);
--- ---
@ -76,6 +77,8 @@ const t = getTranslations(lang);
<slot /> <slot />
</div> </div>
<PostNav post={post} lang={lang} />
<h2>{comments}</h2> <h2>{comments}</h2>
<Remark42Embed slug={slug} /> <Remark42Embed slug={slug} />
</article> </article>

View file

@ -29,6 +29,7 @@ const slug = slugParts.join("/");
--- ---
<MarkdownPostLayout <MarkdownPostLayout
post={post}
frontmatter={post.data} frontmatter={post.data}
lang={lang} lang={lang}
slug={slug} slug={slug}