15120086569

网站建设 APP开发 小程序开发

KNOWLEDGE/知识

分享你我感悟

您当前位置> 首页 > 知识 > APP开发

EyouCMS从百度UEditor更换为Markdown MrEditor编辑器教程

发表时间:2026-05-15 22:35:07

文章作者:小编

浏览次数:

一、为什么要替换UEditor

EyouCMS默认使用百度UEditor作为富文本编辑器。UEditor功能强大,但存在以下问题:

  • 停止维护:百度UEditor已多年未更新,存在安全隐患
  • 体积庞大:UEditor完整包超过5MB,影响后台加载速度
  • 排版困难:富文本编辑容易产生冗余HTML标签,排版不一致
  • 代码不友好:插入代码块体验差,无语法高亮

MrEditor 是一款基于 CodeMirror 6 的现代 Markdown 编辑器,具备以下优势:

  • 左右分栏实时预览,所见即所得
  • 原生 Markdown 语法,排版干净整洁
  • 代码块语法高亮,支持多种编程语言
  • 支持数学公式、Mermaid 流程图
  • 轻量级,加载速度快
  • 粘贴图片自动上传

二、准备工作

2.1 所需文件

需要准备以下插件文件:

文件

用途

存放路径

mreditor.js

MrEditor 编辑器核心

/public/plugins/mr-editor/

mreditor.css

编辑器样式

/public/plugins/mr-editor/

global.css

全局样式

/public/plugins/mr-editor/

marked.min.js

Markdown→HTML 解析器

/public/plugins/mr-marked/

marked.css

渲染样式

/public/plugins/mr-marked/

turndown.min.js

HTML→Markdown 转换器

/public/plugins/turndown/

mreditor_helper.js

桥接层(核心)

/public/static/admin/js/

2.2 MrEditor 来源

MrEditor 来自 MrDoc(觅思文档)项目,是一个基于 Svelte + CodeMirror 6 构建的 Markdown 编辑器。

marked.js 用于将 Markdown 转为 HTML(保存到数据库),turndown.js 用于将 HTML 转回 Markdown(从数据库加载时)。

三、核心实现:桥接层 mreditor_helper.js

这是整个替换方案的核心文件。EyouCMS 的内容管理流程是:

数据库存储 HTML → 编辑器加载 HTML → 编辑器输出 HTML → 保存到数据库

而 MrEditor 操作的是 Markdown,所以需要一个桥接层来做格式转换:

加载时:HTML(数据库) → turndown → Markdown(编辑器)
保存时:Markdown(编辑器) → marked → HTML(数据库)

3.1 桥接层核心结构

var MrEditorHelper = {
    _instances: {},   // MrEditor 实例
    _textareas: {},   // 原始 textarea 引用
    _wrappers: {},    // 编辑器容器 DOM

    // 创建编辑器实例
    create: function(id, options) { ... },

    // 获取 HTML 内容(MD→HTML)
    getContent: function(id) { ... },

    // 设置 HTML 内容(HTML→MD)
    setContent: function(id, html) { ... },

    // 在光标处插入内容
    insertHtml: function(id, html) { ... },

    // 同步内容到原始 textarea
    sync: function(id) { ... },

    // HTML→MD 转换
    _htmlToMd: function(html) { ... },

    // MD→HTML 转换
    _mdToHtml: function(md) { ... },

    // 清理渲染器产生的装饰元素
    _cleanHtml: function(html) { ... },

    // 粘贴图片上传
    _bindPasteUpload: function(id, wrapper, uploadUrl) { ... }
};

3.2 API 兼容设计

桥接层提供了与 UEditor / Vditor 兼容的 API 接口:

方法

说明

MrEditorHelper.create(id, opts)

替代 UE.getEditor(id)

MrEditorHelper.getContent(id)

替代 UE.getEditor(id).getContent()

MrEditorHelper.setContent(id, html)

替代 UE.getEditor(id).setContent(html)

MrEditorHelper.insertHtml(id, html)

替代 UE.getEditor(id).execCommand('insertHtml', html)

MrEditorHelper.sync(id)

表单提交前同步内容

3.3 HTML 清洗机制

marked.js 渲染 Markdown 时会给代码块添加工具栏(复制按钮、语言标签等装饰元素)。如果这些装饰元素被保存到数据库,下次加载时会变成多余的文本。

桥接层内置了 _cleanHtml() 方法,在加载和保存时自动清理:

  • 移除 .markdown-code-toolbar(代码块工具栏)
  • 解包 .markdown-code 容器,只保留 <pre><code>
  • 移除标题中的重复锚点链接
  • 清理工具栏文本残留(如孤立的"复制"段落)

四、模板文件修改

4.1 引入资源文件

在后台模板文件(如 edit.htmadd.htm)的头部,替换原有 UEditor 引用:

<!-- 移除 UEditor 引用 -->
<!-- {load href="__PUBLIC__/plugins/ueditor/...} -->

<!-- 添加 MrEditor 引用 -->
{load href="__PUBLIC__/plugins/mr-marked/marked.min.js" /}
{load href="__PUBLIC__/plugins/turndown/turndown.min.js" /}
{load href="__PUBLIC__/plugins/mr-editor/mreditor.js" /}
{load href="__PUBLIC__/plugins/mr-editor/global.css" /}
{load href="__PUBLIC__/plugins/mr-marked/marked.css" /}
{load href="__PUBLIC__/plugins/mr-editor/mreditor.css" /}
{load href="__STATIC__/admin/js/mreditor_helper.js" /}

4.2 初始化编辑器

将原有 UEditor 初始化代码替换为:

MrEditorHelper.create('addonFieldExt_content', {
    serverUrl: "{:url('Ueditor/index',array('savepath'=>'allimg'))}",
    height: 450,
    toolbars: mreditor_toolbars
});

4.3 需要修改的模板文件

EyouCMS 中涉及编辑器的模板文件较多,需要逐一替换:

模板文件

说明

article/edit.htm

文章编辑页

article/add.htm

文章新增页

article/free_content.htm

自定义内容弹窗

archives/get_field_addonextitem.htm

扩展字段编辑器

field/modelfield.htm

模型字段设置

field/addonitem.htm

附加字段项

other/edit.htmother/add.htm

其他内容编辑

五、关键问题与修复

5.1 按钮触发表单提交

问题:MrEditor 工具栏按钮是 <button> 标签,HTML 规范中 <form> 内的 <button> 默认为 type="submit",点击会触发表单提交。

解决:在桥接层中使用 MutationObserver 监听所有 button 元素,自动设置 type="button"

function fixButtonType(btn) {
    if (!btn.getAttribute('type') || btn.getAttribute('type') === 'submit') {
        btn.setAttribute('type', 'button');
    }
}
// 初始修复 + MutationObserver 监听动态按钮
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(m) {
        m.addedNodes.forEach(function(node) {
            if (node.nodeType !== 1) return;
            if (node.tagName === 'BUTTON') fixButtonType(node);
            var inner = node.querySelectorAll ? node.querySelectorAll('button') : [];
            for (var n = 0; n < inner.length; n++) fixButtonType(inner[n]);
        });
    });
});
observer.observe(wrapper, { childList: true, subtree: true });

5.2 下拉菜单 tooltip 显示 undefined

问题:MrEditor 下拉类按钮(字体、引用提示块、公式等)没有设置 data-tippy-content 属性,鼠标悬停显示 "undefined"。

解决:延迟等待 tippy 实例挂载完成后,手动设置中文名称:

var dropdownTitles = {
    'font': '字体', 'quote-tips': '引用提示块',
    'formula': '公式', 'graph': '图表', 'mermaid': 'Mermaid 图表'
};
function fixDropdownTippy(retries) {
    var dropdowns = wrapper.querySelectorAll('.toolbar-item-tippy-dropdown');
    // ... 延迟重试修复
}
setTimeout(function() { fixDropdownTippy(10); }, 300);

5.3 PC端/手机端切换不同步

问题:EyouCMS 的 contentSwitch() 通过 jQuery show/hide 切换 PC端/手机端 textarea,但 MrEditor wrapper 是 textarea 的兄弟节点,不受影响。

解决:拦截 contentSwitch() 函数,同步操作 MrEditor wrapper 的显示/隐藏。

5.4 粘贴图片上传

解决:在 .cm-content 元素上监听 paste 事件,检测剪贴板中的图片文件,通过 FormData + AJAX 上传到服务器,上传成功后插入 Markdown 图片语法:

editorEl.addEventListener('paste', function(ev) {
    // 检测图片 → FormData 上传 → 插入 ![](url)
}, true);

六、前端显示适配

数据库中存储的是 HTML,前端模板直接输出即可,无需额外处理。但需要为代码块添加 CSS 样式:

/* 文章内容区代码块样式 */
.case_info .text pre {
    background: #f6f6f6;
    padding: 10px;
    overflow: auto;
    border-radius: 3px;
    margin: 16px 0;
}
.case_info .text pre code {
    background: transparent;
    color: #24292e;
    font-size: 0.85em;
    line-height: 1.6;
    font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}
/* 正文排版 */
.case_info .text {
    font-size: 16px;
    line-height: 1.75;
}
.case_info .text p {
    margin: 12px 0;
}
.case_info .text img {
    display: block;
    margin: 20px 0;
    max-width: 100%;
    height: auto;
}

七、效果展示

替换完成后,后台编辑器界面如下:

MrEditor编辑器界面

左侧为 Markdown 源码编辑区,右侧为实时预览区。支持工具栏快捷操作、代码高亮、图片粘贴上传等功能。

代码块预览效果

八、总结

对比项

UEditor

MrEditor

维护状态

已停更

活跃维护

文件体积

5MB+

< 1MB

编辑模式

富文本 WYSIWYG

Markdown 分栏预览

代码块

无语法高亮

CodeMirror 6 高亮

排版一致性

易产生冗余标签

Markdown 语法干净

图片上传

内置复杂上传组件

粘贴即上传

扩展性

插件体系复杂

轻量可定制

通过桥接层设计,实现了零侵入替换——不需要修改 EyouCMS 核心代码,只需替换模板文件中的编辑器引用,所有内容管理流程(新增、编辑、保存、前端展示)完全兼容。


相关案例查看更多