mirror of
https://github.com/ChenQihan666/MyBlog-Next.git
synced 2026-08-14 11:29:33 +08:00
feat: add archives page with configurable menu (#386)
* feat: add archives page with configurable menu * optimize: compat mobile layout * fix: update archive menu layout * fix: hide archives page from URL if showArchives is false * docs: add `showArchives` option in docs Resolves #361 --------- Co-authored-by: satnaing <satnaingdev@gmail.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import Hr from "./Hr.astro";
|
|||||||
import LinkButton from "./LinkButton.astro";
|
import LinkButton from "./LinkButton.astro";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
activeNav?: "posts" | "tags" | "about" | "search";
|
activeNav?: "posts" | "archives" | "tags" | "about" | "search";
|
||||||
}
|
}
|
||||||
|
|
||||||
const { activeNav } = Astro.props;
|
const { activeNav } = Astro.props;
|
||||||
@@ -70,6 +70,41 @@ const { activeNav } = Astro.props;
|
|||||||
About
|
About
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{
|
||||||
|
SITE.showArchives && (
|
||||||
|
<li>
|
||||||
|
<LinkButton
|
||||||
|
href="/archives/"
|
||||||
|
className={`focus-outline flex justify-center p-3 sm:p-1`}
|
||||||
|
ariaLabel="archives"
|
||||||
|
title="Archives"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class:list={[
|
||||||
|
"icon icon-tabler icons-tabler-outline !hidden sm:!inline-block",
|
||||||
|
activeNav === "archives" && "!stroke-skin-accent",
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M3 4m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" />
|
||||||
|
<path d="M5 8v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10" />
|
||||||
|
<path d="M10 12l4 0" />
|
||||||
|
</>
|
||||||
|
</svg>
|
||||||
|
<span
|
||||||
|
class:list={[
|
||||||
|
"sm:sr-only",
|
||||||
|
activeNav === "archives" && "active",
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
Archives
|
||||||
|
</span>
|
||||||
|
</LinkButton>
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
}
|
||||||
<li>
|
<li>
|
||||||
<LinkButton
|
<LinkButton
|
||||||
href="/search/"
|
href="/search/"
|
||||||
@@ -155,7 +190,7 @@ const { activeNav } = Astro.props;
|
|||||||
nav ul li:nth-last-child(2) {
|
nav ul li:nth-last-child(2) {
|
||||||
@apply col-span-1;
|
@apply col-span-1;
|
||||||
}
|
}
|
||||||
nav a.active {
|
nav .active {
|
||||||
@apply underline decoration-wavy decoration-2 underline-offset-4;
|
@apply underline decoration-wavy decoration-2 underline-offset-4;
|
||||||
}
|
}
|
||||||
nav a.active svg {
|
nav a.active svg {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export const SITE: Site = {
|
|||||||
postPerIndex: 4,
|
postPerIndex: 4,
|
||||||
postPerPage: 3,
|
postPerPage: 3,
|
||||||
scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
|
scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
|
||||||
|
showArchives: true,
|
||||||
editPost: {
|
editPost: {
|
||||||
url: "https://github.com/satnaing/astro-paper/edit/main/src/content/blog",
|
url: "https://github.com/satnaing/astro-paper/edit/main/src/content/blog",
|
||||||
text: "Suggest Changes",
|
text: "Suggest Changes",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
author: Sat Naing
|
author: Sat Naing
|
||||||
pubDatetime: 2022-09-23T04:58:53Z
|
pubDatetime: 2022-09-23T04:58:53Z
|
||||||
modDatetime: 2024-01-15T13:05:56.066Z
|
modDatetime: 2024-10-14T09:27:28.605Z
|
||||||
title: How to configure AstroPaper theme
|
title: How to configure AstroPaper theme
|
||||||
slug: how-to-configure-astropaper-theme
|
slug: how-to-configure-astropaper-theme
|
||||||
featured: true
|
featured: true
|
||||||
@@ -33,6 +33,7 @@ export const SITE = {
|
|||||||
lightAndDarkMode: true,
|
lightAndDarkMode: true,
|
||||||
postPerPage: 3,
|
postPerPage: 3,
|
||||||
scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
|
scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
|
||||||
|
showArchives: true,
|
||||||
editPost: {
|
editPost: {
|
||||||
url: "https://github.com/satnaing/astro-paper/edit/main/src/content/blog",
|
url: "https://github.com/satnaing/astro-paper/edit/main/src/content/blog",
|
||||||
text: "Suggest Changes",
|
text: "Suggest Changes",
|
||||||
@@ -54,6 +55,7 @@ Here are SITE configuration options
|
|||||||
| `postPerIndex` | The number of posts to be displayed at the home page under `Recent` section. |
|
| `postPerIndex` | The number of posts to be displayed at the home page under `Recent` section. |
|
||||||
| `postPerPage` | You can specify how many posts will be displayed in each posts page. (eg: if you set SITE.postPerPage to 3, each page will only show 3 posts per page) |
|
| `postPerPage` | You can specify how many posts will be displayed in each posts page. (eg: if you set SITE.postPerPage to 3, each page will only show 3 posts per page) |
|
||||||
| `scheduledPostMargin` | In Production mode, posts with a future `pubDatetime` will not be visible. However, if a post's `pubDatetime` is within the next 15 minutes, it will be visible. You can set `scheduledPostMargin` if you don't like the default 15 minutes margin. |
|
| `scheduledPostMargin` | In Production mode, posts with a future `pubDatetime` will not be visible. However, if a post's `pubDatetime` is within the next 15 minutes, it will be visible. You can set `scheduledPostMargin` if you don't like the default 15 minutes margin. |
|
||||||
|
| `showArchives` | Determines whether to display the `Archives` menu (positioned between the `About` and `Search` menus) and its corresponding page on the site. This option is set to `true` by default. |
|
||||||
| `editPost` | This option allows users to suggest changes to a blog post by providing an edit link under blog post titles. This feature can be disabled by removing it from the `SITE` config. You can also set `appendFilePath` to `true` to automatically append the file path of the post to the url, directing users to the specific post they wish to edit. |
|
| `editPost` | This option allows users to suggest changes to a blog post by providing an edit link under blog post titles. This feature can be disabled by removing it from the `SITE` config. You can also set `appendFilePath` to `true` to automatically append the file path of the post to the url, directing users to the specific post they wish to edit. |
|
||||||
|
|
||||||
## Configuring locale
|
## Configuring locale
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
import { getCollection } from "astro:content";
|
||||||
|
import Card from "@components/Card";
|
||||||
|
import Footer from "@components/Footer.astro";
|
||||||
|
import Header from "@components/Header.astro";
|
||||||
|
import { SITE } from "@config";
|
||||||
|
import Layout from "@layouts/Layout.astro";
|
||||||
|
import Main from "@layouts/Main.astro";
|
||||||
|
import getPostsByGroupCondition from "@utils/getPostsByGroupCondition";
|
||||||
|
|
||||||
|
// Redirect to 404 page if `showArchives` config is false
|
||||||
|
if (!SITE.showArchives) {
|
||||||
|
return Astro.redirect("/404");
|
||||||
|
}
|
||||||
|
|
||||||
|
const posts = await getCollection("blog", ({ data }) => !data.draft);
|
||||||
|
|
||||||
|
const MonthMap: Record<string, string> = {
|
||||||
|
"1": "January",
|
||||||
|
"2": "February",
|
||||||
|
"3": "March",
|
||||||
|
"4": "April",
|
||||||
|
"5": "May",
|
||||||
|
"6": "June",
|
||||||
|
"7": "July",
|
||||||
|
"8": "August",
|
||||||
|
"9": "September",
|
||||||
|
"10": "October",
|
||||||
|
"11": "November",
|
||||||
|
"12": "December",
|
||||||
|
};
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={`Archives | ${SITE.title}`}>
|
||||||
|
<Header activeNav="archives" />
|
||||||
|
<Main pageTitle="Archives" pageDesc="All the articles I've archived.">
|
||||||
|
{
|
||||||
|
Object.entries(
|
||||||
|
getPostsByGroupCondition(posts, post =>
|
||||||
|
post.data.pubDatetime.getFullYear()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.sort(([yearA], [yearB]) => Number(yearB) - Number(yearA))
|
||||||
|
.map(([year, yearGroup]) => (
|
||||||
|
<div>
|
||||||
|
<span class="text-2xl font-bold">{year}</span>
|
||||||
|
<sup class="text-sm">{yearGroup.length}</sup>
|
||||||
|
{Object.entries(
|
||||||
|
getPostsByGroupCondition(
|
||||||
|
yearGroup,
|
||||||
|
post => post.data.pubDatetime.getMonth() + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.sort(([monthA], [monthB]) => Number(monthB) - Number(monthA))
|
||||||
|
.map(([month, monthGroup]) => (
|
||||||
|
<div class="flex flex-col sm:flex-row">
|
||||||
|
<div class="mt-6 min-w-36 text-lg sm:my-6">
|
||||||
|
<span class="font-bold">{MonthMap[month]}</span>
|
||||||
|
<sup class="text-xs">{monthGroup.length}</sup>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
{monthGroup.map(({ data, slug }) => (
|
||||||
|
<Card href={`/posts/${slug}`} frontmatter={data} />
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</Main>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
@@ -11,6 +11,7 @@ export type Site = {
|
|||||||
postPerIndex: number;
|
postPerIndex: number;
|
||||||
postPerPage: number;
|
postPerPage: number;
|
||||||
scheduledPostMargin: number;
|
scheduledPostMargin: number;
|
||||||
|
showArchives?: boolean;
|
||||||
editPost?: {
|
editPost?: {
|
||||||
url?: URL["href"];
|
url?: URL["href"];
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import type { CollectionEntry } from "astro:content";
|
||||||
|
|
||||||
|
type GroupKey = string | number | symbol;
|
||||||
|
|
||||||
|
interface GroupFunction<T> {
|
||||||
|
(item: T, index?: number): GroupKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPostsByGroupCondition = (
|
||||||
|
posts: CollectionEntry<"blog">[],
|
||||||
|
groupFunction: GroupFunction<CollectionEntry<"blog">>
|
||||||
|
) => {
|
||||||
|
const result: Record<GroupKey, CollectionEntry<"blog">[]> = {};
|
||||||
|
for (let i = 0; i < posts.length; i++) {
|
||||||
|
const item = posts[i];
|
||||||
|
const groupKey = groupFunction(item, i);
|
||||||
|
if (!result[groupKey]) {
|
||||||
|
result[groupKey] = [];
|
||||||
|
}
|
||||||
|
result[groupKey].push(item);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getPostsByGroupCondition;
|
||||||
@@ -54,6 +54,11 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
transparent: "transparent",
|
transparent: "transparent",
|
||||||
},
|
},
|
||||||
|
stroke: {
|
||||||
|
skin: {
|
||||||
|
accent: withOpacity("--color-accent")
|
||||||
|
}
|
||||||
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
mono: ["IBM Plex Mono", "monospace"],
|
mono: ["IBM Plex Mono", "monospace"],
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user