资讯详情

Elementor Editor V2 编辑器包扩展实战:从 PHP 注册、UI 注入到 MCP 工具挂载

📅 2026/9/17 8:16:24 | 华诺云谱 👁 阅读
Elementor Editor V2 编辑器包扩展实战:从 PHP 注册、UI 注入到 MCP 工具挂载
Elementor Editor V2 编辑器包扩展实战从 PHP 注册、UI 注入到 MCP 工具挂载【免费下载链接】elementorThe most advanced frontend drag drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.项目地址: https://gitcode.com/GitHub_Trending/el/elementor本指南围绕 Elementor 开源仓库中的 add-editor-package 示例文档完整讲解如何通过插件自有 Package扩展 Editor V2 编辑器先用 PHP 过滤器注册包名再在 TypeScript 包的init()中注入 UI 槽位、注册面板与菜单最后通过elementor/editor-mcp为编辑器内 AgentAngie / WebMCP注册领域化 MCP 工具。读完本文你将掌握一条可复制的端到端扩展路径并能对照 site-navigation 模块 等仓库内真实实现进行验证。一、前置认知Editor V2 的包加载机制在动手写代码之前需要先理解包Package在 Editor V2 架构中的位置。Editor V2 是 Elementor 模块化的编辑器前端功能以独立构建的包React TypeScript为单位发布通过 WordPress 脚本句柄script handle入队并暴露在window.elementorV2全局对象上。PHP 端通过 WordPress 过滤器把包名追加进加载列表每个被加载的包在elementor/editor渲染之前运行一次init()完成注册。这一机制在 overview.md 中有完整描述。从 core/editor/loader/editor-loader.php 的实现可以看到包加载的完整生命周期Load—— 每个包经wp_enqueue_script入队依赖来自构建产物.asset.phpEnv——elementor/editor/v2/scripts/env过滤器产出运行期配置写入elementorEditorEnv全局Init extensions—— 依次调用window.elementorV2.{packageName}?.init?.()Start app—— 调用window.elementorV2.editor.start( domElement )启动 React 外壳。值得注意的是init()的执行顺序遵循**脚本依赖图dependency graph**而非 PHP 过滤器数组的书写顺序。另外Editor_Loader::apply_editor_filter()揭示了过滤器链的实际走向elementor/editor/{hook}→elementor/editor/v1/{hook}→elementor/editor/v2/{hook}。也就是说本文使用的elementor/editor/v2/packages是三级链路的最后一环既兼容旧扩展也面向新包。二、PHP 端注册包两个过滤器扩展的第一步是让 WordPress 后端认识你的包。示例文档给出两个过滤器一个负责把包名加入加载列表一个负责注入运行期环境配置add_filter( elementor/editor/v2/packages, function ( array $packages ) { return array_merge( $packages, [ editor-my-feature ] ); } ); add_filter( elementor/editor/v2/scripts/env, function ( array $env ) { $env[elementor/editor-my-feature] [ enabled true ]; return $env; } );要点拆解第一个过滤器接收当前已注册的包名数组$packages用array_merge追加你的包名editor-my-feature。包名是字符串最终会映射到window.elementorV2.editorMyFeaturecamelCase 化并触发其init()。第二个过滤器以elementor/{包名}为键写入任意 JSON 可序列化的配置前端包可通过elementor/env等机制读取。示例中的enabled只是示范实际可放入任何业务数据。仓库内最直接的标准答案是 modules/site-navigation/module.phpconst PACKAGES [ editor-site-navigation, ]; // 构造函数中 add_filter( elementor/editor/v2/packages, fn( $packages ) $this-add_packages( $packages ) ); add_filter( elementor/editor/v2/scripts/env, function( $env ) { $env[elementor/editor-site-navigation] [ is_pages_panel_active Plugin::$instance-experiments-is_feature_active( self::PAGES_PANEL_EXPERIMENT_NAME ), ]; return $env; } );可以看到生产代码的两种进阶做法其一用Plugin::$instance-experiments-is_feature_active()把实验开关Experiment状态注入 env前端据此决定是否渲染面板其二包名收敛为模块常量PACKAGES由array_merge( $packages, self::PACKAGES )统一合并便于集中管理。文档 extending-editor.md 还展示了一种按条件返回的写法——功能未激活时直接返回原数组、不注册包实现延迟/按需加载。三、JS 端创建包init()契约与入口导出包的核心是src/init.ts中的init()函数。构建体系webpack 构建尾部会自动调用window.elementorV2.{camelCasePackage}?.init?.()——例如包名editor-my-feature对应window.elementorV2.editorMyFeature。init()是同步注册函数只做注册不负责渲染渲染工作交给注入到各槽位的 React 组件完成。init()契约在 overview.md 中定义为window.elementorV2.{packageName}?.init?.();示例文档给出的init.ts结构import { injectIntoPageIndication, toolsMenu } from elementor/editor-app-bar; import { getMCPByDomain } from elementor/editor-mcp; import { z } from elementor/schema; import { MyIndicator } from ./components/my-indicator; import { useMyToggleProps } from ./hooks/use-my-toggle-props; export function init() { injectIntoPageIndication( { id: my-indicator, component: MyIndicator, } ); toolsMenu.registerToggleAction( { id: toggle-my-panel, priority: 20, useProps: useMyToggleProps, } ); const mcp getMCPByDomain( my_feature, { instructions: Short hint for agents, docs: Full domain documentation, } ); mcp.addTool( { name: my_tool, description: Does something in the editor, schema: { elementId: z.string().describe( Target element id ), }, handler: async ( { elementId } ) Handled ${ elementId }, } ); }同时必须从src/index.ts再导出init构建脚本才能识别包入口// src/index.ts export { init } from ./init;仓库内最贴近此示例的真实实现是 packages/packages/core/editor-site-navigation/src/init.ts它同样调用injectIntoPageIndication()注册顶部栏组件通过toolsMenu.registerToggleAction()注册带priority: 6的开关动作并在实验开关激活时用registerPanel( panel )注册滑入面板——id、component、priority、useProps等参数与示例一一对应是阅读 API 用法的绝佳范本。四、注入 API 全景六大扩展区域示例文档用一张表概括了常用注入 API按编辑器区域 → 注入 API → 所属包组织区域API所属包Shell 外壳injectIntoTop、injectIntoLogicelementor/editor顶栏 App barinjectIntoPageIndication、toolsMenu.registerToggleActionelementor/editor-app-bar样式选项卡injectIntoStyleTabelementor/editor-editing-panel元素面板injectTabelementor/editor-elements-panel样式仓库stylesRepository.registerelementor/editor-styles-repositoryv1 桥接registerDataHook、blockCommand、__privateListenToelementor/editor-v1-adapters对照 extending-editor.md 的完整 Public API 表还可补充几个同族入口编辑面板替换registerEditingPanelReplacementelementor/editor-editing-panel按元素类型条件替换整个面板站点设置选项卡injectSiteSettingsTabelementor/editor-site-settings滑入面板registerPanelelementor/editor-panelsRedux slice__registerSliceelementor/storeMCP 领域getMCPByDomainelementor/editor-mcp。从 packages/packages/core/editor/src/index.ts 的导出可以看到 Shell 层的两个注入点injectIntoTop、injectIntoLogic与start()同源发布这印证了外壳槽位由elementor/editor提供的设计。需要做旧事件桥接的场景React UI 里监听 v1 编辑器事件则依赖elementor/editor-v1-adapters的registerDataHook、blockCommand以及listenTo( v1ReadyEvent(), fn )——注意带__private前缀的导出属于内部 API不建议在生产代码中使用。五、MCP 命名空间与工具注册Editor V2 的包扩展不仅是 UI 注入还包含编辑器内 MCPModel Context Protocol层包可在init()中调用getMCPByDomain()暴露能力给 Angie 与 WebMCP。这与 PHP 端modules/mcp/的能力abilities是两套独立体系——本文示例文档特别标注了这一点这里注册的是插件自有包内的 in-editor MCP 工具不涉及 PHP MCP abilities。两条硬性规则必须遵守命名空间格式必须是/^[a-z_]$/即仅小写字母加下划线。示例中的my_feature符合规范my-feature之类的连字符命名不被接受Schema 类型addTool的schema字段是来自elementor/schema的Zod 对象而非纯 JSON Schema。运行时由 registry 将 Zod raw shape 转换为 JSON Schema 交给宿主。getMCPByDomain的完整语义可在 registering-editor-tools.md 中找到它返回/创建名为editor-{namespace}的领域服务器domain server可传入instructions给 Agent 的简短提示与docs领域完整文档。其中options.docs会自动注册elementor://{namespace}/server-docs资源并合并进工具的requiredResources——这正是示例中docs: Full domain documentation一行背后的机制。addTool的字段语义同样引自上述文档字段用途name暴露给宿主的工具名description面向 Agent 的工具描述schemaZod raw shape运行期转 JSON SchemaoutputSchema可选启用后自动附加errors字段isDestructive映射到destructiveHint标记破坏性操作requiredResources{ uri, description }[]会前置拼接到工具描述中handler异步(args) result抛错时宿主侧收到isError: true六、验证清单如何确认扩展生效示例文档以三条可观测结果收尾构成最小验证闭环包出现在编辑器网络请求中打开浏览器开发者工具过滤js/packages/应能看到你的包脚本被加载。注意 editor-loader.php 的命名规律是{assets_url}js/packages/{package}/{package}{min_suffix}.js例如js/packages/editor-my-feature/editor-my-feature.min.jsUI 渲染在指定槽位注入的组件应出现在所选区域——顶栏指示器出现在页面指示区切换按钮出现在工具菜单中可观察priority对排序的影响MCP 工具可见当 Angie / WebMCP 实验启用后my_tool应出现在 Agent 可用工具列表且elementId参数按 Zod schema 校验。七、源码级进阶从示例到生产实践的差异将示例与仓库真实代码对照还能提炼出三条生产级实践1. 用实验开关控制加载。site-navigation 模块在 env 中注入is_pages_panel_active供前端判断同时仅当实验激活时才注册 REST 字段。示例中enabled: true的写法可升级为Plugin::$instance-experiments-is_feature_active( ... )驱动的真实开关。2. 创建新包有完整流程。如果功能足够独立、需要新建包而非复用现有包参考 packages/docs/creating-a-new-package.md新建目录与package.json→ 编写源码 → 在 Demo 应用测试 → 在 Elementor 插件内联调 → 补单元测试 → 提 PR。加入插件的方式有两种直接写死在core/editor/loader/editor-loader.php的包列表始终加载或走过滤器条件加载、便于模块化封装。3. 基础库与扩展包分离。Editor_Loader::LIBS见 editor-loader.php维护了locations、store、schema、editor-v1-adapters等基础库EXTENSIONS维护默认扩展你的包通过elementor/editor/v2/packages追加后与基础库一起入队、按依赖图排序初始化。八、延伸阅读编辑器包扩展完整指南——本示例的上游详版文档含init()契约、elementor/locations位置表与更多代码示例编辑器包总览——包分类、生命周期与加载器内部实现注册编辑器内 MCP 工具——getMCPByDomain、addTool字段、适配器模式与命名空间规则的权威出处Site Navigation 模块真实实现——PHP 注册的最佳实践范本Editor Site Navigation 包 init 实现——init()中组合injectIntoPageIndication、toolsMenu.registerToggleAction与registerPanel的完整范例。【免费下载链接】elementorThe most advanced frontend drag drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.项目地址: https://gitcode.com/GitHub_Trending/el/elementor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。