React 管理页面和小部件

本页内容

原生插件可以使用自定义 React 页面、仪表板小部件、字段小部件和内容列表列来扩展管理面板——沙盒插件改为将其 UI 描述为 Block Kit,因为将插件 JavaScript 加载到管理面板会破坏沙盒隔离。

如果您的插件只需要设置表单,自动生成的 admin.settingsSchema 表单(参见您的第一个原生插件)无需编写 React 即可覆盖大多数场景。

管理入口点

import { SEOSettingsPage } from "./components/SEOSettingsPage";
import { SEODashboardWidget } from "./components/SEODashboardWidget";

export const widgets = { "seo-overview": SEODashboardWidget };
export const pages = { "/settings": SEOSettingsPage };
{ "exports": { ".": "./dist/index.js", "./admin": "./dist/admin.js" } }
definePlugin({
	id: "seo",
	version: "1.0.0",
	admin: {
		entry: "@my-org/plugin-seo/admin",
		pages: [{ path: "/settings", label: "SEO Settings", icon: "settings" }],
		widgets: [{ id: "seo-overview", title: "SEO Overview", size: "half" }],
	},
});

管理页面

管理页面是挂载在 /_emdash/admin/plugins/<plugin-id>/<路径> 下的 React 组件。标签以英文声明——管理面板在渲染侧边栏和命令面板之前会通过共享的 Lingui 实例处理,因此加载自己消息目录的插件可以免费获得本地化导航。

插件 API Hook

usePluginAPI() 会自动添加插件 ID 前缀和 X-EmDash-Request: 1 CSRF 头来调用插件路由。

仪表板小部件

大小描述
full仪表板全宽
half仪表板半宽
third仪表板三分之一宽

内容编辑器面板

受信任的 React 插件可以为已保存的内容条目在设置侧边栏中添加宿主框架的区域。

import type { ContentEditorPanelContext } from "@emdash-cms/admin";

function ContentInsights({ entry, locale }: ContentEditorPanelContext) {
	return <p>{entry.slug} 的分析({locale ?? "默认区域设置"})</p>;
}

export const contentEditorPanels = [
	{ id: "content-insights", title: "内容洞察", component: ContentInsights, collections: ["posts", "pages"], minRole: 40, order: 10 },
];

内容列表列

受信任的 React 插件可以向活跃的内容集合列表添加只读列。

自动生成的设置 UI

admin: {
	settingsSchema: {
		apiKey: { type: "secret", label: "API Key" },
		enabled: { type: "boolean", label: "Enabled", default: true },
	},
},

构建配置

tsdown

export default {
	entry: { index: "src/index.ts", admin: "src/admin.tsx" },
	format: "esm", dts: true,
	external: ["react", "react-dom", "emdash", "@emdash-cms/admin"],
};

tsup

export default {
	entry: ["src/index.ts", "src/admin.tsx"],
	format: "esm", dts: true,
	external: ["react", "react-dom", "emdash", "@emdash-cms/admin"],
};

启用/禁用插件

当插件在管理面板中被禁用时:侧边栏链接被隐藏、仪表板小部件不渲染、内容列表列不渲染、管理页面返回 404、后端钩子继续执行(为了数据安全)。

const enabled = await ctx.kv.get<boolean>("_emdash:enabled");