TypeScript statt PHP
Templates sind Astro-Komponenten. Die Syntax ist sauberer, aber das Konzept ist dasselbe: Server-Code, der HTML ausgibt.
EmDash überführt vertraute WordPress-Konzepte wie Beiträge, Seiten, Taxonomien, Menüs, Widgets und Mediathek in einen modernen Astro-Stack. Die redaktionelle Logik bleibt dabei gut wiedererkennbar.
Wenn Sie Plattformen vor einer Migration vergleichen, lesen Sie EmDash vs WordPress und WordPress zu Astro mit EmDash.
Die Konzepte, die Sie von WordPress kennen, sind erstklassige Funktionen in EmDash:
Die Implementierung ändert sich, aber das mentale Modell bleibt gleich:
TypeScript statt PHP
Templates sind Astro-Komponenten. Die Syntax ist sauberer, aber das Konzept ist dasselbe: Server-Code, der HTML ausgibt.
Content-APIs statt WP_Query
Abfragefunktionen wie getEmDashCollection() ersetzen WP_Query. Kein SQL, nur Funktionsaufrufe.
Dateibasiertes Routing
Dateien in src/pages/ werden zu URLs. Keine Rewrite-Regeln oder Template-Hierarchie zum Auswendiglernen.
Komponenten statt Template-Parts
Importieren und verwenden Sie Komponenten. Gleiche Idee wie get_template_part(), bessere Organisation.
| WordPress | EmDash | Anmerkungen |
|---|---|---|
| Custom Post Types | Collections | Über Admin-UI oder API definieren |
WP_Query | getEmDashCollection() | Filter, Limits, Taxonomie-Abfragen |
get_post() | getEmDashEntry() | Gibt Eintrag oder null zurück |
| Categories/Tags | Taxonomies | Hierarchische Unterstützung erhalten |
register_nav_menus() | getMenu() | Erstklassige Menüunterstützung |
register_sidebar() | getWidgetArea() | Erstklassige Widget-Bereiche |
bloginfo('name') | getSiteSetting("title") | Site-Settings-API |
the_content() | <PortableText /> | Strukturierte Inhaltsdarstellung |
| Shortcodes | Portable Text blocks | Benutzerdefinierte Komponenten |
add_action/filter() | Plugin hooks | content:beforeSave, etc. |
wp_options | ctx.kv | Key-Value-Speicher |
| Theme directory | src/ directory | Komponenten, Layouts, Seiten |
functions.php | astro.config.mjs + EmDash config | Build- und Laufzeitkonfiguration |
WordPress-Abfragen verwenden WP_Query oder Hilfsfunktionen. EmDash verwendet typisierte Abfragefunktionen.
<?php$posts = new WP_Query([ 'post_type' => 'post', 'posts_per_page' => 10, 'post_status' => 'publish', 'category_name' => 'news',]);
while ($posts->have_posts()) :$posts->the_post();?>
<h2><?php the_title(); ?></h2> <?php the_excerpt(); ?><?php endwhile; ?>---import { getEmDashCollection } from "emdash";
const { entries: posts } = await getEmDashCollection("posts", {status: "published",limit: 10,where: { category: "news" },});
---
{posts.map((post) => (
<article> <h2>{post.data.title}</h2> <p>{post.data.excerpt}</p> </article>))}<?php$post = get_post($id);?><article> <h1><?php echo $post->post_title; ?></h1> <?php echo apply_filters('the_content', $post->post_content); ?></article>---import { getEmDashEntry } from "emdash";import { PortableText } from "emdash/ui";
const { slug } = Astro.params;const { entry: post } = await getEmDashEntry("posts", slug);
if (!post) return Astro.redirect("/404");
<article> <h1>{post.data.title}</h1> <PortableText value={post.data.content} /></article>WordPress verwendet eine Template-Hierarchie, um auszuwählen, welche Datei eine Seite rendert. Astro verwendet explizites, dateibasiertes Routing.
| WordPress-Template | EmDash-Äquivalent |
|---|---|
index.php | src/pages/index.astro |
single.php | src/pages/posts/[slug].astro |
single-{type}.php | src/pages/{type}/[slug].astro |
page.php | src/pages/pages/[slug].astro |
archive.php | src/pages/posts/index.astro |
archive-{type}.php | src/pages/{type}/index.astro |
category.php | src/pages/categories/[slug].astro |
tag.php | src/pages/tags/[slug].astro |
search.php | src/pages/search.astro |
404.php | src/pages/404.astro |
header.php / footer.php | src/layouts/Base.astro |
sidebar.php | src/components/Sidebar.astro |
WordPress Template Parts werden zu Astro-Komponenten:
// In template:get_template_part('template-parts/content', 'post');
// template-parts/content-post.php:
<article class="post"> <h2><?php the_title(); ?></h2> <?php the_excerpt(); ?></article>---const { post } = Astro.props;---
<article class="post"> <h2>{post.data.title}</h2> <p>{post.data.excerpt}</p></article>---import PostCard from "../../components/PostCard.astro";import { getEmDashCollection } from "emdash";
const { entries: posts } = await getEmDashCollection("posts");---
{posts.map((post) => <PostCard {post} />)}EmDash bietet erstklassige Menüunterstützung mit automatischer URL-Auflösung:
<?phpwp_nav_menu([ 'theme_location' => 'primary', 'container' => 'nav',]);?>---import { getMenu } from "emdash";
const menu = await getMenu("primary");
<nav> <ul> {menu?.items.map((item) => ( <li> <a href={item.url}>{item.label}</a> </li> ))} </ul></nav>Menüs werden über die Admin-Oberfläche, Seed-Dateien oder WordPress-Import erstellt.
Widget-Bereiche funktionieren wie Sidebars in WordPress:
<?php if (is_active_sidebar('sidebar-1')) : ?> <aside> <?php dynamic_sidebar('sidebar-1'); ?> </aside><?php endif; ?>---import { getWidgetArea } from "emdash";import { PortableText } from "emdash/ui";
const sidebar = await getWidgetArea("sidebar");
{sidebar && (
<aside> {sidebar.widgets.map((widget) => { if (widget.type === "content") { return <PortableText value={widget.content} />; } // Andere Widget-Typen behandeln })} </aside>)}Website-Optionen und Customizer-Einstellungen werden auf getSiteSetting() abgebildet:
| WordPress | EmDash |
|---|---|
bloginfo('name') | getSiteSetting("title") |
bloginfo('description') | getSiteSetting("tagline") |
get_custom_logo() | getSiteSetting("logo") |
get_option('date_format') | getSiteSetting("dateFormat") |
home_url() | Astro.site |
import { getSiteSetting } from "emdash";
const title = await getSiteSetting("title");const logo = await getSiteSetting("logo"); // Gibt { mediaId, alt, url } zurückTaxonomien funktionieren konzeptionell gleich – hierarchisch (wie Kategorien) oder flach (wie Tags):
import { getTaxonomyTerms, getEntryTerms, getTerm } from "emdash";
// Alle Kategorien abrufenconst categories = await getTaxonomyTerms("categories");
// Einen bestimmten Begriff abrufenconst news = await getTerm("categories", "news");
// Begriffe für einen Beitrag abrufenconst postCategories = await getEntryTerms("posts", postId, "categories");WordPress-Hooks (add_action, add_filter) werden zu EmDash-Plugin-Hooks:
| WordPress Hook | EmDash Hook | Zweck |
|---|---|---|
save_post | content:beforeSave | Inhalt vor dem Speichern ändern |
the_content | PortableText components | Gerenderten Inhalt transformieren |
pre_get_posts | Query options | Abfragen filtern |
wp_head | Layout <head> | Head-Inhalt hinzufügen |
wp_footer | Layout before </body> | Footer-Inhalt hinzufügen |
Typsicherheit
Durchgängig TypeScript. Sammlungen, Abfragen und Komponenten sind vollständig typisiert. Kein Raten mehr bei Feldnamen oder Rückgabetypen.
Leistung
Kein PHP-Overhead. Standardmäßig statische Generierung. Server-Rendering bei Bedarf. Bereit für Edge-Deployment.
Moderne DX
Hot Module Replacement. Komponentenbasierte Architektur. Moderne Tools (Vite, TypeScript, ESLint).
Git-basierte Deployments
Code und Templates in Git. Inhalt in der Datenbank. Kein FTP, keine Dateiberechtigungen, keine gehackten Websites.
EmDash generiert sichere Vorschau-URLs mit HMAC-signierten Tokens. Inhaltseditoren können Entwürfe ohne Anmeldung in der Produktion vorschauen – einen Link teilen, keine Zugangsdaten.
WordPress-Plugin-Konflikte verschwinden. EmDash-Plugins laufen in isolierten Kontexten mit expliziten APIs. Keine globale Zustandsverschmutzung.
Inhaltseditoren verwenden das EmDash-Admin-Oberfläche, ähnlich wie wp-admin:
Die Bearbeitungserfahrung ist vertraut. Die darunterliegende Technologie ist modern.
EmDash importiert WordPress-Inhalte direkt:
.xml-Datei im EmDash-Admin hochladenBeiträge, Seiten, Taxonomien, Menüs und Medien werden übertragen. Gutenberg-Blöcke werden in Portable Text konvertiert. Benutzerdefinierte Felder werden analysiert und abgebildet.
Siehe die WordPress-Migrationsanleitung für vollständige Anweisungen.