EmDash 将熟悉的 WordPress 概念——文章、页面、分类法、菜单、小工具和媒体库——带入现代化的 Astro 技术栈。您的内容管理知识可以直接迁移。
保持熟悉的内容
您从 WordPress 了解的概念在 EmDash 中都是一流的功能:
- Collections 的工作方式类似于自定义文章类型——定义您的内容结构,在模板中查询它
- 分类法 的工作方式相同——分层(如类别)和扁平(如标签)
- 菜单 支持拖放排序和嵌套项
- 小工具区域 用于侧边栏和动态内容区域
- 媒体库 支持上传、组织和图片管理
- 管理界面 内容编辑者无需接触代码即可使用
不同的地方
实现方式改变了,但思维模型保持不变:
TypeScript 而非 PHP
模板是 Astro 组件。语法更清晰,但概念相同:输出 HTML 的服务器代码。
内容 API 而非 WP_Query
像 getEmDashCollection() 这样的查询函数取代了 WP_Query。不需要 SQL,只需函数调用。
基于文件的路由
src/pages/ 中的文件变成 URL。无需记忆重写规则或模板层次结构。
组件而非模板部分
导入并使用组件。与 get_template_part() 相同的想法,更好的组织方式。
快速参考
| WordPress | EmDash | 说明 |
|---|---|---|
| 自定义文章类型 | Collections | 通过管理界面或 API 定义 |
WP_Query | getEmDashCollection() | 过滤器、限制、分类法查询 |
get_post() | getEmDashEntry() | 返回条目或 null |
| 类别/标签 | 分类法 | 保留层次结构支持 |
register_nav_menus() | getMenu() | 一流的菜单支持 |
register_sidebar() | getWidgetArea() | 一流的小工具区域 |
bloginfo('name') | getSiteSetting("title") | 网站设置 API |
the_content() | <PortableText /> | 结构化内容渲染 |
| 短代码 | Portable Text 块 | 自定义组件 |
add_action/filter() | 插件钩子 | content:beforeSave 等 |
wp_options | ctx.kv | 键值存储 |
| 主题目录 | src/ 目录 | 组件、布局、页面 |
functions.php | astro.config.mjs + EmDash 配置 | 构建和运行时配置 |
内容 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 和 EmDash 中:
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 模板 | 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
// 在模板中:
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} />;
}
// 处理其他小工具类型
})}
</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 |
下面的示例使用 getSiteSetting() 读取单个设置:
import { getSiteSetting } from "emdash";
const title = await getSiteSetting("title");
const logo = await getSiteSetting("logo"); // 返回 { mediaId, alt, url }
分类法
分类法在概念上的工作方式相同——分层(如类别)或扁平(如标签):
import { getTaxonomyTerms, getEntryTerms, getTerm } from "emdash";
// 获取所有类别
const categories = await getTaxonomyTerms("categories");
// 获取特定术语
const news = await getTerm("categories", "news");
// 获取文章的术语
const postCategories = await getEntryTerms("posts", postId, "categories");
钩子 → 插件系统
WordPress 钩子(add_action、add_filter)变成 EmDash 插件钩子:
| WordPress 钩子 | EmDash 钩子 | 目的 |
|---|---|---|
save_post | content:beforeSave | 在保存前修改内容 |
the_content | PortableText 组件 | 转换渲染的内容 |
pre_get_posts | 查询选项 | 过滤查询 |
wp_head | 布局 <head> | 添加 head 内容 |
wp_footer | 布局 </body> 之前 | 添加 footer 内容 |
EmDash 的优势
类型安全
全面使用 TypeScript。Collections、查询和组件都是完全类型化的,因此字段名称和 返回类型可以自动完成并在构建时检查。
性能
默认静态生成,需要时进行服务器渲染。支持边缘部署。
现代开发体验
热模块替换。基于组件的架构。现代工具(Vite、TypeScript、ESLint)。
基于 Git 的部署
代码和模板存储在 git 中;内容存储在数据库中。通过推送代码进行部署。
预览链接
EmDash 使用 HMAC 签名令牌生成安全的预览 URL。内容编辑者共享预览链接以显示草稿,以便审核者可以在不登录生产环境的情况下查看。
隔离的插件
EmDash 插件在具有明确 API 的隔离上下文中运行。每个插件只能访问它声明的 API,因此插件不会共享或覆盖彼此的全局状态。
内容编辑者体验
内容编辑者使用类似于 wp-admin 的 EmDash 管理面板:
- 带有最近活动的仪表板
- 带有搜索、过滤和批量操作的 Collection 列表
- 用于内容的富文本编辑器(Portable Text,而非 Gutenberg)
- 支持拖放上传的媒体库
- 支持拖放排序的菜单构建器
- 用于侧边栏内容的小工具区域编辑器
编辑体验很熟悉。底层技术是现代化的。
迁移路径
EmDash 直接导入 WordPress 内容:
- 从 WordPress 导出(工具 → 导出)
- 在 EmDash 的管理界面中上传
.xml文件 - 将文章类型映射到 Collections
- 导入内容和媒体
文章、页面、分类法、菜单和媒体都会转移。Gutenberg 块转换为 Portable Text。自定义字段被分析和映射。
查看 WordPress 迁移指南获取完整说明。
下一步
- 入门 — 设置您的第一个 EmDash 网站
- 查询内容 — 深入了解内容 API
- 分类法 — 类别、标签和自定义分类法
- 菜单 — 导航菜单
- 从 WordPress 迁移 — 导入现有内容