EmDash 保留了熟悉的内容概念,如文章、页面、分类法、菜单、媒体和修订。Astro 提供主题层:路由、布局、组件和服务器渲染。
保持熟悉的部分
编辑器仍然使用命名内容类型、结构化字段、草稿和已发布状态、层级分类、扁平标签、嵌套菜单、媒体和修订历史。这些概念被迁移到 EmDash 集合和管理界面中。
开发工作流发生了变化。PHP 模板选择变为显式的 Astro 路由,模板部件变为导入的组件,代码与数据库内容分开部署。构建公共站点不需要 React;.astro 组件将服务器端 TypeScript 与类 HTML 模板结合在一起。
概念映射
| WordPress | EmDash 和 Astro |
|---|---|
| Post Type | EmDash 集合 |
| Post Meta | 集合字段 |
| 分类或标签 | EmDash 分类法 |
WP_Query | getEmDashCollection() |
get_post() | getEmDashEntry() |
the_content() | <PortableText /> |
| 模板层级 | src/pages/ 中的文件 |
| 模板部件 | 导入的 .astro 组件 |
header.php 和 footer.php | Astro 布局 |
wp_nav_menu() | getMenu() |
| 侧边栏 | 小部件区域和 <WidgetArea /> |
| Options API | 站点设置,或插件的 ctx.kv |
| WordPress 插件 | 沙盒或原生 EmDash 插件 |
内容模型
在 EmDash 管理后台的内容类型下创建和编辑集合。集合有明确的类型化字段,可以启用草稿、修订、定时发布、搜索、SEO 或评论。
查询返回 Astro 实时集合条目。entry.id 是路由标识符,通常是 slug;entry.data.id 是数据库内容 ID。
以下存档按发布顺序查询文章:
---
import { getEmDashCollection } from "emdash";
const { entries: posts, error } = await getEmDashCollection("posts", {
orderBy: { published_at: "desc" },
limit: 10,
});
if (error) return new Response("无法加载文章", { status: 500 });
---
{posts.map((post) => (
<article>
<h2><a href={`/posts/${post.id}`}>{post.data.title}</a></h2>
{post.data.excerpt && <p>{post.data.excerpt}</p>}
</article>
))}
主题文件
Astro 路由替代了 WordPress 模板层级。模板选择自己的 URL 结构,而不是依赖魔术文件名。
| WordPress 文件 | 当前博客模板文件 |
|---|---|
front-page.php 或 home.php | src/pages/index.astro |
single.php | src/pages/posts/[slug].astro |
archive.php | src/pages/posts/index.astro |
page.php | src/pages/pages/[slug].astro |
category.php | src/pages/category/[slug].astro |
tag.php | src/pages/tag/[slug].astro |
search.php | src/pages/search.astro |
404.php | src/pages/404.astro |
header.php 和 footer.php | src/layouts/Base.astro |
有关 EmDash 模板使用的项目结构、组件语法、Props、插槽、布局、路由和服务器渲染查询流,请阅读面向 WordPress 开发者的 Astro。
菜单和小部件区域
菜单和小部件区域存在于数据库中,设置后仍可编辑。模板在请求时查询它们:
---
import { getMenu } from "emdash";
import { WidgetArea } from "emdash/ui";
const primary = await getMenu("primary");
---
<nav>
{primary?.items.map((item) => <a href={item.url}>{item.label}</a>)}
</nav>
<aside><WidgetArea name="sidebar" /></aside>
站点设置和分类法
自定义器风格的站点身份位于 EmDash 设置中。获取一次设置,并在存在时使用解析后的徽标 URL:
---
import { getSiteSettings } from "emdash";
const settings = await getSiteSettings();
---
<a href="/">
{settings.logo?.url
? <img src={settings.logo.url} alt={settings.logo.alt || settings.title} />
: settings.title}
</a>
分类法术语是独立记录,而非直接存储在 entry.data 中的值。解析一个术语,然后在集合过滤器中使用其 slug:
import { getEmDashCollection, getTerm } from "emdash";
const news = await getTerm("category", "news", { includeCounts: false });
const { entries: posts } = news
? await getEmDashCollection("posts", { where: { category: news.slug } })
: { entries: [] };
插件格式
EmDash 有两种插件格式:
- 沙盒插件使用
emdash-plugin.jsonc作为其身份和信任合约,加上使用SandboxedPlugin类型的默认导出src/plugin.ts对象。它可以在隔离的运行时中运行,并使用 Block Kit 构建管理 UI。 - 原生插件导出构建时的描述符工厂和使用
definePlugin()构建的运行时createPlugin()函数。用于 React 管理组件、公共 Astro 组件或页面片段。
从选择插件格式开始。钩子名称和 PluginContext API 是共享的,但包和处理程序的形式不可互换。
导入 WordPress 内容
在管理侧边栏中打开 WordPress 导入,或直接访问 /_emdash/admin/import/wordpress。EmDash 支持两种导入路径:
- 上传从 工具 → 导出 导出的 WordPress eXtended RSS(WXR)文件。
- 在 WordPress 站点上安装 EmDash Exporter 插件,并使用 WordPress 应用密码连接。此路径可以包含普通公共 REST API 不公开的内容。
不使用导出器输入 WordPress URL 可以检测站点并统计公开文章、页面和媒体。该 REST 探测不导入内容。
导入器将 WordPress 的 publish 映射到 EmDash 的 published。草稿、待审、私密、定时、回收站和未知状态变为草稿。在更改 DNS 或停用 WordPress 之前,请检查导入的权限和发布状态。
完整步骤和重试行为请参见从 WordPress 迁移。
编辑器工作流
EmDash 管理后台提供集合列表、Portable Text 编辑器、媒体管理、菜单编辑、分类法管理、修订和预览链接。它不是 wp-admin 的视觉副本:Gutenberg 块变为 Portable Text,可用的界面取决于为站点配置的集合和功能。