Inhalte abfragen

Auf dieser Seite

EmDash bietet Abfragefunktionen zum Abrufen von Inhalten in Ihren Astro-Seiten und -Komponenten. Diese Funktionen folgen dem Live Content Collections-Muster von Astro und geben strukturierte Ergebnisse mit Fehlerbehandlung zurück.

Abfragefunktionen

EmDash exportiert zwei primäre Abfragefunktionen:

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

Importieren Sie sie von emdash:

import { getEmDashCollection, getEmDashEntry } from "emdash";

Alle Einträge abrufen

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

---
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>

Nach Locale filtern

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

// Französische Beiträge
const { entries: frenchPosts } = await getEmDashCollection("posts", {
	locale: "fr",
	status: "published",
});

// Die aktuelle Request-Locale verwenden
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 Locale der Anfrage verwendet. Wenn keine Übersetzung für die angeforderte Locale existiert, wird die Fallback-Kette befolgt.

Nach Status filtern

Nur veröffentlichte oder Entwurfs-Inhalte 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",
});

Ergebnisse begrenzen

Begrenzen Sie die Anzahl der zurückgegebenen Einträge:

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

Nach Taxonomie filtern

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

// 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.

Fehlerbehandlung

Prüfen Sie immer auf Fehler, wenn Zuverlässigkeit wichtig ist:

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 });
}

Einen einzelnen Eintrag abrufen

Verwenden Sie getEmDashEntry, um einen Eintrag nach seiner ID oder seinem Slug abzurufen:

---
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>

Rückgabetyp für Einträge

getEmDashEntry gibt ein Ergebnisobjekt zurück:

interface EntryResult<T> {
	entry: ContentEntry<T> | null; // null wenn nicht gefunden
	error?: Error; // Nur bei tatsächlichen Fehlern gesetzt (nicht "nicht gefunden")
	isPreview: boolean; // true wenn Vorschau-/Entwurfs-Inhalte angezeigt werden
}

interface ContentEntry<T> {
	id: string;
	data: T;
	edit: EditProxy; // Annotationen für visuelle Bearbeitung
}

Das data-Objekt innerhalb von entry enthält alle für den Inhaltstyp definierten Felder. Der edit-Proxy bietet Annotationen für die visuelle Bearbeitung (siehe unten).

Vorschaumodus

EmDash verarbeitet die Vorschau automatisch über Middleware. Wenn eine URL ein gültiges _preview-Token enthält, verifiziert die Middleware es und richtet den Anforderungskontext ein. Ihre Abfragefunktionen liefern dann Entwurfsinhalte ohne spezielle Parameter:

---
import { getEmDashEntry } from "emdash";

const { slug } = Astro.params;

// Keine spezielle Vorschau-Behandlung erforderlich — die Middleware erledigt es 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">
    Vorschau wird angezeigt. Dieser Inhalt ist nicht veröffentlicht.
  </div>
)}

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

Visuelle Bearbeitung

Jeder von Abfragefunktionen zurückgegebene Eintrag enthält einen edit-Proxy zum Annotieren Ihrer Templates. Spreaden Sie ihn auf Elemente, um Inline-Bearbeitung für authentifizierte Editoren zu aktivieren:

<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 Toolbar für visuelle Bearbeitung verwendet, um Inline-Bearbeitung zu ermöglichen. In der Produktion erzeugen die Proxy-Spreads keine Ausgabe.

Ergebnisse sortieren

getEmDashCollection garantiert keine Sortierreihenfolge. Sortieren Sie Ergebnisse in Ihrem Template:

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),
);

Gängige Sortiermuster

// Alphabetisch nach Titel
posts.sort((a, b) => a.data.title.localeCompare(b.data.title));

// Nach benutzerdefiniertem Sortierfeld
posts.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));

// Zufällige Reihenfolge
posts.sort(() => Math.random() - 0.5);

TypeScript-Typen

Generieren Sie TypeScript-Typen für Ihre Collections:

npx emdash types

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

import { getEmDashCollection, getEmDashEntry } from "emdash";
import type { Post } from "../.emdash/types";

// Typsichere Collection-Abfrage
const { entries: posts } = await getEmDashCollection<Post>("posts");
// posts ist ContentEntry<Post>[]

// Typsichere Eintrags-Abfrage
const { entry: post } = await getEmDashEntry<Post>("posts", "my-post");
// post ist ContentEntry<Post> | null

Statisches vs. Server-Rendering

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

Statisch (Vorgerendert)

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

---
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);
---

Server-gerendert

Für server-gerenderte Seiten fragen Sie Inhalte direkt ab:

---
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 });
}
---

Leistungsüberlegungen

Caching

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

---
const { entries: posts } = await getEmDashCollection("posts", {
  status: "published",
});

// 5 Minuten cachen
Astro.response.headers.set("Cache-Control", "public, max-age=300");
---

Redundante Abfragen vermeiden

Fragen Sie einmal ab und übergeben Sie Daten an Komponenten:

---
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} />

Nächste Schritte