Astro für WordPress-Entwickler

Auf dieser Seite

Astro stellt die Seiten, Layouts, Komponenten und das Server-Rendering für eine EmDash-Site bereit. Dieser Leitfaden behandelt die Astro-Konzepte, die von den aktuellen EmDash-Templates verwendet werden. Er setzt voraus, dass Sie WordPress-Themes und PHP-Templates bereits verstehen.

Für Framework-Funktionen, die nicht EmDash-spezifisch sind, nutzen Sie die Astro-Dokumentation.

Projektstruktur

Eine Astro-Site weist jeder Dateiart ein eigenes Verzeichnis zu. Die aktuellen EmDash-Templates verwenden diese Struktur:

WordPressAstroZweck
index.php, single.php, page.phpsrc/pages/URL-Routen
template-parts/src/components/Wiederverwendbares Markup
header.php und footer.phpsrc/layouts/Gemeinsame Seitenhüllen
style.csssrc/styles/Site-Stile
Plugin- und Datenbank-Setupastro.config.mjsIntegrationen und Server-Adapter
Theme-Setup-Datenseed/seed.jsonSammlungen, Menüs und Beispielinhalte

Das Blog-Template verwendet Routenverzeichnisse, die zu seinen öffentlichen URLs passen:

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 und ein HTML-Template. Code zwischen den ----Fences läuft auf dem Server. Das Markup unter dem zweiten Fence wird zum HTML der Antwort.

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 maskiert Werte, die mit {value} gerendert werden. Imports, Datenbankabfragen und andere Serverarbeit gehören ins Frontmatter.

Template-Ausdrücke

Astro-Templates verwenden geschweifte Klammern an den Stellen, an denen ein PHP-Template in <?php ?> wechseln würde. Die häufigsten Muster in EmDash-Templates sind Werte, Bedingungen und das Mapping von Arrays:

ZielAstro-Syntax
Einen Wert ausgeben{post.data.title}
Rendern, wenn ein Wert existiert{post.data.excerpt && <p>{post.data.excerpt}</p>}
Zwischen zwei Ergebnissen wählen{posts.length === 0 ? <p>No posts yet.</p> : <PostList />}
Eine Liste rendern{posts.map((post) => <PostCard title={post.data.title} excerpt={post.data.excerpt} href={"/posts/" + post.id} />)}

Der Ausdruck kann im Frontmatter vorbereitete Variablen, Werte aus Astro.props oder von einer EmDash-Abfrage zurückgegebene Daten verwenden. Astro maskiert String-Werte standardmäßig; verwenden Sie für strukturierten Rich Text einen Renderer wie <PortableText />, anstatt HTML einzuschleusen.

Props und Slots

Props sind mit den $args vergleichbar, die an get_template_part() übergeben werden. Sie machen jede Eingabe explizit und können von TypeScript geprüft werden.

Slots lassen ein übergeordnetes Element Markup in eine Komponente übergeben. Ein Default-Slot eignet sich für Seiteninhalte, während benannte Slots zusätzliche Einfügepunkte bereitstellen:

---
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="Latest post">
  <p>The main card content.</p>
  <a slot="footer" href="/posts/latest">Read the post</a>
</Card>

Slots sind lokal für den 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 auf 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="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{title}</title>
  </head>
  <body>
    <header><a href="/">My site</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="Home">
  <h1>Latest posts</h1>
</Base>

Dateibasiertes Routing

Dateien in src/pages/ definieren Routen. Dateinamen in eckigen Klammern erzeugen dynamische Segmente.

DateiURL
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

In 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

Aktuelle 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 einer EmDash-Theme-Route kein getStaticPaths() hinzu, es sei denn, die Site behandelt EmDash bewusst als Datenquelle zur Build-Zeit. Die mitgelieferten Themes werden serverseitig gerendert.

Lesen Sie Astro On-Demand-Rendering für das Verhalten auf Framework-Ebene.

EmDash-Inhalte abfragen

EmDash umhüllt die Live-Content-Collections von Astro mit getEmDashCollection() und getEmDashEntry(). Sammlungsergebnisse enthalten ein entries-Array. Ergebnisse für einzelne Einträge enthalten entry, das null ist, wenn kein veröffentlichter Eintrag passt.

Das folgende Archiv verwendet dieselbe Sortierung und dieselben 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("Could not load posts", { status: 500 });
}
---

<Base title="Posts">
  {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 Routenbezeichner und normalerweise der Slug des Eintrags. post.data.id ist der Datenbankbezeichner. Verwenden Sie data.id, wenn eine API die gespeicherte Inhalts-ID erwartet, etwa bei 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.rewrite("/404");

const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) return new Response("Could not load the post", { status: 500 });
if (!post) return Astro.rewrite("/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 außerdem Komponentenstile 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 Stile sowie Skripte und Event-Handling, wenn eine Komponente browserseitiges Verhalten benötigt.