Portable Text 渲染组件

本页内容

插件可以向 Portable Text 编辑器添加自定义块类型 — YouTube 嵌入、代码片段、图片画廊,任何默认块集未涵盖的内容。沙盒化插件可以声明这些块的编辑界面(使用 Block Kit 字段),但在公开网站上渲染它们的 Astro 组件必须在构建时从 npm 加载。这就是需要原生插件的部分。

如果你的插件只需要编辑侧字段,并且其他人正在提供渲染组件(或网站在本地提供它们),你可以保持沙盒化。如果插件也应该提供渲染组件,则需要是原生的。

声明块类型

沙盒化和原生插件都可以声明块类型。原生插件在 definePlugin()admin.portableTextBlocks 下执行此操作:

admin: {
	portableTextBlocks: [
		{
			type: "youtube",
			label: "YouTube Video",
			icon: "video",                       // video, code, link, link-external
			placeholder: "Paste YouTube URL...",
			fields: [                            // Block Kit fields for the editing UI
				{ type: "text_input", action_id: "id", label: "YouTube URL" },
				{ type: "text_input", action_id: "title", label: "Title" },
				{ type: "text_input", action_id: "poster", label: "Poster Image URL" },
			],
		},
	],
},

每个块类型定义:

  • type — 块类型名称(在 Portable Text _type 中使用)。
  • label — 编辑器斜杠命令菜单中的显示名称。
  • iconvideocodelinklink-external。默认回退到通用立方体。
  • placeholder — 输入占位符文本。
  • fields — 用于编辑的 Block Kit 表单字段。如果省略,则显示简单的 URL 输入。

在公开网站上渲染

要在公开网站上渲染块类型,从 componentsEntry 导出 Astro 组件。导出名称必须blockComponents

import YouTube from "./YouTube.astro";
import CodePen from "./CodePen.astro";

export const blockComponents = {
	youtube: YouTube,
	codepen: CodePen,
};

在描述符上设置 componentsEntry

export function myPlugin(): PluginDescriptor {
	return {
		id: "embeds",
		version: "1.0.0",
		format: "native",
		entrypoint: "@my-org/embeds",
		componentsEntry: "@my-org/embeds/astro",
	};
}

EmDash 会自动将插件块组件合并到 <PortableText> 中 — 网站作者无需导入任何内容。用户提供的组件(在网站的 <PortableText>components 属性中声明)优先于插件默认值。

包导出

./astro 导出添加到 package.json

{
	"exports": {
		".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" },
		"./admin": { "types": "./dist/admin.d.ts", "import": "./dist/admin.js" },
		"./astro": { "types": "./dist/astro/index.d.ts", "import": "./dist/astro/index.js" }
	}
}

./astro 导出是服务器端(Astro SSR),./admin 导出是浏览器端(React),"." 导出是描述符 + createPlugin。将它们保存在单独的文件中,因为它们为不同的环境打包。

沙盒友好的变体

如果你希望插件是沙盒化的,但仍然提供默认的渲染体验,通常的模式是:

  1. 在市场上发布沙盒化插件(仅编辑字段)。
  2. 在 npm 上发布一个单独的配套原生包,提供 Astro 渲染组件。
  3. 记录两者:最终用户从市场安装沙盒化插件,并使用 npm install 安装用于渲染的配套包。

这将一步安装换成保持编辑器端的沙盒化。当涉及块渲染时,大多数插件作者更喜欢直接使用原生 — 但该选项是存在的。