slug eingeführt

This commit is contained in:
ebby 2026-08-29 10:41:02 +02:00
parent 2e16f61b3b
commit d1c87db4f7
13 changed files with 81 additions and 50 deletions

View file

@ -1,9 +1,8 @@
--- ---
import type { Post } from "../types/global";
import PostPreviewSmall from "./PostPreviewSmall.astro"; import PostPreviewSmall from "./PostPreviewSmall.astro";
interface Props { interface Props {
posts: Array<Post>; posts: Array<any>;
} }
const { posts } = Astro.props; const { posts } = Astro.props;
@ -12,7 +11,7 @@ const { posts } = Astro.props;
<div class="post-grid"> <div class="post-grid">
{ {
posts.map((post_file: any) => ( posts.map((post_file: any) => (
<PostPreviewSmall url={post_file.url} post={post_file.frontmatter} /> <PostPreviewSmall post={post_file.data} />
)) ))
} }
</div> </div>

View file

@ -1,15 +1,14 @@
--- ---
import type { Post } from "../types/global";
import { findImageByPath } from "../lib/findImage"; import { findImageByPath } from "../lib/findImage";
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import { formatLocalizedDateString } from "../lib/formatDate"; import { formatLocalizedDateString } from "../lib/formatDate";
import type { PostData } from "../content.config";
interface Props { interface Props {
post: Post; post: PostData;
url: string;
} }
const { post, url } = Astro.props; const { post } = Astro.props;
const img = findImageByPath(post.image.path); const img = findImageByPath(post.image.path);
const localeDate = formatLocalizedDateString(post.date) const localeDate = formatLocalizedDateString(post.date)
@ -17,12 +16,12 @@ const localeDate = formatLocalizedDateString(post.date)
<div class="wide-container"> <div class="wide-container">
<div class="image-col col rounded"> <div class="image-col col rounded">
<a href={url}> <a href={`/blog/${post.slug}`}>
<Image src={img} alt={post.image.alt} layout="constrained" /> <Image src={img} alt={post.image.alt} layout="constrained" />
</a> </a>
</div> </div>
<div class="text-col col"> <div class="text-col col">
<a href={url} class="headline-link"> <a href={`/blog/${post.slug}`} class="headline-link">
<h2 class="headline">{post.title}</h2> <h2 class="headline">{post.title}</h2>
</a> </a>
<h7>{post.subtitle}</h7> <h7>{post.subtitle}</h7>

View file

@ -1,21 +1,19 @@
--- ---
import type { PostData } from "../content.config";
import { findImageByPath } from "../lib/findImage"; import { findImageByPath } from "../lib/findImage";
import { formatLocalizedDateString } from "../lib/formatDate"; import { formatLocalizedDateString } from "../lib/formatDate";
import type { Post } from "../types/global";
interface Props { interface Props {
post: Post; post: PostData;
url: string;
} }
const { post, url } = Astro.props; const { post } = Astro.props;
const img = findImageByPath(post.image.path) const img = findImageByPath(post.image.path)
const localeDate = formatLocalizedDateString(post.date) const localeDate = formatLocalizedDateString(post.date)
--- ---
<a href={url} class="no-link-link"> <a href={`/blog/${post.slug}`} class="no-link-link">
<div class="frame rounded"> <div class="frame rounded">
<img src={img.src} alt={post.image.alt} class="rounded" /> <img src={img.src} alt={post.image.alt} class="rounded" />
<h2 class="headline">{post.title}</h2> <h2 class="headline">{post.title}</h2>

View file

@ -0,0 +1,29 @@
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';
const postSchema = z.object({
title: z.string(),
subtitle: z.string(),
description: z.string(),
image: z.object({
path: z.string(),
alt: z.string()
}),
author: z.string(),
date: z.coerce.date(),
slug: z.string(),
});
export type PostData = z.infer<typeof postSchema>;
const posts = defineCollection({
loader: glob({
pattern: "**/*.md",
base: "./src/pages/blog/",
}),
schema: postSchema
});
export const collections = { posts };

View file

@ -2,12 +2,12 @@
import { Image } from "astro:assets"; import { Image } from "astro:assets";
import BackNav from "../components/BackNav.astro"; import BackNav from "../components/BackNav.astro";
import { findImageByPath } from "../lib/findImage"; import { findImageByPath } from "../lib/findImage";
import type { Post } from "../types/global";
import Main from "./Main.astro"; import Main from "./Main.astro";
import { formatLocalizedDateString } from "../lib/formatDate"; import { formatLocalizedDateString } from "../lib/formatDate";
import type { PostData } from "../content.config";
interface Props { interface Props {
frontmatter: Post; frontmatter: PostData;
} }
const { frontmatter } = Astro.props; const { frontmatter } = Astro.props;

View file

@ -1,3 +1,3 @@
export function formatLocalizedDateString(date: string): string { export function formatLocalizedDateString(date: Date): string {
return new Date(date).toLocaleDateString('de-DE') return date.toLocaleDateString('de-DE')
} }

View file

@ -1,12 +1,14 @@
--- ---
layout: ../../layouts/BlogPostLayout.astro layout: ../../layouts/BlogPostLayout.astro
title: Under Construction title: Under Construction
subtitle: Wir bauen für Sie
description: Bald könnt ihr hier unsere ersten Abenteuer mitverfolgen. Und keine Sorge...an der Webseite wird auch noch gearbeitet! description: Bald könnt ihr hier unsere ersten Abenteuer mitverfolgen. Und keine Sorge...an der Webseite wird auch noch gearbeitet!
image: image:
path: construction.png path: construction.png
alt: Under Construction alt: Under Construction
author: Tim author: Tim
date: '2026-07-10' date: '2026-07-10'
slug: Under-Construction
--- ---
# All Endings Are Beginnings # All Endings Are Beginnings

View file

@ -8,6 +8,7 @@ image:
alt: Chiara und Tim vor einem Strand alt: Chiara und Tim vor einem Strand
author: Tim author: Tim
date: '2026-08-20' date: '2026-08-20'
slug: Ostseeurlaub
--- ---
Eigentlich soll es hier um unser (zukünftiges) Boot und die Segelreisen gehen. Eigentlich soll es hier um unser (zukünftiges) Boot und die Segelreisen gehen.

View file

@ -8,6 +8,7 @@ image:
alt: Chiara und Tim in der nähe der Bergeralm mit tollen Bergen im Hintergrund. alt: Chiara und Tim in der nähe der Bergeralm mit tollen Bergen im Hintergrund.
author: Tim author: Tim
date: '2026-08-29' date: '2026-08-29'
slug: Luxusurlaub-in-Matrei
--- ---
Was könnte ein besser Kontrast zum Zelturlaub an der Ostsee sein, als eine Woche in einem luxuriösen Hotel, mitten in den Alpen?<br /> Was könnte ein besser Kontrast zum Zelturlaub an der Ostsee sein, als eine Woche in einem luxuriösen Hotel, mitten in den Alpen?<br />

View file

@ -0,0 +1,24 @@
---
import { getCollection, render } from "astro:content";
import BlogPostLayout from "../../layouts/BlogPostLayout.astro";
export async function getStaticPaths() {
const posts = await getCollection("posts");
return posts.map((post) => ({
params: {
slug: post.data.slug,
},
props: {
post,
},
}));
}
const { post } = Astro.props;
const { Content } = await render(post);
---
<BlogPostLayout frontmatter={post.data}>
<Content />
</BlogPostLayout>

View file

@ -2,32 +2,21 @@
import Main from "../layouts/Main.astro"; import Main from "../layouts/Main.astro";
import PostPreviewLarge from "../components/PostPreviewLarge.astro"; import PostPreviewLarge from "../components/PostPreviewLarge.astro";
import PostGrid from "../components/PostGrid.astro"; import PostGrid from "../components/PostGrid.astro";
import type { Post } from "../types/global"; import { getCollection } from "astro:content";
import { date, readonly } from "astro:schema";
const allPosts: Array<any> = Object.values( const allPostsSorted = (await getCollection('posts')).sort(
import.meta.glob("./posts/*.md", { eager: true }) (postA, postB) =>
postB.data.date.getTime() - postA.data.date.getTime()
); );
const sortedPosts = allPosts.slice(0, allPosts.length - 1) const [mostRecentPost, ...sortedPosts] = allPostsSorted;
.sort((postA: any, postB: any): number => {
const dateA = new Date(postA.frontmatter.date)
const dateB = new Date(postB.frontmatter.date)
if (dateA > dateB) return -1 console.log(mostRecentPost.data)
else if (dateA < dateB) return 1
return 0
})
const mostRecentPost = allPosts.at(allPosts.length - 1);
--- ---
<Main title="Startseite"> <Main title="Startseite">
<PostPreviewLarge <PostPreviewLarge
url={mostRecentPost.url} post={mostRecentPost.data}
post={mostRecentPost.frontmatter}
/> />
<PostGrid posts={sortedPosts} /> <PostGrid posts={sortedPosts} />
</Main> </Main>

View file

@ -3,7 +3,7 @@ import rss, { pagesGlobToRssItems } from '@astrojs/rss';
export async function GET(context) { export async function GET(context) {
const posts = Object.values( const posts = Object.values(
import.meta.glob("./posts/*.md", { eager: true }) import.meta.glob("./blog/*.md", { eager: true })
); );
return rss({ return rss({
@ -15,7 +15,7 @@ export async function GET(context) {
subtitle: post.frontmatter.subtitle, subtitle: post.frontmatter.subtitle,
pubDate: Date.parse(post.frontmatter.date), pubDate: Date.parse(post.frontmatter.date),
description: post.frontmatter.description, description: post.frontmatter.description,
link: post.url, link: `/blog/${post.frontmatter.slug}`
})), })),
customData: `<language>de-de</language>`, customData: `<language>de-de</language>`,
}); });

View file

@ -1,11 +0,0 @@
export interface Post {
title: String,
subtitle: String,
description: String,
date: string,
author: String,
image: {
path: string,
alt: string
}
}