- 中文整理标题: 为 WordPress 编辑器的“预览”菜单添加自定义入口
- 来源: WordPress Developer Blog
- 作者: Birgit Pauli-Haack
- 原文日期: 2026 年 2 月 19 日
- 适用前提: WordPress 6.7 起;示例使用区块编辑器插件开发工具链
WordPress 编辑器顶部栏的“预览”下拉菜单可以放入插件自己的预览入口。本文按原文的“社交卡片预览”示例,说明如何注册菜单项、打开弹窗、从编辑器状态读取文章信息,并在本地临时站点中查看效果。原文页面包含菜单和弹窗截图;此稿不附带图片。
1. 了解扩展点
WordPress 6.7 起,插件可以通过 @wordpress/editor 包中的 PluginPreviewMenuItem 向编辑器“预览”菜单注册项目。它沿用 Slot/Fill 扩展模式,与 PluginMoreMenuItem、PluginSidebar 等编辑器扩展点相似。
菜单项可以使用 onClick 处理按钮行为,也可以用 href 指向链接;icon 是可选图标属性。组件标签之间的文本就是菜单显示名称。示例点击后打开一个模态框,预览当前文章在 X 上分享时的卡片样式。预览读取编辑器中的标题、摘要和特色图片,因此会反映尚未保存的编辑内容。
2. 准备插件目录和 PHP 引导文件
插件目录包含主 PHP 文件、构建配置和源文件:
custom-preview/
├── custom-preview.php
├── package.json
└── src/
├── index.js
├── social-card-preview.js
└── style.css
在 custom-preview.php 中,通过 enqueue_block_editor_assets 钩子只为区块编辑器注册脚本和样式。构建工具生成的 build/index.asset.php 提供依赖项及版本哈希;文件不存在时直接返回,避免引用尚未构建的资源。
function social_card_preview_enqueue_editor_assets() {
$asset_file = plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
if ( ! file_exists( $asset_file ) ) {
return;
}
$asset = include $asset_file;
wp_enqueue_script(
'social-card-preview-editor',
plugin_dir_url( __FILE__ ) . 'build/index.js',
$asset['dependencies'],
$asset['version'],
true
);
wp_enqueue_style(
'social-card-preview-editor',
plugin_dir_url( __FILE__ ) . 'build/style-index.css',
array(),
$asset['version']
);
}
add_action( 'enqueue_block_editor_assets', 'social_card_preview_enqueue_editor_assets' );
3. 配置 JavaScript 构建工具
原文示例使用 @wordpress/scripts。在 package.json 中声明构建和监听脚本,并将该工具列为开发依赖:
{
"name": "social-card-preview",
"version": "1.0.0",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
},
"devDependencies": {
"@wordpress/scripts": "^30.0.0"
}
}
安装依赖并构建生产资源:
npm install
npm run build
开发时可运行 npm run start,让构建工具监听文件变动并自动重建。
4. 注册“社交卡片预览”菜单项
在 src/index.js 中注册插件组件。点击菜单项时将弹窗状态设为打开;条件渲染弹窗,并把关闭回调传给它。
import { __ } from '@wordpress/i18n';
import { registerPlugin } from '@wordpress/plugins';
import { PluginPreviewMenuItem } from '@wordpress/editor';
import { useState } from '@wordpress/element';
import SocialCardPreview from './social-card-preview';
import './style.css';
const SocialCardPreviewMenuItem = () => {
const [ isOpen, setIsOpen ] = useState( false );
return (
<>
<PluginPreviewMenuItem
onClick={ () => setIsOpen( true ) }
>
{ __( 'Social Card Preview', 'social-card-preview' ) }
</PluginPreviewMenuItem>
{ isOpen && (
<SocialCardPreview
onClose={ () => setIsOpen( false ) }
/>
) }
</>
);
};
registerPlugin( 'social-card-preview', {
render: SocialCardPreviewMenuItem,
} );
这里由 registerPlugin 把组件接入编辑器;useState 只负责控制弹窗显隐。菜单文本通过 __() 包装,便于国际化。
5. 从编辑器状态生成预览数据
src/social-card-preview.js 使用 useSelect 读取两个数据源:从 editor store 取得当前编辑的标题、摘要和特色媒体 ID;再从 core-data store 解析媒体对象及站点 URL。媒体优先使用 large 尺寸,没有该尺寸时回退到原始 source_url。示例将摘要截为 200 个字符,并在末尾添加省略号。
import { __ } from '@wordpress/i18n';
import { Modal } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
import { store as coreStore } from '@wordpress/core-data';
const SocialCardPreview = ( { onClose } ) => {
const { title, excerpt, imageUrl, siteUrl } = useSelect( ( select ) => {
const { getEditedPostAttribute } = select( editorStore );
const featuredMediaId = getEditedPostAttribute( 'featured_media' );
let featuredImageUrl = '';
if ( featuredMediaId ) {
const media = select( coreStore ).getMedia( featuredMediaId );
featuredImageUrl =
media?.media_details?.sizes?.large?.source_url ||
media?.source_url ||
'';
}
return {
title: getEditedPostAttribute( 'title' ) || '',
excerpt: getEditedPostAttribute( 'excerpt' ) || '',
imageUrl: featuredImageUrl,
siteUrl: select( coreStore ).getSite()?.url || '',
};
}, [] );
const domain = siteUrl ? new URL( siteUrl ).hostname : '';
const truncatedExcerpt =
excerpt.length > 200
? excerpt.substring( 0, 200 ) + '…'
: excerpt;
return (
<Modal
title={ __( 'X Preview', 'social-card-preview' ) }
onRequestClose={ onClose }
size="medium"
>
{ /* 卡片预览标记见下一节 */ }
</Modal>
);
};
useSelect 会订阅所选数据,编辑过程中标题或摘要改变时,预览可以随编辑状态更新。此组件中的示例代码把卡片标记留作下一步插入到 Modal 内部。
6. 加入卡片标记
卡片由特色图片和文字区域构成。没有特色图片时不渲染 img;站点域名、标题和截短后的摘要分别使用 span。原文将它说明为视觉模拟,因此没有把这些元素写成语义标题或段落。类名采用 BEM 风格,便于把样式限定在本组件内。
将下面的 JSX 放在上一节 Modal 的开始和结束标签之间:
<div className="social-card-preview">
<div className="social-card-preview__card social-card-preview__card--twitter">
{ imageUrl && (
<img
className="social-card-preview__image"
src={ imageUrl }
alt=""
/>
) }
<div className="social-card-preview__content">
<span className="social-card-preview__domain">
{ domain }
</span>
<span className="social-card-preview__title">
{ title }
</span>
<span className="social-card-preview__description">
{ truncatedExcerpt }
</span>
</div>
</div>
</div>
7. 添加基础样式
示例以边框、圆角和溢出裁切模拟卡片外观;标题使用两行截断:
.social-card-preview__card {
border: 1px solid #dadce0;
border-radius: 16px;
overflow: hidden;
}
.social-card-preview__title {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
原文指出,卡片使用 16px 圆角来接近 X 的圆角视觉;-webkit-line-clamp 处理标题和描述的多行截断。
8. 用 WordPress Playground 查看入口
原文使用 Playground CLI 启动一次性 WordPress 实例,不要求预先安装完整站点。前提是 Node.js 20.18 或更高版本;在插件目录中依次运行:
npm install
npm run build
npx @wp-playground/cli@latest server --auto-mount --login
CLI 会自动挂载插件并登录管理员。随后在浏览器打开 http://127.0.0.1:9400,新建或编辑文章,打开编辑器顶部的“预览”下拉菜单,即可查看“Social Card Preview”入口。以上是原文给出的操作步骤,本稿没有实际运行这些命令。
9. 可扩展的预览场景
同一个扩展点也可以承载其他编辑时检查或预览,例如:
- 无障碍检查: 打开模态框,检查缺少替代文本、对比度不足等常见问题。
- 可读性预览: 展示可读性分数和简化后的内容。
- 外部预览服务: 使用 href 属性,将文章 URL 带到第三方 staging 或 QA 环境。
- 邮件简报预览: 展示文章套用邮件模板后在邮件客户端中的样子。
来源信息
- 原文: How to add custom entries to the editor Preview dropdown
- 作者: Birgit Pauli-Haack
- 日期: 2026 年 2 月 19 日
- 版本提示: 原文说明该扩展能力自 WordPress 6.7 起提供。











暂无评论内容