Skip to content

Commit

Permalink
feat: add archives page with configurable menu (#386)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
  • Loading branch information
barnett617 and satnaing authored Oct 14, 2024
1 parent 58a0d25 commit 7573617
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 3 deletions.
39 changes: 37 additions & 2 deletions src/components/Header.astro
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Hr from "./Hr.astro";
import LinkButton from "./LinkButton.astro";
export interface Props {
activeNav?: "posts" | "tags" | "about" | "search";
activeNav?: "posts" | "archives" | "tags" | "about" | "search";
}
const { activeNav } = Astro.props;
Expand Down Expand Up @@ -70,6 +70,41 @@ const { activeNav } = Astro.props;
About
</a>
</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>
<LinkButton
href="/search/"
Expand Down Expand Up @@ -155,7 +190,7 @@ const { activeNav } = Astro.props;
nav ul li:nth-last-child(2) {
@apply col-span-1;
}
nav a.active {
nav .active {
@apply underline decoration-wavy decoration-2 underline-offset-4;
}
nav a.active svg {
Expand Down
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const SITE: Site = {
postPerIndex: 4,
postPerPage: 3,
scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
showArchives: true,
editPost: {
url: "https:/satnaing/astro-paper/edit/main/src/content/blog",
text: "Suggest Changes",
Expand Down
4 changes: 3 additions & 1 deletion src/content/blog/how-to-configure-astropaper-theme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
author: Sat Naing
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
slug: how-to-configure-astropaper-theme
featured: true
Expand Down Expand Up @@ -33,6 +33,7 @@ export const SITE = {
lightAndDarkMode: true,
postPerPage: 3,
scheduledPostMargin: 15 * 60 * 1000, // 15 minutes
showArchives: true,
editPost: {
url: "https:/satnaing/astro-paper/edit/main/src/content/blog",
text: "Suggest Changes",
Expand All @@ -54,6 +55,7 @@ Here are SITE configuration options
| `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) |
| `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. |

## Configuring locale
Expand Down
74 changes: 74 additions & 0 deletions src/pages/archives/index.astro
Original file line number Diff line number Diff line change
@@ -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>
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type Site = {
postPerIndex: number;
postPerPage: number;
scheduledPostMargin: number;
showArchives?: boolean;
editPost?: {
url?: URL["href"];
text?: string;
Expand Down
25 changes: 25 additions & 0 deletions src/utils/getPostsByGroupCondition.ts
Original file line number Diff line number Diff line change
@@ -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;
5 changes: 5 additions & 0 deletions tailwind.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ module.exports = {
},
transparent: "transparent",
},
stroke: {
skin: {
accent: withOpacity("--color-accent")
}
},
fontFamily: {
mono: ["IBM Plex Mono", "monospace"],
},
Expand Down

0 comments on commit 7573617

Please sign in to comment.