mirror of
https://codeberg.org/JasterV/jaster.xyz.git
synced 2026-04-26 18:10:01 +00:00
[feat] Update codebase to optimize images and use content collections
This commit is contained in:
parent
d74b427992
commit
03c99121b4
10 changed files with 135 additions and 104 deletions
17
src/components/FormattedDate.astro
Normal file
17
src/components/FormattedDate.astro
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
interface Props {
|
||||
date: Date;
|
||||
}
|
||||
|
||||
const { date } = Astro.props;
|
||||
---
|
||||
|
||||
<time datetime={date.toISOString()}>
|
||||
{
|
||||
date.toLocaleDateString("en-us", {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
})
|
||||
}
|
||||
</time>
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
---
|
||||
import type { BlogPost } from "../types/BlogPost.ts";
|
||||
|
||||
interface Props {
|
||||
post: BlogPost;
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
---
|
||||
|
||||
<article class="post-card">
|
||||
<time datetime={post.frontmatter.pubDate}>
|
||||
{post.frontmatter.pubDate.slice(0, 10)}
|
||||
</time>
|
||||
<h2>
|
||||
<a href={post.url} rel="bookmark">
|
||||
{post.frontmatter.title}
|
||||
</a>
|
||||
</h2>
|
||||
</article>
|
||||
|
||||
<style>
|
||||
time {
|
||||
color: var(--text-color-light);
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.post-card {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
border: 1px solid var(--text-color);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
15
src/content.config.ts
Normal file
15
src/content.config.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { glob } from "astro/loaders";
|
||||
import { defineCollection, z } from "astro:content";
|
||||
|
||||
const blog = defineCollection({
|
||||
loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
|
||||
// Type-check frontmatter using a schema
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
title: z.string(),
|
||||
pubDate: z.coerce.date(),
|
||||
image: image(),
|
||||
}),
|
||||
});
|
||||
|
||||
export const collections = { blog };
|
||||
|
|
@ -1,10 +1,7 @@
|
|||
---
|
||||
layout: ../../layouts/PostLayout.astro
|
||||
title: "First time posting here"
|
||||
pubDate: 2024-01-20
|
||||
image:
|
||||
url: "/images/me.png"
|
||||
alt: "Just me hanging out"
|
||||
image: "./assets/me.png"
|
||||
---
|
||||
|
||||
So this is my first post in here, I'm quite excited :D
|
||||
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
|
@ -1,28 +1,24 @@
|
|||
---
|
||||
import type { Frontmatter } from "../types/BlogPost.ts";
|
||||
import { type CollectionEntry } from "astro:content";
|
||||
import BaseLayout from "./BaseLayout.astro";
|
||||
import backgroundImage from "@assets/blog-bg.jpg";
|
||||
import FormattedDate from "@components/FormattedDate.astro";
|
||||
import { Image } from "astro:assets";
|
||||
|
||||
interface Props {
|
||||
frontmatter: Frontmatter;
|
||||
}
|
||||
type Props = CollectionEntry<"blog">["data"];
|
||||
|
||||
const { frontmatter } = Astro.props;
|
||||
const { title, pubDate, image } = Astro.props;
|
||||
---
|
||||
|
||||
<BaseLayout backgroundImage={backgroundImage}>
|
||||
<article>
|
||||
<header>
|
||||
<img
|
||||
src={frontmatter.image?.url}
|
||||
width="90"
|
||||
alt={frontmatter.image?.alt}
|
||||
/>
|
||||
<Image src={image} width="90" alt="Header pic" />
|
||||
<div>
|
||||
<h1 class="post-title">{frontmatter.title}</h1>
|
||||
<time datetime={frontmatter.pubDate}
|
||||
>{frontmatter.pubDate.slice(0, 10)}</time
|
||||
>
|
||||
<h1 class="post-title">{title}</h1>
|
||||
<div class="date">
|
||||
<FormattedDate date={pubDate} />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="post-content">
|
||||
|
|
@ -46,7 +42,7 @@ const { frontmatter } = Astro.props;
|
|||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
time {
|
||||
.date {
|
||||
color: var(--text-color-light);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
---
|
||||
import type { BlogPost } from "../types/BlogPost.ts";
|
||||
import PostCard from "@components/PostCard.astro";
|
||||
import Layout from "@layouts/BaseLayout.astro";
|
||||
import backgroundImage from "@assets/blog-bg.jpg";
|
||||
|
||||
const posts = Object.values(
|
||||
import.meta.glob<BlogPost>("../pages/posts/*.md", { eager: true }),
|
||||
);
|
||||
---
|
||||
|
||||
<Layout title="Blog" , backgroundImage={backgroundImage}>
|
||||
<div class="post-cards">
|
||||
{posts.map((post) => <PostCard post={post} />)}
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
.post-cards {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin: 1rem 0rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
25
src/pages/blog/[...slug].astro
Normal file
25
src/pages/blog/[...slug].astro
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import PostLayout from "../../layouts/PostLayout.astro";
|
||||
import { render } from "astro:content";
|
||||
|
||||
type Props = CollectionEntry<"Blog">;
|
||||
type Post = CollectionEntry<"Blog">;
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection("blog");
|
||||
|
||||
return posts.map((post: Post) => ({
|
||||
params: { slug: post.id },
|
||||
props: post,
|
||||
}));
|
||||
}
|
||||
|
||||
const post = Astro.props;
|
||||
|
||||
const { Content } = await render(post);
|
||||
---
|
||||
|
||||
<PostLayout {...post.data}>
|
||||
<Content />
|
||||
</PostLayout>
|
||||
66
src/pages/blog/index.astro
Normal file
66
src/pages/blog/index.astro
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
import Layout from "@layouts/BaseLayout.astro";
|
||||
import backgroundImage from "@assets/blog-bg.jpg";
|
||||
import { type CollectionEntry, getCollection } from "astro:content";
|
||||
import FormattedDate from "@components/FormattedDate.astro";
|
||||
|
||||
type PostEntry = CollectionEntry<"Blog">;
|
||||
|
||||
const posts: PostEntry[] = await getCollection("blog");
|
||||
|
||||
const sortedPosts = posts.sort(
|
||||
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
|
||||
);
|
||||
---
|
||||
|
||||
<Layout title="Blog" , backgroundImage={backgroundImage}>
|
||||
<div class="post-cards">
|
||||
{
|
||||
sortedPosts.map((post) => (
|
||||
<article class="post-card">
|
||||
<div class="date">
|
||||
<FormattedDate date={post.data.pubDate} />
|
||||
</div>
|
||||
<h2>
|
||||
<a href={`/blog/${post.id}`} rel="bookmark">
|
||||
{post.data.title}
|
||||
</a>
|
||||
</h2>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</Layout>
|
||||
|
||||
<style>
|
||||
.post-cards {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
margin: 1rem 0rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.post-card {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
border: 1px solid var(--text-color);
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.date {
|
||||
color: var(--text-color-light);
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import type { MarkdownInstance } from "astro";
|
||||
|
||||
export interface Image {
|
||||
url: string;
|
||||
alt?: string;
|
||||
}
|
||||
|
||||
export interface Frontmatter {
|
||||
title: string;
|
||||
pubDate: string;
|
||||
image?: Image;
|
||||
}
|
||||
|
||||
export type BlogPost = MarkdownInstance<Frontmatter>;
|
||||
Loading…
Reference in a new issue