资讯动态

CKEditor 5 Media Embed 配置实战:数据输出格式与媒体提供方的扩展、移除和重写

发布时间:2026/9/16 16:35:07 来源:尧图企业网站定制
CKEditor 5 Media Embed 配置实战数据输出格式与媒体提供方的扩展、移除和重写【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5本篇技术指南围绕 CKEditor 5 的MediaEmbed插件配置展开覆盖mediaEmbed配置对象中控制数据输出格式的核心参数previewsInData、elementName以及管理媒体提供方的三组配置providers、extraProviders、removeProviders。读完本文你将能够按需决定编辑器输出“语义化oembed标签”还是“带预览的 HTML”并能扩展、移除或完全重写默认支持的媒体提供方所有配置均结合当前仓库源码实现逐一对应可直接复制使用。MediaEmbed是一个“粘合”插件在 mediaembed.ts 中声明其依赖MediaEmbedEditing、MediaEmbedUI、AutoMediaEmbed和Widget四个插件。本文讨论的全部配置项都通过editor.config.define(mediaEmbed, ...)注入默认值定义在 mediaembedediting.ts 的构造函数中配置类型的完整声明见 mediaembedconfig.ts 中的MediaEmbedConfig接口。数据输出格式MediaEmbed支持两种数据输出格式通过config.mediaEmbed.previewsInData切换。需要注意该选项只影响输出数据不改变编辑器内部的显示方式——可预览的媒体在编辑器里始终显示预览来源media-embed-configuration.md 中的说明框。语义化数据输出默认默认情况下previewsInData为false无论媒体是否可预览输出的都是语义化的oembed url...标签figure classmedia oembed urlhttps://media-url/oembed /figure这种格式最适合以下两类场景应用在服务端对媒体进行解析展开或在前端直接渲染参见 media-embed-external-preview.md。它保留了最灵活的数据库表示——URL 被持久化具体展示逻辑交给消费端决定。用elementName自定义语义标签通过config.mediaEmbed.elementName可以覆盖默认的oembed标签名。例如设置为o-embedmediaEmbed: { elementName: o-embed }输出变为figure classmedia o-embed urlhttps://media-url/o-embed /figure默认值为oembed见 mediaembedconfig.ts 中elementName的 JSDoc 及default标注。一个容易忽略的向后兼容细节如果elementName被重写为非默认值旧的oembed元素仍然可以被识别和显示。从源码可以确认这一点——upcast数据到模型转换器同时匹配两个标签名见 mediaembedediting.ts// Upcast semantic media. .elementToElement( { view: element [ oembed, elementName ].includes( element.name ) element.getAttribute( url ) ? { name: true } : null, // ... } )因此即使切换到o-embed历史数据中的oembed也能被正常还原为模型中的media元素。在数据中包含预览previewsInData将mediaEmbed.previewsInData设为true后媒体将以与编辑器中完全一致的形式输出对于“可预览”媒体预览 HTML通常是iframe会被写入数据figure classmedia div>figure classmedia oembed urlhttps://media-url/oembed /figure源码中这一“分支决策”发生在Media.getViewElement()mediaregistry.ts当options.renderMediaPreview为真且该媒体带有html渲染函数时生成带data-oembed-url属性的div并写入预览 HTML否则生成一个带url属性的空元素即语义化标签标签名由elementName决定if ( options.renderForEditingView || ( options.renderMediaPreview this.url this._previewRenderer ) ) { // 生成 div>ClassicEditor .create( { // ... Other configuration options ... mediaEmbed: { extraProviders: [ { // 提供方名称例如用于 removeProviders 时引用 name: myProvider, // URL 正则或正则数组 url: /^example\.com\/media\/(\w)/, // 仅当媒体可预览时才需要定义 html: match ... } ] } } ) .then( /* ... */ ) .catch( /* ... */ );从源码结构看合并逻辑发生在MediaRegistry构造函数mediaregistry.tsconfig.providers.concat(config.extraProviders)之后再按removeProviders过滤即extraProviders总是排在默认提供方之后。配合“先到先得”的 URL 匹配规则见下文这意味着默认提供方对同一 URL 拥有更高优先级。移除媒体提供方removeProvidersconfig.mediaEmbed.removeProviders接受提供方名称数组从合并后的提供方列表中剔除指定提供方。官方文档给出的典型用例是只保留可预览的提供方ClassicEditor .create( { // ... Other configuration options ... mediaEmbed: { removeProviders: [ instagram, twitter, googleMaps, flickr, facebook ] } } ) .then( /* ... */ ) .catch( /* ... */ );实现上构造函数将removeProviders装入Set过滤掉name命中其中的提供方同时缺少name字段的提供方会被media-embed-no-provider-name警告丢弃且不生效mediaregistry.ts。这一点值得注意自定义提供方一定要写name否则既无法被引用也无法被移除。对应的测试用例见 tests/mediaembedediting.js 中#extraProviders与#removeProviders两个 describe 块含removeProviders同时作用于providers和extraProviders的验证以及 tests/mediaregistry.js 中注册表层面的扩展/移除测试。重写媒体提供方providers要完全接管提供方列表使用config.mediaEmbed.providers并按提供方语法定义你自己的集合——这会整体替换默认列表默认 9 个提供方全部失效ClassicEditor .create( { // ... Other configuration options ... mediaEmbed: { providers: [ { name: example, // URL 正则或正则数组 url: /^example\.com\/media\/(\w)/, // 仅当媒体可预览时才需要定义 html: match The HTML representing the media with ID${ match[ 1 ] }. } // ... 更多提供方 ] } } ) .then( /* ... */ ) .catch( /* ... */ );官方文档建议以仓库中的默认配置为模板即 mediaembedediting.ts) 中editor.config.define(mediaEmbed, ...)内的定义。提供方语法详解提供方是一个MediaEmbedProvider对象mediaembedconfig.ts包含三个字段name: string必填提供方名称removeProviders按此匹配url: RegExp | RegExp[]必填媒体 URL 的正则可以是单个正则或正则数组任一匹配即视为该提供方的媒体。RegExp.match()的完整结果数组会传入html渲染函数html?: ( match: RegExpMatchArray ) string可选渲染函数用于生成编辑视图与开启previewsInData时的数据输出中的预览 HTML。未定义时媒体以通用表示呈现数据输出恒为语义化标记。写url正则时不必包含协议http://、https://和www子域——匹配前它们会被剥离。源码中 MediaRegistry._getUrlMatches() 按三步尝试直接用原始 URL 匹配不剥离协议和www剥离协议后匹配url.replace( /^https?:\/\//, )再剥离www.子域后匹配。任意一步命中即返回匹配结果因此url: /^example\.com\/media\/(\w)/同时能覆盖https://www.example.com/...、http://example.com/...与裸example.com/...等形式。匹配优先级提供方按配置顺序处理第一个匹配该 URL 的提供方获胜URL 不会再与后续提供方比较该规则写在providers字段的 JSDoc 中mediaembedconfig.ts实现见 MediaRegistry._getMedia() 的线性循环。所以如果你想用“允许一切”的正则兜底必须把它放在最后{ name: allow-all, url: /^./ }响应式媒体写法MediaEmbedProvider的 JSDocmediaembedconfig.ts给出了一段可直接参考的html实现——外层用普通div包裹便于外部样式或选择器命中该容器内层iframe用 HTMLwidth/height属性提供固有尺寸、用 CSSwidth: 100%; height: auto; aspect-ratio: 16 / 9;实现随容器缩放并保持宽高比html: match div iframe src... width1280 height720 stylewidth: 100%; height: auto; aspect-ratio: 16 / 9; border: 0; display: block; frameborder0 allowfullscreen /iframe /div默认的 YouTube、Vimeo、Dailymotion 提供方正是采用这套 16:9 的响应式写法mediaembedediting.ts。配置如何驱动数据管线理解了配置项可以再看一眼它们在转换管线中的落点帮助排查“输出不是我想要的格式”这类问题实现均在 mediaembedediting.ts 的init()中数据下转模型 → 数据dataDowncast把模型media元素转换为figure classmedia包裹的结构是否渲染预览由renderMediaPreview: !!url renderMediaPreviewrenderMediaPreview即previewsInData配置值决定语义标签名由elementName决定编辑视图下转模型 → 视图同样调用createMediaFigureElement()utils.ts但强制renderForEditingView: true——可预览媒体渲染真实预览不可预览媒体渲染占位符图标 可点击的 URL 链接即文首截图所示样式URL 属性变更attribute:url:media的转换器converters.ts会在 URL 修改后整体重建figure内容因此粘贴新链接时预览/语义标记会即时切换upcast数据 → 模型两条路径分别还原语义化元素oembed或自定义elementName需带url属性与非语义化的div[data-oembed-url]且两种情况都会先经registry.hasMedia(url)校验 URL 是否仍被某个现存提供方匹配——这也是“移除提供方后旧媒体 URL 不再被识别”的根源。小结配置项作用默认值previewsInDatatrue时可预览媒体的输出包含预览 HTMLdiv[data-oembed-url]iframe不可预览媒体恒为语义化输出false语义化输出elementName语义化输出的标签名旧oembed标签保持兼容可读oembedproviders整体替换默认提供方列表9 个内置提供方extraProviders在默认列表之后追加提供方空removeProviders按名称从providersextraProviders合并结果中剔除空核心决策路径很简单想让数据库只存 URL、展示交给服务端或前端渲染就保持默认语义化输出想让存储的数据在网站上开箱即用就开启previewsInData并用removeProviders/providers把支持的 URL 限定在可预览范围内要接入自有视频或第三方内容平台则用extraProviders追加保留默认或providers重写完全接管并按“先到先得”的优先级安排正则顺序。【免费下载链接】ckeditor5Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.项目地址: https://gitcode.com/GitHub_Trending/ck/ckeditor5创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价