Optional: Erstelle eine Content-Collection
Nun, da du einen Blog mit Astros integrierter dateibasierter Routenführung (EN) hast, wirst du ihn so aktualisieren, dass es eine Content-Collection (Inhaltssammlung) (EN) verwendet. Content-Collections sind eine leistungsstarke Möglichkeit, Gruppen ähnlicher Inhalte – etwa Blogbeiträge – zu verwalten.
Mach dich bereit, …
- deinen Ordner mit Blogbeiträgen nach
src/blog/zu verschieben - ein Schema zu erstellen, um das Frontmatter deiner Blogbeiträge zu definieren
getCollection()zu verwenden, um Inhalte und Metadaten der Blogbeiträge abzurufen
Lernen: Astro-Seiten vs. Content-Collections
Abschnitt betitelt „Lernen: Astro-Seiten vs. Content-Collections“Auch wenn du Content-Collections verwendest, nutzt du weiterhin den Ordner src/pages/ für einzelne Seiten, etwa deine „Über mich“-Seite. Wenn du jedoch deine Blogbeiträge aus diesem speziellen Ordner herausnimmst, kannst du leistungsfähigere APIs nutzen, um dein Blog-Index und einzelne Beiträge zu erzeugen und anzuzeigen.
Gleichzeitig erhältst du in deinem Code-Editor bessere Vorschläge und Autovervollständigung, da du ein Schema (EN) hast, das eine gemeinsame Struktur für jeden Beitrag definiert. Astro hilft dir, diese Struktur mithilfe von Zod, einer Schema- und Validierungsbibliothek für TypeScript, durchzusetzen.
In deinem Schema kannst du festlegen, welche Frontmatter-Eigenschaften erforderlich sind – etwa description oder author – und welchen Datentyp jede Eigenschaft haben muss, z. B. string oder array. So fängst du viele Fehler frühzeitig ab, mit klaren Fehlermeldungen, die genau erklären, was schiefgelaufen ist.
Lies mehr über Astros Content-Collections (EN) in unserer Anleitung, oder folge den Schritten unten, um ein einfaches Blog von src/pages/posts/ nach src/blog/ umzuwandeln.
Teste dein Wissen
Abschnitt betitelt „Teste dein Wissen“-
Welche Art von Seite würdest du wahrscheinlich in
src/pages/behalten? -
Welcher Punkt ist kein Vorteil davon, Blogbeiträge in eine Content-Collection zu verschieben?
-
Content-Collections verwenden TypeScript …
Die folgenden Schritte zeigen dir, wie du das Endergebnis des Blog-Tutorials erweiterst, indem du eine Content-Collection für deine Blogbeiträge erstellst.
Abhängigkeiten aktualisieren
Abschnitt betitelt „Abhängigkeiten aktualisieren“Aktualisiere Astro und alle Integrationen auf die neuesten Versionen, indem du im Terminal die folgenden Befehle ausführst:
# Astro und offizielle Integrationen gemeinsam aktualisierennpx @astrojs/upgrade# Astro und offizielle Integrationen gemeinsam aktualisierenpnpm dlx @astrojs/upgrade# Astro und offizielle Integrationen gemeinsam aktualisierenyarn dlx @astrojs/upgradeEin Content-Collection für deine Beiträge erstellen
Abschnitt betitelt „Ein Content-Collection für deine Beiträge erstellen“-
Erstelle eine neue Collection (einen Ordner) namens
src/blog/. -
Verschiebe alle bestehenden Blogbeiträge (
.md-Dateien) vonsrc/pages/posts/in diesen neuen Ordner. -
Erstelle eine Datei
src/content.config.ts, um ein Schema zu definieren (EN) für deinepostsCollection. Für den bestehenden Code aus dem Blog-Tutorial füge Folgendes in die Datei ein, um alle im Frontmatter verwendeten Eigenschaften zu definieren:src/content.config.ts import { glob } from "astro/loaders";import { z, defineCollection } from "astro:content";const blog = defineCollection({loader: glob({ pattern: '**/[^_]*.md', base: "./src/blog" }),schema: z.object({title: z.string(),pubDate: z.date(),description: z.string(),author: z.string(),image: z.object({url: z.string(),alt: z.string()}),tags: z.array(z.string())})});export const collections = { blog }; -
Damit Astro dein Schema erkennt, beende (Strg + C/Control + C) und starte den Entwicklungsserver neu. Dadurch wird das Modul
astro:contentbereitgestellt.
Seiten aus einer Content-Collection erzeugen
Abschnitt betitelt „Seiten aus einer Content-Collection erzeugen“-
Erstelle eine neue Seitendatei
src/pages/posts/[...slug].astro.
Markdown- und MDX-Dateien werden innerhalb einer Sammlung nicht mehr automatisch zu Seiten. Du musst daher eine Seite erstellen, die für die Ausgabe jedes einzelnen Blogbeitrags verantwortlich ist. -
Füge den folgenden Code ein, um deine Sammlung abzufragen (EN) und für jede generierte Seite die
slugund den Seiteninhalt bereitzustellen:src/pages/posts/[...slug].astro ---import { getCollection, render } from 'astro:content';export async function getStaticPaths() {const posts = await getCollection('blog');return posts.map(post => ({params: { slug: post.id }, props: { post },}));}const { post } = Astro.props;const { Content } = await render(post);--- -
Gib
<Content />innerhalb deines Markdown-Layouts aus, um ein gemeinsames Layout für alle Beiträge zu verwenden.src/pages/posts/[...slug].astro ---import { getCollection, render } from 'astro:content';import MarkdownPostLayout from '../../layouts/MarkdownPostLayout.astro';export async function getStaticPaths() {const posts = await getCollection('blog');return posts.map(post => ({params: { slug: post.id }, props: { post },}));}const { post } = Astro.props;const { Content } = await render(post);---<MarkdownPostLayout frontmatter={post.data}><Content /></MarkdownPostLayout> -
Entferne die
layout-Eigenschaft aus dem Frontmatter jedes einzelnen Beitrags.
Dein Inhalt wird nun beim Rendern in ein Layout eingebettet, diese Angabe ist also nicht mehr nötig.
import.meta.glob() durch getCollection() ersetzen
Abschnitt betitelt „import.meta.glob() durch getCollection() ersetzen“-
Überall dort, wo du eine Liste von Blogbeiträgen hast – z. B. auf der Blogseite
src/pages/blog.astro– musst duimport.meta.glob()durchgetCollection()(EN) ersetzen, um Inhalte und Metadaten aus deinen Markdown-Dateien abzurufen. -
Passe anschließend alle Verweise auf die zurückgegebenen Daten an:
Die Frontmatter-Werte befinden sich jetzt unter der Eigenschaftdata. Außerdem hat jedespost-Objekt nun eineslugstatt einer vollständigen URL.
Frontmatter-Werte an dein Schema anpassen
Abschnitt betitelt „Frontmatter-Werte an dein Schema anpassen“Falls nötig, aktualisiere Frontmatter-Werte in deinem Projekt, etwa in Layouts, damit sie deinem Schema entsprechen.
Im Blog-Tutorial war pubDate ursprünglich ein String. Laut Schema ist es jetzt ein Date-Objekt. Dadurch kannst du Methoden wie toLocaleDateString() verwenden, um das Datum zu formatieren:
<!-- ... --><BaseLayout pageTitle={frontmatter.title}> <p>{frontmatter.pubDate.toLocaleDateString()}</p> <p><em>{frontmatter.description}</em></p> <p>Autor/Autorin: {frontmatter.author}</p> <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} /><!-- ... -->RSS-Funktion aktualisieren
Abschnitt betitelt „RSS-Funktion aktualisieren“Das Blog-Tutorial enthält einen RSS-Feed.
Diese Funktion muss ebenfalls getCollection() verwenden, um die Beiträge abzurufen und deren data-Objekt zu nutzen:
import rss from '@astrojs/rss';import { getCollection } from 'astro:content';
export async function GET(context) { const posts = await getCollection("blog"); return rss({ title: 'Astro-Lernender | Blog', description: 'Mein Weg mit Astro', site: context.site, items: posts.map((post) => ({ title: post.data.title, pubDate: post.data.pubDate, description: post.data.description, link: `/posts/${post.id}/`, })), customData: `<language>de-de</language>`, });}Das vollständige Beispiel des Blog-Tutorials mit Content-Collections findest du im Content-Collections-Branch des Tutorial-Repos.