Astro stellt die Seiten, Layouts, Komponenten und das Server-Rendering für eine EmDash-Site bereit. Diese Anleitung behandelt die Astro-Konzepte, die von den aktuellen EmDash-Templates verwendet werden. Es wird vorausgesetzt, dass Sie bereits mit WordPress-Themes und PHP-Templates vertraut sind.
Für Framework-Funktionen, die nicht spezifisch für EmDash sind, verwenden Sie die Astro-Dokumentation.
Projektstruktur
Eine Astro-Site weist jeder Art von Datei ein explizites Verzeichnis zu. Die aktuellen EmDash-Templates verwenden diese Struktur:
| WordPress | Astro | Zweck |
|---|---|---|
index.php, single.php, page.php | src/pages/ | URL-Routen |
template-parts/ | src/components/ | Wiederverwendbare Markup-Bausteine |
header.php und footer.php | src/layouts/ | Gemeinsame Seitenhüllen |
style.css | src/styles/ | Site-Styles |
| Plugin- und Datenbank-Setup | astro.config.mjs | Integrationen und Server-Adapter |
| Theme-Setup-Daten | seed/seed.json | Sammlungen, Menüs und Beispielinhalte |
Das Blog-Template verwendet Routenverzeichnisse, die seinen öffentlichen URLs entsprechen:
src/
├── components/
│ └── PostCard.astro
├── layouts/
│ └── Base.astro
├── pages/
│ ├── index.astro
│ ├── pages/
│ │ └── [slug].astro
│ └── posts/
│ ├── index.astro
│ └── [slug].astro
└── live.config.ts
Astro-Komponenten
Eine .astro-Komponente kombiniert serverseitiges TypeScript mit einem HTML-Template. Code zwischen den ----Begrenzungen wird auf dem Server ausgeführt. Das Markup unterhalb der zweiten Begrenzung wird zum Antwort-HTML.
Die folgende Komponente deklariert Props in ihrem Frontmatter und rendert sie in ihrem Template:
---
interface Props {
title: string;
excerpt?: string;
href: string;
}
const { title, excerpt, href } = Astro.props;
---
<article>
<h2><a href={href}>{title}</a></h2>
{excerpt && <p>{excerpt}</p>}
</article>
Astro escaped Werte, die mit {value} gerendert werden. Imports, Datenbankabfragen und andere Serverarbeiten gehören ins Frontmatter.
Template-Ausdrücke
Astro-Templates verwenden geschweifte Klammern, wo ein PHP-Template zu <?php ?> wechseln würde. Die häufigsten Muster in EmDash-Templates sind Werte, Bedingungen und Array-Mapping:
| Ziel | Astro-Syntax |
|---|---|
| Einen Wert ausgeben | {post.data.title} |
| Rendern, wenn ein Wert vorhanden ist | {post.data.excerpt && <p>{post.data.excerpt}</p>} |
| Zwischen zwei Ergebnissen wählen | {posts.length === 0 ? <p>Noch keine Beiträge.</p> : <PostList />} |
| Eine Liste rendern | {posts.map((post) => <PostCard title={post.data.title} excerpt={post.data.excerpt} href={"/posts/" + post.id} />)} |
Der Ausdruck kann Variablen verwenden, die im Frontmatter vorbereitet wurden, Werte aus Astro.props oder Daten, die von einer EmDash-Abfrage zurückgegeben werden. Astro escaped String-Werte standardmäßig; verwenden Sie einen Renderer wie <PortableText /> für strukturierten Rich Text, anstatt HTML zu injizieren.
Props und Slots
Props sind vergleichbar mit den $args, die an get_template_part() übergeben werden. Sie machen jede Eingabe explizit und können von TypeScript überprüft werden.
Slots ermöglichen es einem übergeordneten Element, Markup an eine Komponente zu übergeben. Ein Standard-Slot ist nützlich für Seiteninhalt, während benannte Slots zusätzliche Einfügepunkte bieten:
---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<article>
<h2>{title}</h2>
<slot />
<footer><slot name="footer" /></footer>
</article>
Die folgende Seite füllt beide Slots:
---
import Card from "../components/Card.astro";
---
<Card title="Neuester Beitrag">
<p>Der Hauptinhalt der Karte.</p>
<a slot="footer" href="/posts/latest">Beitrag lesen</a>
</Card>
Slots sind lokal zum Komponentenaufruf. Sie verhalten sich nicht wie WordPress-Actions, die Callbacks empfangen können, die an anderer Stelle registriert wurden.
Layouts
Ein Layout besitzt die gemeinsame Dokumentstruktur, die ein WordPress-Theme oft zwischen header.php und footer.php aufteilt. Seiten importieren das Layout und übergeben ihren Inhalt über dessen Slot.
Das folgende Layout stellt eine Dokumenthülle bereit:
---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>{title}</title>
</head>
<body>
<header><a href="/">Meine Website</a></header>
<main><slot /></main>
</body>
</html>
Die folgende Seite liefert den Titel und den Hauptinhalt des Layouts:
---
import Base from "../layouts/Base.astro";
---
<Base title="Startseite">
<h1>Neueste Beiträge</h1>
</Base>
Dateibasiertes Routing
Dateien in src/pages/ definieren Routen. Dateinamen in eckigen Klammern erstellen dynamische Segmente.
| Datei | URL |
|---|---|
src/pages/index.astro | / |
src/pages/posts/index.astro | /posts |
src/pages/posts/[slug].astro | /posts/hello-world |
src/pages/pages/[slug].astro | /pages/about |
Innerhalb von src/pages/posts/[slug].astro enthält Astro.params.slug den Wert aus der URL. Lesen Sie Astro-Routing für Rest-Parameter, Weiterleitungen und andere Routing-Funktionen.
Server-Rendering
Die aktuellen EmDash-Templates verwenden output: "server" in astro.config.mjs. Eine Seite kann daher bei jeder Anfrage die Datenbank abfragen, sodass veröffentlichte Inhalte nicht von einem neuen statischen Build abhängen.
Fügen Sie getStaticPaths() nicht zu einer EmDash-Theme-Route hinzu, es sei denn, die Site behandelt EmDash bewusst als Build-Time-Datenquelle. Die mitgelieferten Themes werden serverseitig gerendert.
Lesen Sie Astro On-Demand-Rendering für das Framework-Level-Verhalten.
EmDash-Inhalte abfragen
EmDash umhüllt Astro-Live-Content-Sammlungen mit getEmDashCollection() und getEmDashEntry(). Sammlungsergebnisse enthalten ein entries-Array. Einzeleintrags-Ergebnisse enthalten entry, das null ist, wenn kein veröffentlichter Eintrag übereinstimmt.
Das folgende Archiv verwendet dieselbe Sortierung und Bezeichner wie das aktuelle Blog-Template:
---
import { getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";
const { entries: posts, error } = await getEmDashCollection("posts", {
orderBy: { published_at: "desc" },
});
if (error) {
return new Response("Beiträge konnten nicht geladen werden", { status: 500 });
}
---
<Base title="Beiträge">
{posts.map((post) => (
<article>
<h2><a href={`/posts/${post.id}`}>{post.data.title}</a></h2>
{post.data.excerpt && <p>{post.data.excerpt}</p>}
</article>
))}
</Base>
post.id ist der von Astro bereitgestellte Routen-Bezeichner und ist normalerweise der Eintrags-Slug. post.data.id ist der Datenbank-Bezeichner. Verwenden Sie data.id, wenn eine API die gespeicherte Inhalts-ID erwartet, wie z. B. Taxonomie- oder Kommentar-Hilfsfunktionen.
Die folgende dynamische Route sucht einen Beitrag anhand des Slugs in der URL und rendert sein Portable-Text-Feld:
---
import { decodeSlug, getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "../../layouts/Base.astro";
const slug = decodeSlug(Astro.params.slug);
if (!slug) return Astro.redirect("/404");
const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) return new Response("Beitrag konnte nicht geladen werden", { status: 500 });
if (!post) return Astro.redirect("/404");
---
<Base title={post.data.title}>
<article>
<h1>{post.data.title}</h1>
<PortableText value={post.data.content} />
</article>
</Base>
Weiter mit Astro
EmDash-Templates verwenden auch Komponenten-Styles und kleine Browser-Skripte, aber das sind gewöhnliche Astro-Funktionen und keine EmDash-Konzepte. Lesen Sie Styles und CSS für scoped und globale Styles, und Skripte und Event-Handling, wenn eine Komponente Browser-seitiges Verhalten benötigt.