Astro für WordPress-Entwickler

Auf dieser Seite

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:

WordPressAstroZweck
index.php, single.php, page.phpsrc/pages/URL-Routen
template-parts/src/components/Wiederverwendbare Markup-Bausteine
header.php und footer.phpsrc/layouts/Gemeinsame Seitenhüllen
style.csssrc/styles/Site-Styles
Plugin- und Datenbank-Setupastro.config.mjsIntegrationen und Server-Adapter
Theme-Setup-Datenseed/seed.jsonSammlungen, 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:

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

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

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.