mirror of
https://codeberg.org/JasterV/jaster.xyz.git
synced 2026-04-27 02:15:40 +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"
|
title: "First time posting here"
|
||||||
pubDate: 2024-01-20
|
pubDate: 2024-01-20
|
||||||
image:
|
image: "./assets/me.png"
|
||||||
url: "/images/me.png"
|
|
||||||
alt: "Just me hanging out"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
So this is my first post in here, I'm quite excited :D
|
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 BaseLayout from "./BaseLayout.astro";
|
||||||
import backgroundImage from "@assets/blog-bg.jpg";
|
import backgroundImage from "@assets/blog-bg.jpg";
|
||||||
|
import FormattedDate from "@components/FormattedDate.astro";
|
||||||
|
import { Image } from "astro:assets";
|
||||||
|
|
||||||
interface Props {
|
type Props = CollectionEntry<"blog">["data"];
|
||||||
frontmatter: Frontmatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { frontmatter } = Astro.props;
|
const { title, pubDate, image } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout backgroundImage={backgroundImage}>
|
<BaseLayout backgroundImage={backgroundImage}>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<img
|
<Image src={image} width="90" alt="Header pic" />
|
||||||
src={frontmatter.image?.url}
|
|
||||||
width="90"
|
|
||||||
alt={frontmatter.image?.alt}
|
|
||||||
/>
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="post-title">{frontmatter.title}</h1>
|
<h1 class="post-title">{title}</h1>
|
||||||
<time datetime={frontmatter.pubDate}
|
<div class="date">
|
||||||
>{frontmatter.pubDate.slice(0, 10)}</time
|
<FormattedDate date={pubDate} />
|
||||||
>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main class="post-content">
|
<main class="post-content">
|
||||||
|
|
@ -46,7 +42,7 @@ const { frontmatter } = Astro.props;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
time {
|
.date {
|
||||||
color: var(--text-color-light);
|
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…
Add table
Add a link
Reference in a new issue