Zum Inhalt springen

Inhalte abfragen

EmDash bietet Abfragefunktionen, mit denen Sie Inhalte in Astro-Seiten und Komponenten abrufen können. Sie folgen dem Muster von Astros Live Content Collections und liefern strukturierte Ergebnisse inklusive Fehlerbehandlung.

EmDash exportiert zwei primäre Abfragefunktionen:

FunktionZweckRückgabewert
getEmDashCollectionAlle Einträge eines Inhaltstyps abrufen{ entries, error }
getEmDashEntryEinen einzelnen Eintrag per ID oder Slug abrufen{ entry, error, isPreview }

Importieren Sie sie aus emdash:

import { getEmDashCollection, getEmDashEntry } from "emdash";

Verwenden Sie getEmDashCollection, um alle Einträge eines Inhaltstyps abzurufen:

src/pages/posts.astro
---
import { getEmDashCollection } from "emdash";
const { entries: posts, error } = await getEmDashCollection("posts");
if (error) {
console.error("Fehler beim Laden der Beiträge:", error);
}
---
<ul>
{posts.map((post) => (
<li>{post.data.title}</li>
))}
</ul>

Wenn i18n aktiviert ist, filtern Sie nach Sprache, um Inhalte in einer bestimmten Sprache abzurufen:

// Beiträge auf Französisch
const { entries: frenchPosts } = await getEmDashCollection("posts", {
locale: "fr",
status: "published",
});
// Verwenden Sie die aktuelle Anfragesprache
const { entries: localizedPosts } = await getEmDashCollection("posts", {
locale: Astro.currentLocale,
status: "published",
});

Für einzelne Einträge übergeben Sie locale als drittes Argument:

const { entry: post } = await getEmDashEntry("posts", "my-post", {
locale: Astro.currentLocale,
});

Wenn locale weggelassen wird, wird standardmäßig die aktuelle Sprache der Anfrage verwendet. Wenn keine Übersetzung für die angeforderte Sprache existiert, wird die Fallback-Kette befolgt.

Nur veröffentlichte oder Entwurfsinhalte abrufen:

// Nur veröffentlichte Beiträge
const { entries: published } = await getEmDashCollection("posts", {
status: "published",
});
// Nur Entwürfe
const { entries: drafts } = await getEmDashCollection("posts", {
status: "draft",
});

Beschränken Sie die Anzahl der zurückgegebenen Einträge:

// Die 5 neuesten Beiträge abrufen
const { entries: recentPosts } = await getEmDashCollection("posts", {
status: "published",
limit: 5,
});

Einträge nach Kategorie, Tag oder benutzerdefinierten Taxonomie-Begriffen filtern:

// Beiträge in der Kategorie "news"
const { entries: newsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { category: "news" },
});
// Beiträge mit dem Tag "javascript"
const { entries: jsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { tag: "javascript" },
});
// Beiträge, die einem von mehreren Begriffen entsprechen
const { entries: featuredNews } = await getEmDashCollection("posts", {
status: "published",
where: { category: ["news", "featured"] },
});

Der where-Filter verwendet ODER-Logik, wenn mehrere Werte für eine einzelne Taxonomie angegeben werden.

Überprüfen Sie bei Bedarf an Zuverlässigkeit immer auf Fehler:

const { entries: posts, error } = await getEmDashCollection("posts");
if (error) {
// Protokollieren und elegant behandeln
console.error("Fehler beim Laden der Beiträge:", error);
return new Response("Serverfehler", { status: 500 });
}

Verwenden Sie getEmDashEntry, um einen Eintrag anhand seiner ID oder seines Slugs abzurufen:

src/pages/posts/[slug].astro
---
import { getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
const { slug } = Astro.params;
const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) {
return new Response("Serverfehler", { status: 500 });
}
if (!post) {
return Astro.redirect("/404");
}
---
<article>
<h1>{post.data.title}</h1>
<PortableText value={post.data.content} />
</article>

getEmDashEntry gibt ein Ergebnisobjekt zurück:

interface EntryResult<T> {
entry: ContentEntry<T> | null; // null if not found
error?: Error; // Only set for actual errors (not "not found")
isPreview: boolean; // true if viewing preview/draft content
}
interface ContentEntry<T> {
id: string;
data: T;
edit: EditProxy; // Visual editing annotations
}

Das data-Objekt innerhalb von entry enthält alle für den Inhaltstyp definierten Felder. Der edit-Proxy stellt visuelle Bearbeitungsannotationen bereit (siehe unten).

EmDash behandelt Vorschau automatisch über Middleware. Wenn eine URL einen gültigen _preview-Token enthält, überprüft die Middleware diesen und richtet den Anfragekontext ein. Ihre Abfragefunktionen liefern dann Entwurfsinhalte ohne spezielle Parameter aus:

src/pages/posts/[...slug].astro
---
import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;
// Keine spezielle Vorschaubehandlung erforderlich – Middleware erledigt dies automatisch
const { entry, isPreview, error } = await getEmDashEntry("posts", slug);
if (error) {
return new Response("Serverfehler", { status: 500 });
}
if (!entry) {
return Astro.redirect("/404");
}
---
{isPreview && (
<div class="preview-banner">
Sie sehen eine Vorschau. Dieser Inhalt ist noch nicht veröffentlicht.
</div>
)}
<article>
<h1>{entry.data.title}</h1>
<PortableText value={entry.data.content} />
</article>

Jeder von Abfragefunktionen zurückgegebene Eintrag enthält einen edit-Proxy zum Kommentieren Ihrer Vorlagen. Verteilen Sie ihn auf Elemente, um Inline-Bearbeitung für authentifizierte Editoren zu ermöglichen:

<article {...entry.edit}>
<h1 {...entry.edit.title}>{entry.data.title}</h1>
<div {...entry.edit.content}>
<PortableText value={entry.data.content} />
</div>
</article>

Im Bearbeitungsmodus erzeugt {...entry.edit.title} ein data-emdash-ref-Attribut, das die Symbolleiste für die visuelle Bearbeitung zur Inline-Bearbeitung verwendet. In der Produktion erzeugen die Proxy-Verteilungen keine Ausgabe – keine Laufzeitkosten.

getEmDashCollection garantiert keine Sortierreihenfolge. Sortieren Sie Ergebnisse in Ihrer Vorlage:

const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
// Nach Veröffentlichungsdatum sortieren, neueste zuerst
const sorted = posts.sort(
(a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0),
);
// Alphabetical by title
posts.sort((a, b) => a.data.title.localeCompare(b.data.title));
// Nach benutzerdefiniertem Reihenfolgefeld
posts.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));
// Zufällige Reihenfolge
posts.sort(() => Math.random() - 0.5);

Generieren Sie TypeScript-Typen für Ihre Sammlungen:

Terminal-Fenster
npx emdash types

Dies erstellt .emdash/types.ts mit Schnittstellen für jede Sammlung. Verwenden Sie sie für Typsicherheit:

import { getEmDashCollection, getEmDashEntry } from "emdash";
import type { Post } from "../../.emdash/types";
// Typsichere Sammlungsabfrage
const { entries: posts } = await getEmDashCollection<Post>("posts");
// posts ist ContentEntry<Post>[]
// Typsichere Eintragsabfrage
const { entry: post } = await getEmDashEntry<Post>("posts", "my-post");
// post ist ContentEntry<Post> | null

EmDash-Inhalte funktionieren sowohl mit statischen als auch mit serverseitig gerenderten Seiten.

Verwenden Sie für statische Seiten getStaticPaths, um Routen zur Build-Zeit zu generieren:

src/pages/posts/[slug].astro
---
import { getEmDashCollection, getEmDashEntry } from "emdash";
export async function getStaticPaths() {
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
return posts.map((post) => ({
params: { slug: post.data.slug },
}));
}
const { slug } = Astro.params;
const { entry: post } = await getEmDashEntry("posts", slug);
---

Für serverseitig gerenderte Seiten fragen Sie Inhalte direkt ab:

src/pages/posts/[slug].astro
---
export const prerender = false;
import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;
const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) {
return new Response("Serverfehler", { status: 500 });
}
if (!post) {
return new Response(null, { status: 404 });
}
---

EmDash verwendet Astros Live-Content-Collections, die das Caching automatisch handhaben. Für serverseitig gerenderte Seiten sollten Sie HTTP-Cache-Header hinzufügen:

---
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
// Cache für 5 Minuten
Astro.response.headers.set("Cache-Control", "public, max-age=300");
---

Einmal abfragen und Daten an Komponenten übergeben:

src/pages/index.astro
---
import { getEmDashCollection } from "emdash";
import PostList from "../../components/PostList.astro";
import Sidebar from "../../components/Sidebar.astro";
// Einmal abfragen
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
const featured = posts.filter((p) => p.data.featured);
const recent = posts.slice(0, 5);
---
<PostList posts={featured} />
<Sidebar posts={recent} />