面向 WordPress 开发者的 EmDash

本页内容

EmDash 保留了熟悉的内容概念,例如文章、页面、分类法、菜单、媒体和修订版本。Astro 提供主题层:路由、布局、组件和服务器渲染。

保持熟悉的部分

编辑者仍然使用命名的内容类型、结构化字段、草稿和已发布状态、层级分类、扁平标签、嵌套菜单、媒体以及修订历史。这些概念都对应到 EmDash 的集合和管理界面中。

开发工作流有所不同。PHP 模板选择变成显式的 Astro 路由,模板部件变成导入的组件,代码与数据库内容分开部署。构建公开站点不需要 React;.astro 组件将服务器端 TypeScript 与类似 HTML 的模板结合在一起。

概念映射

WordPressEmDash 和 Astro
Post TypeEmDash 集合
Post Meta集合字段
分类或标签EmDash 分类法
WP_QuerygetEmDashCollection()
get_post()getEmDashEntry()
the_content()<PortableText />
模板层级src/pages/ 中的文件
模板部件导入的 .astro 组件
header.php 和 footer.phpAstro 布局
wp_nav_menu()getMenu()
侧边栏小部件区域和 <WidgetArea />
Options API站点设置,或插件的 ctx.kv
WordPress 插件沙盒或原生 EmDash 插件

内容模型

在 EmDash 管理后台的 Content Types 下创建和编辑集合。集合具有显式类型的字段,并且可以启用草稿、修订版本、定时发布、搜索、SEO 或评论。

查询返回 Astro 实时集合(live collection)条目。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("Could not load posts", { 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.phpsrc/pages/index.astro
single.phpsrc/pages/posts/[slug].astro
archive.phpsrc/pages/posts/index.astro
page.phpsrc/pages/pages/[slug].astro
category.phpsrc/pages/category/[slug].astro
tag.phpsrc/pages/tag/[slug].astro
search.phpsrc/pages/search.astro
404.phpsrc/pages/404.astro
header.php 和 footer.phpsrc/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>

站点设置和分类法

Customizer 风格的站点标识存储在 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 内容

在管理后台侧边栏中选择 Import 以打开 Import from WordPress 页面,或直接访问 /_emdash/admin/import/wordpress。EmDash 支持两种导入路径:

  1. 上传从 Tools → Export 导出的 WordPress eXtended RSS(WXR)文件。
  2. 在 WordPress 站点上安装 EmDash Exporter 插件,并使用 WordPress 应用程序密码进行连接。此路径可以包含普通公开 REST API 不会暴露的内容。

在没有导出器的情况下输入 WordPress URL,可以检测站点并统计公开的文章、页面和媒体。该 REST 探测不会导入内容。

导入器将 WordPress 的 publish 映射到 EmDash 的 published。草稿、待审、私密、定时、回收站和未知状态都会变为草稿。在更改 DNS 或停用 WordPress 之前,请检查导入的权限和发布状态。

完整步骤和重试行为请参见从 WordPress 迁移。

编辑器工作流

EmDash 管理后台提供集合列表、Portable Text 编辑器、媒体管理、菜单编辑、分类法管理、修订版本和预览链接。它不是 wp-admin 的可视化复制品:Gutenberg 区块会变成 Portable Text,可用的界面取决于为站点配置的集合和功能。

下一步