EmDash 把熟悉的 WordPress 概念——文章、頁面、分類法、選單、小工具與媒體庫——帶進現代化的 Astro 技術堆疊。你的內容管理知識可以直接沿用。
依然熟悉的部分
你在 WordPress 裡熟悉的概念,在 EmDash 中都是第一級功能:
- Collections 就像 Custom Post Types——定義內容結構,在範本中查詢
- Taxonomies 同理——階層式(如分類)與扁平式(如標籤)
- Menus 支援拖曳排序與巢狀項目
- Widget Areas 用於側欄與動態內容區域
- Media library 含上傳、整理與圖片管理
- 編輯不必碰程式碼就能使用的 Admin UI
不同之處
實作會變,但心智模型不變:
以 TypeScript 取代 PHP
範本是 Astro 元件。語法更乾淨,概念相同:在伺服器上執行、輸出 HTML 的程式碼。
以 Content API 取代 WP_Query
像 getEmDashCollection() 這類查詢函式取代 WP_Query。沒有 SQL,只有函式呼叫。
以檔案為基礎的路由
src/pages/ 裡的檔案就是 URL。不必背重寫規則或範本階層。
以元件取代範本片段
import 並使用元件。與 get_template_part() 同一個想法,組織更清楚。
速查表
| WordPress | EmDash | 說明 |
|---|---|---|
| Custom Post Types | Collections | 透過管理後台或 API 定義 |
WP_Query | getEmDashCollection() | 篩選、筆數、分類法查詢 |
get_post() | getEmDashEntry() | 回傳項目或 null |
| Categories/Tags | Taxonomies | 階層支援維持不變 |
register_nav_menus() | getMenu() | 第一級選單支援 |
register_sidebar() | getWidgetArea() | 第一級小工具區域 |
bloginfo('name') | getSiteSetting("title") | 網站設定 API |
the_content() | <PortableText /> | 結構化內容呈現 |
| Shortcodes | Portable Text blocks | 自訂元件 |
add_action/filter() | Plugin hooks | 例如 content:beforeSave 等 |
wp_options | ctx.kv | 鍵值儲存 |
| Theme directory | src/ directory | 元件、版面、頁面 |
functions.php | astro.config.mjs + EmDash config | 建置與執行階段設定 |
Content API
查詢 Collections
WordPress 使用 WP_Query 或輔助函式查詢。EmDash 使用具型別的查詢函式。
WordPress
<?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; ?> EmDash
---
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>
))} 取得單一項目
WordPress
<?php
$post = get_post($id);
?>
<article>
<h1><?php echo $post->post_title; ?></h1>
<?php echo apply_filters('the_content', $post->post_content); ?>
</article> EmDash
---
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 用範本階層決定由哪個檔案呈現頁面。Astro 使用明確的以檔案為基礎的路由。
| WordPress Template | EmDash 對應 |
|---|---|
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 的範本片段會變成 Astro 元件:
WordPress
// 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> EmDash
---
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 提供第一級選單支援,並會自動解析 URL:
WordPress
<?php
wp_nav_menu([
'theme_location' => 'primary',
'container' => 'nav',
]);
?> EmDash
---
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> 選單可透過管理後台、種子檔或 WordPress 匯入建立。
小工具區域
小工具區域與 WordPress 的側欄類似:
WordPress
<?php if (is_active_sidebar('sidebar-1')) : ?>
<aside>
<?php dynamic_sidebar('sidebar-1'); ?>
</aside>
<?php endif; ?> EmDash
---
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} />;
}
// Handle other widget types
})}
</aside>
)} 網站設定
網站選項與自訂器設定對應到 getSiteSetting():
| 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"); // Returns { mediaId, alt, url }
分類法
概念相同——階層式(如分類)或扁平式(如標籤):
import { getTaxonomyTerms, getEntryTerms, getTerm } from "emdash";
// Get all categories
const categories = await getTaxonomyTerms("categories");
// Get a specific term
const news = await getTerm("categories", "news");
// Get terms for a post
const postCategories = await getEntryTerms("posts", postId, "categories");
Hooks → 外掛系統
WordPress 的掛勾(add_action、add_filter)對應 EmDash 的外掛掛勾:
| WordPress Hook | EmDash Hook | 用途 |
|---|---|---|
save_post | content:beforeSave | 儲存前修改內容 |
the_content | PortableText components | 轉換已呈現的內容 |
pre_get_posts | Query options | 篩選查詢 |
wp_head | Layout <head> | 在 head 加入內容 |
wp_footer | Layout before </body> | 在頁尾加入內容 |
EmDash 的優勢
型別安全
全面使用 TypeScript。Collections、查詢與元件皆有完整型別,不必再猜欄位名稱或回傳型別。
效能
沒有 PHP 負擔。預設靜態產生,需要時伺服器端呈現,並可部署到邊緣。
現代開發體驗
Hot module replacement。元件化架構。Vite、TypeScript、ESLint 等現代工具鏈。
以 Git 為主的部署
程式碼與範本在 git,內容在資料庫。不必 FTP、不必糾結檔案權限,也較少整站被駭的風險。
預覽連結
EmDash 會產生帶 HMAC 簽章權杖的安全預覽 URL。編輯不必登入正式環境就能預覽草稿——分享連結即可,不必給帳密。
沒有外掛衝突
WordPress 常見的外掛衝突在 EmDash 中消失。外掛在隔離的環境中以明確的 API 執行,不會污染全域狀態。
內容編輯體驗
編輯使用類似 wp-admin 的 EmDash 管理後台:
- 含最近活動的 Dashboard
- 支援搜尋、篩選與批次動作的 Collection 清單
- 內容用的富文字編輯器(Portable Text,不是 Gutenberg)
- 支援拖放上傳的媒體庫
- 支援拖曳排序的選單建構器
- 側欄內容用的小工具區域編輯器
編輯體驗熟悉,底層技術已現代化。
遷移路徑
EmDash 可直接匯入 WordPress 內容:
- 從 WordPress 匯出(工具 → 匯出)
- 在 EmDash 管理後台上傳
.xml檔 - 將文章類型對應到 collections
- 匯入內容與媒體
文章、頁面、分類法、選單與媒體都會轉移。Gutenberg 區塊會轉成 Portable Text。自訂欄位會被分析並對應。
完整步驟見 WordPress 遷移指南。
下一步
- Getting Started — 建立第一個 EmDash 網站
- Querying Content — 深入 Content API
- Taxonomies — 分類、標籤與自訂分類法
- Menus — 導覽選單
- Migrate from WordPress — 匯入既有內容