From d41eff9eccf66644c4c60f53cb516bf079937a28 Mon Sep 17 00:00:00 2001 From: aman333nolawz Date: Mon, 2 Mar 2026 21:49:13 +0530 Subject: Using astro-erudite for static site generation --- src/pages/404.astro | 29 ++++ src/pages/about.astro | 47 +++++++ src/pages/authors/[...id].astro | 58 ++++++++ src/pages/authors/index.astro | 27 ++++ src/pages/blog/[...id].astro | 299 ++++++++++++++++++++++++++++++++++++++++ src/pages/blog/[...page].astro | 58 ++++++++ src/pages/index.astro | 85 ++++++++++++ src/pages/robots.txt.ts | 13 ++ src/pages/rss.xml.ts | 25 ++++ src/pages/tags/[...id].astro | 52 +++++++ src/pages/tags/index.astro | 33 +++++ 11 files changed, 726 insertions(+) create mode 100644 src/pages/404.astro create mode 100644 src/pages/about.astro create mode 100644 src/pages/authors/[...id].astro create mode 100644 src/pages/authors/index.astro create mode 100644 src/pages/blog/[...id].astro create mode 100644 src/pages/blog/[...page].astro create mode 100644 src/pages/index.astro create mode 100644 src/pages/robots.txt.ts create mode 100644 src/pages/rss.xml.ts create mode 100644 src/pages/tags/[...id].astro create mode 100644 src/pages/tags/index.astro (limited to 'src/pages') diff --git a/src/pages/404.astro b/src/pages/404.astro new file mode 100644 index 0000000..5591bc7 --- /dev/null +++ b/src/pages/404.astro @@ -0,0 +1,29 @@ +--- +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import Link from '@/components/Link.astro' +import PageHead from '@/components/PageHead.astro' +import { buttonVariants } from '@/components/ui/button' +import Layout from '@/layouts/Layout.astro' +import { cn } from '@/lib/utils' +--- + + + + + +
+
+

404: Page not found

+

Oops! The page you're looking for doesn't exist.

+
+ + ← Go to home page + +
+
diff --git a/src/pages/about.astro b/src/pages/about.astro new file mode 100644 index 0000000..680c1b2 --- /dev/null +++ b/src/pages/about.astro @@ -0,0 +1,47 @@ +--- +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import Link from '@/components/Link.astro' +import PageHead from '@/components/PageHead.astro' +import ProjectCard from '@/components/ProjectCard.astro' +import Layout from '@/layouts/Layout.astro' +import { getAllProjects } from '@/lib/data-utils' + +const projects = await getAllProjects() +--- + + + + + +
+
+
+

+ astro-erudite is an opinionated, unstyled static blogging template + that prioritizes simplicity and performance, built with Astro, Tailwind, and shadcn/ui. It provides a clean foundation for your content while being + extremely easy to customize. +

+

+ To learn more about the philosophy behind this template, check out the + following blog post: The State of Static Blogs in 2024. +

+
+ +

Example Projects Listing

+
+ {projects.map((project) => )} +
+
+
+
diff --git a/src/pages/authors/[...id].astro b/src/pages/authors/[...id].astro new file mode 100644 index 0000000..d71fcf8 --- /dev/null +++ b/src/pages/authors/[...id].astro @@ -0,0 +1,58 @@ +--- +import AuthorCard from '@/components/AuthorCard.astro' +import BlogCard from '@/components/BlogCard.astro' +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import PageHead from '@/components/PageHead.astro' +import Layout from '@/layouts/Layout.astro' +import { getAllAuthors, getPostsByAuthor } from '@/lib/data-utils' + +export async function getStaticPaths() { + const authors = await getAllAuthors() + return authors.map((author) => ({ + params: { id: author.id }, + props: { author }, + })) +} + +const { author } = Astro.props +const authorPosts = await getPostsByAuthor(author.id) +--- + + + + + +
+ +
+
+

Posts by {author.data.name}

+ { + authorPosts.length > 0 ? ( +
    + {authorPosts + .filter((post) => !post.data.draft) + .map((post) => ( +
  • + +
  • + ))} +
+ ) : ( +

+ No posts available from this author. +

+ ) + } +
+
diff --git a/src/pages/authors/index.astro b/src/pages/authors/index.astro new file mode 100644 index 0000000..ba311a0 --- /dev/null +++ b/src/pages/authors/index.astro @@ -0,0 +1,27 @@ +--- +import AuthorCard from '@/components/AuthorCard.astro' +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import PageHead from '@/components/PageHead.astro' +import Layout from '@/layouts/Layout.astro' +import { getAllAuthors } from '@/lib/data-utils' + +const authors = await getAllAuthors() +--- + + + + + { + authors.length > 0 ? ( +
    + {authors.map((author) => ( +
  • + +
  • + ))} +
+ ) : ( +

No authors found.

+ ) + } +
diff --git a/src/pages/blog/[...id].astro b/src/pages/blog/[...id].astro new file mode 100644 index 0000000..5cc9eab --- /dev/null +++ b/src/pages/blog/[...id].astro @@ -0,0 +1,299 @@ +--- +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import Link from '@/components/Link.astro' +import PostHead from '@/components/PostHead.astro' +import PostNavigation from '@/components/PostNavigation.astro' +import SubpostsHeader from '@/components/SubpostsHeader.astro' +import SubpostsSidebar from '@/components/SubpostsSidebar.astro' +import TOCHeader from '@/components/TOCHeader.astro' +import TOCSidebar from '@/components/TOCSidebar.astro' +import { badgeVariants } from '@/components/ui/badge' +import { Button } from '@/components/ui/button' +import Layout from '@/layouts/Layout.astro' +import { + getAdjacentPosts, + getAllPostsAndSubposts, + getCombinedReadingTime, + getParentId, + getParentPost, + getPostReadingTime, + getSubpostCount, + getTOCSections, + hasSubposts, + isSubpost, + parseAuthors, +} from '@/lib/data-utils' +import { formatDate } from '@/lib/utils' +import { Icon } from 'astro-icon/components' +import { Image } from 'astro:assets' +import { render } from 'astro:content' + +export async function getStaticPaths() { + const posts = await getAllPostsAndSubposts() + return posts.map((post) => ({ + params: { id: post.id }, + props: post, + })) +} + +const post = Astro.props +const currentPostId = Astro.params.id +const { Content, headings } = await render(post) +const authors = await parseAuthors(post.data.authors ?? []) + +const isCurrentSubpost = isSubpost(currentPostId) +const navigation = await getAdjacentPosts(currentPostId) +const parentPost = isCurrentSubpost ? await getParentPost(currentPostId) : null + +const hasChildPosts = await hasSubposts(currentPostId) +const subpostCount = !isCurrentSubpost + ? await getSubpostCount(currentPostId) + : 0 +const postReadingTime = await getPostReadingTime(currentPostId) +const combinedReadingTime = + hasChildPosts && !isCurrentSubpost + ? await getCombinedReadingTime(currentPostId) + : null + +const tocSections = await getTOCSections(currentPostId) +--- + + + + { + (hasChildPosts || isCurrentSubpost) && ( + + ) + } + { + headings?.length > 0 && + !( + isCurrentSubpost && + headings.length === 1 && + headings[0].text === post.data.title + ) && + } + +
+
+ +
+ + { + post.data.image && ( + {post.data.title} + ) + } + +
+
+

+ {post.data.title} +

+ +
+ { + authors.length > 0 && ( +
+ {authors.map((author) => ( +
+ {author.name} + {author.isRegistered ? ( + + {author.name} + + ) : ( + {author.name} + )} +
+ ))} +
+ ) + } + +
+ {formatDate(post.data.date)} +
+ +
+ + {postReadingTime} + { + combinedReadingTime && + combinedReadingTime !== postReadingTime && ( + + {' '} + ({combinedReadingTime} total) + + ) + } + +
+ + { + subpostCount > 0 && ( +
+ + {subpostCount} subpost{subpostCount === 1 ? '' : 's'} +
+ ) + } +
+
+ { + post.data.tags && + post.data.tags.length > 0 && + post.data.tags.map((tag) => ( + + + {tag} + + )) + } +
+
+ + +
+ + { + tocSections.length > 0 && ( + + ) + } + +
+ +
+ + { + (hasChildPosts || isCurrentSubpost) && ( + + ) + } + + +
+ + + + +
+ + \ No newline at end of file diff --git a/src/pages/blog/[...page].astro b/src/pages/blog/[...page].astro new file mode 100644 index 0000000..eb196db --- /dev/null +++ b/src/pages/blog/[...page].astro @@ -0,0 +1,58 @@ +--- +import BlogCard from '@/components/BlogCard.astro' +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import PageHead from '@/components/PageHead.astro' +import PaginationComponent from '@/components/ui/pagination' +import { SITE } from '@/consts' +import Layout from '@/layouts/Layout.astro' +import { getAllPosts, groupPostsByYear } from '@/lib/data-utils' +import type { PaginateFunction } from 'astro' + +export async function getStaticPaths({ + paginate, +}: { + paginate: PaginateFunction +}) { + const allPosts = await getAllPosts() + return paginate(allPosts, { pageSize: SITE.postsPerPage }) +} + +const { page } = Astro.props + +const postsByYear = groupPostsByYear(page.data) +const years = Object.keys(postsByYear).sort((a, b) => parseInt(b) - parseInt(a)) +--- + + + + + +
+ { + years.map((year) => ( +
+
{year}
+
    + {postsByYear[year].map((post) => ( +
  • + +
  • + ))} +
+
+ )) + } +
+ + +
diff --git a/src/pages/index.astro b/src/pages/index.astro new file mode 100644 index 0000000..019283d --- /dev/null +++ b/src/pages/index.astro @@ -0,0 +1,85 @@ +--- +import BlogCard from '@/components/BlogCard.astro' +import Link from '@/components/Link.astro' +import PageHead from '@/components/PageHead.astro' +import { buttonVariants } from '@/components/ui/button' +import { SITE } from '@/consts' +import Layout from '@/layouts/Layout.astro' +import { getRecentPosts } from '@/lib/data-utils' + +const blog = await getRecentPosts(SITE.featuredPostCount) +--- + + + +
+
+

er·u·dite

+

+ /ˈer(y)əˌdīt/ • adjective +

+
+
+

+ astro-erudite is an opinionated, unstyled static blogging template built + with Astro, Tailwind, and shadcn/ui. Extraordinarily loosely based on the Astro Micro theme. +

+

+ To use this template, check out the GitHub repository. To learn more about why this template exists, read this blog + post: The State of Static Blogs in 2024. +

+
+
+
+

Latest posts

+
    + { + blog.map((post) => ( +
  • + +
  • + )) + } +
+
+ + See all posts → + +
+
+
diff --git a/src/pages/robots.txt.ts b/src/pages/robots.txt.ts new file mode 100644 index 0000000..679a44d --- /dev/null +++ b/src/pages/robots.txt.ts @@ -0,0 +1,13 @@ +import type { APIRoute } from 'astro' + +const getRobotsTxt = (sitemapURL: URL) => ` +User-agent: * +Allow: / + +Sitemap: ${sitemapURL.href} +` + +export const GET: APIRoute = ({ site }) => { + const sitemapURL = new URL('sitemap-index.xml', site) + return new Response(getRobotsTxt(sitemapURL)) +} diff --git a/src/pages/rss.xml.ts b/src/pages/rss.xml.ts new file mode 100644 index 0000000..fe7e9d2 --- /dev/null +++ b/src/pages/rss.xml.ts @@ -0,0 +1,25 @@ +import { SITE } from '@/consts' +import rss from '@astrojs/rss' +import type { APIContext } from 'astro' +import { getAllPosts } from '@/lib/data-utils' + +export async function GET(context: APIContext) { + try { + const posts = await getAllPosts() + + return rss({ + title: SITE.title, + description: SITE.description, + site: context.site ?? SITE.href, + items: posts.map((post) => ({ + title: post.data.title, + description: post.data.description, + pubDate: post.data.date, + link: `/blog/${post.id}/`, + })), + }) + } catch (error) { + console.error('Error generating RSS feed:', error) + return new Response('Error generating RSS feed', { status: 500 }) + } +} diff --git a/src/pages/tags/[...id].astro b/src/pages/tags/[...id].astro new file mode 100644 index 0000000..dfd4bb8 --- /dev/null +++ b/src/pages/tags/[...id].astro @@ -0,0 +1,52 @@ +--- +import BlogCard from '@/components/BlogCard.astro' +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import PageHead from '@/components/PageHead.astro' +import Layout from '@/layouts/Layout.astro' +import { getAllTags, getPostsByTag } from '@/lib/data-utils' + +export async function getStaticPaths() { + const tagMap = await getAllTags() + const uniqueTags = Array.from(tagMap.keys()) + + return Promise.all( + uniqueTags.map(async (tag) => { + const posts = await getPostsByTag(tag) + return { + params: { id: tag }, + props: { + tag, + posts, + }, + } + }), + ) +} + +const { tag, posts } = Astro.props +--- + + + + + +
    + { + posts.map((post) => ( +
  • + +
  • + )) + } +
+
diff --git a/src/pages/tags/index.astro b/src/pages/tags/index.astro new file mode 100644 index 0000000..3d2c75f --- /dev/null +++ b/src/pages/tags/index.astro @@ -0,0 +1,33 @@ +--- +import Breadcrumbs from '@/components/Breadcrumbs.astro' +import Link from '@/components/Link.astro' +import PageHead from '@/components/PageHead.astro' +import { badgeVariants } from '@/components/ui/badge' +import Layout from '@/layouts/Layout.astro' +import { getSortedTags } from '@/lib/data-utils' +import { Icon } from 'astro-icon/components' + +const sortedTags = await getSortedTags() +--- + + + + + +
+
+ { + sortedTags.map(({ tag, count }) => ( + + + {tag} + ({count}) + + )) + } +
+
+
-- cgit v1.2.3