简介
本文件面向 DouPHP 后台管理系统的富文本编辑器集成,覆盖 UEditor 与 Vditor 两种编辑器的配置、使用、工具栏定制、插件扩展、图片上传与视频插入、数据同步、格式转换、内容存储与版本管理、安全机制(内容过滤、脚本拦截、恶意代码检测)、性能优化与移动端适配等主题。文档基于仓库中的实际实现进行说明,并提供可追溯的源码路径与图示,便于开发者快速定位与二次开发。
更新 系统现已支持智能Markdown渲染逻辑,根据编辑器类型自动处理内容格式,确保UEditor返回HTML而Vditor返回Markdown源码的安全处理方式。
项目结构
编辑器相关资源集中在 admin/editor 目录下,包含 UEditor 与 Vditor 两套实现;模板通过统一入口 inc/editor.tpl 根据系统配置动态加载对应编辑器资源并渲染编辑区域;业务页面通过 include 引入该模板以启用编辑器功能。后端通过 MarkdownRenderer 服务提供智能内容渲染能力。
graph TB
subgraph "后台视图"
TPL["inc/editor.tpl"]
P1["support.htm"]
P2["download.htm"]
P3["video.htm"]
end
subgraph "编辑器资源"
UE_CFG["ueditor.config.js"]
UE_INIT["ueditor/init.js"]
VD_INIT["vditor/init.js"]
end
subgraph "后端能力"
FC["FileController.php"]
RT["route/file.php"]
CUH["ChunkedUploadHandler.php"]
MR["MarkdownRenderer.php"]
UT["Util.php"]
end
P1 --> TPL
P2 --> TPL
P3 --> TPL
TPL --> UE_CFG
TPL --> UE_INIT
TPL --> VD_INIT
TPL --> FC
FC --> RT
FC --> CUH
MR --> UT
核心组件
- 统一模板入口:inc.editor.tpl 负责根据系统配置选择加载 UEditor 或 Vditor 的资源,提供统一的"插入图片/媒体"、"全屏"、"切换编辑器"等能力。
- UEditor 配置与初始化:ueditor.config.js 定义工具栏、XSS 白名单与安全过滤;init.js 负责实例化、高度自适应与全屏逻辑。
- Vditor 配置与初始化:init.js 提供 Markdown/WYSIWYG 模式、工具栏、输入同步、缓存控制、全屏与回车提交行为。
- 智能Markdown渲染器:MarkdownRenderer 服务根据编辑器类型和内容环境智能处理内容格式,确保数据安全性和兼容性。
- Markdown语法检测:Util::containsMarkdownSyntax 方法提供精确的Markdown语法特征识别。
- 文件上传与附件处理:FileController 与路由 file.php 提供上传接口;ChunkedUploadHandler 支持分块上传与草稿态暂存。
架构总览
编辑器在前端由模板统一注入,根据配置决定使用 UEditor 或 Vditor;在需要时调用后端文件上传接口完成图片/媒体插入;内容保存时通过表单字段将 HTML 或 Markdown 提交至后端,再由模型层持久化。后端通过 MarkdownRenderer 服务提供智能内容渲染,根据编辑器类型和环境自动处理内容格式。
sequenceDiagram
participant 页面 as "业务页面"
participant 模板 as "inc/editor.tpl"
participant 前端 as "UE/Vditor"
participant 渲染器 as "MarkdownRenderer"
participant 后端 as "FileController + 路由"
participant 存储 as "ChunkedUploadHandler"
页面->>模板 : 引入编辑器模板
模板->>前端 : 加载对应编辑器资源并初始化
前端->>后端 : 触发图片/媒体上传
后端->>存储 : 分块/草稿写入与落盘
存储-->>后端 : 返回资源URL
后端-->>前端 : 返回JSON结果
前端->>前端 : 插入图片/媒体到编辑器内容
页面->>渲染器 : 请求内容渲染
渲染器->>渲染器 : 智能判断编辑器类型和环境
渲染器-->>页面 : 返回处理后的内容
详细组件分析
智能Markdown渲染器
新增 系统引入了专门的 MarkdownRenderer 服务来处理不同编辑器类型的智能内容渲染。
- 编辑器类型检测:通过 Config::get('site.editor') 判断当前使用的编辑器类型
- UEditor处理:直接返回原始HTML内容,不进行任何转换,避免误判HTML标签为Markdown语法
- Vditor处理:在管理后台返回Markdown源码,在前台使用Parsedown安全模式渲染HTML
- 安全模式:使用 Parsedown 的 safe mode 转义内联HTML并过滤危险链接协议如 javascript:
- 语法检测:仅在检测到Markdown语法时才进行渲染,提升性能
flowchart TD
A["接收内容"] --> B{"检查编辑器类型"}
B -- UEditor --> C["直接返回HTML"]
B -- Vditor --> D{"检查是否后台环境"}
D -- 是 --> E["返回Markdown源码"]
D -- 否 --> F{"检测Markdown语法"}
F -- 有语法 --> G["Parsedown安全模式渲染"]
F -- 无语法 --> H["原样返回"]
G --> I["返回HTML"]
E --> J["返回Markdown"]
C --> K["返回HTML"]
H --> L["返回原文"]
Markdown语法检测机制
新增 Util::containsMarkdownSyntax 方法提供了精确的Markdown语法特征识别功能。
- 正则表达式匹配:支持标题、代码块、引用、列表、表格、链接、图片、强调、删除线、行内代码、脚注等Markdown语法
- 空内容处理:对空字符串直接返回false,避免不必要的处理
- 性能优化:使用预编译的正则表达式数组,提高匹配效率
- 全面覆盖:涵盖所有常见Markdown语法特征,确保检测准确性
UEditor 集成与配置
- 工具栏定制:通过 ueditor.config.js 的 toolbars 配置项定义按钮集合,可按需裁剪或扩展。
- 安全过滤:开启 xssFilterRules、inputXssFilter、outputXssFilter,并通过 whitList 精确控制允许标签与属性,防止 XSS 注入。
- 初始化与交互:init.js 中通过 UE.getEditor 创建实例,监听 ready 事件设置高度;提供 btnFullscreen 与 resizeEditor 实现全屏与自适应。
- 图片/视频插入:模板提供"插入图片/媒体"按钮,点击后调用后端上传接口,成功后将资源 URL 插入编辑器。
- 内容处理:UEditor 站点的内容始终作为HTML处理,不进行Markdown转换,确保内容完整性。
flowchart TD
A["页面加载"] --> B["加载 ueditor.config.js"]
B --> C["加载 init.js"]
C --> D["实例化编辑器"]
D --> E{"是否全屏?"}
E -- 是 --> F["计算可用高度并设置"]
E -- 否 --> G["保持默认高度"]
D --> H["绑定就绪事件设置高度"]
D --> I["插入图片/媒体流程"]
I --> J["UEditor直接返回HTML内容"]
Vditor 集成与配置
- 模式与工具栏:init.js 中通过 toolbar 数组配置常用 Markdown 与 WYSIWYG 工具;mode 设置为 wysiwyg 以获得所见即所得体验。
- 内容同步:after 回调用于将已有内容转换为 Markdown(当检测到非 Markdown 时),input 回调将编辑器内容实时同步到隐藏 textarea,便于表单提交。
- 缓存控制:cache.enable=false 避免本地缓存干扰;cache.id 指定唯一标识。
- 交互增强:支持 ESC 退出全屏;回车键阻止冒泡并触发表单提交;自动检测 Markdown 语法以决定是否转换。
- 内容处理:Vditor 在管理后台返回Markdown源码,在前台通过MarkdownRenderer进行安全渲染。
sequenceDiagram
participant 页面 as "业务页面"
participant 模板 as "inc/editor.tpl"
participant V as "Vditor"
participant 渲染器 as "MarkdownRenderer"
participant 后端 as "FileController + 路由"
页面->>模板 : 引入编辑器模板
模板->>V : 初始化并传入工具栏与CDN
V->>V : after 回调检测并转换内容
V->>V : input 回调同步到Textarea
V->>后端 : 上传图片/媒体
后端-->>V : 返回资源URL
V->>V : 插入媒体到内容
页面->>渲染器 : 前台渲染Markdown内容
渲染器-->>页面 : 返回安全的HTML
编辑器与业务页面的集成
- 模板复用:各业务页面(如 support.htm、download.htm、video.htm)通过 {include file="inc/editor.tpl" name="content" value="$item_content"} 引入编辑器,name 作为字段名,value 为初始内容。
- 字段命名:编辑器最终会生成隐藏的 textarea 或 script 节点,其 name 与模板参数一致,便于表单提交。
- 模块差异:不同模块可在模板层传递不同变量(如 $paid_use、$cur、$item_id、$draft_token)以实现差异化行为(例如付费内容分隔线、草稿令牌)。
图片上传与视频插入
- 前端入口:editor.tpl 提供"插入图片"和"插入媒体"按钮,分别调用 fileBox 与 fileBig 函数,传入 cur、item_id、draft_token 与当前编辑器类型。
- 后端处理:FileController 与 route/file.php 提供上传接口;ChunkedUploadHandler 支持分块上传与草稿态暂存(含 uploader_type/uploader_id/token/expire),确保大文件稳定上传。
- 结果回写:上传成功后,前端将返回的资源 URL 插入编辑器内容,形成图片/视频嵌入。
sequenceDiagram
participant 用户 as "管理员"
participant 编辑器 as "UE/Vditor"
participant 模板 as "editor.tpl"
participant 控制器 as "FileController"
participant 处理器 as "ChunkedUploadHandler"
用户->>编辑器 : 点击"插入图片/媒体"
编辑器->>模板 : 调用 fileBox/fileBig
模板->>控制器 : 发起上传请求(含 draft_token)
控制器->>处理器 : 分块/草稿写入
处理器-->>控制器 : 返回资源URL
控制器-->>编辑器 : JSON响应
编辑器->>编辑器 : 插入图片/视频到内容
数据同步、格式转换、内容存储与版本管理
- 数据同步:
- UEditor:通过 script 节点承载内容,提交时由框架读取对应 name 的值。
- Vditor:通过 input 回调将内容同步到隐藏 textarea,确保表单提交携带最新内容。
- 智能格式转换:
- UEditor:内容始终作为HTML处理,不进行任何转换。
- Vditor:后台返回Markdown源码,前台通过MarkdownRenderer进行安全渲染。
- 内容存储:
- 业务表字段通常为 content 或 item_content,由模板 value 传入初始值,提交后由后端服务层持久化。
- 版本管理:
- 草稿态:上传阶段支持 draft token 暂存,业务表写入后再认领,减少中间状态风险。
- 建议:对重要内容(如文章、下载页描述)增加版本字段或变更日志,便于回溯。
安全机制(内容过滤、脚本拦截、恶意代码检测)
- UEditor 安全:
- 开启 xssFilterRules、inputXssFilter、outputXssFilter。
- 通过 whitList 精确控制允许的标签与属性,限制危险元素与事件。
- Vditor 安全:
- 输出内容经 MarkdownRenderer 的 Parsedown safe mode 处理,过滤危险链接协议。
- 后台编辑表单直接返回Markdown源码,避免HTML注入风险。
- MarkdownRenderer 安全:
- 使用 Parsedown 的 setSafeMode(true) 转义内联HTML。
- 仅在有Markdown语法时才进行渲染,提升性能和安全性。
- 通用建议:
- 对所有富文本内容进行服务端二次过滤。
- 限制可插入的媒体类型与大小,避免恶意文件。
- 对远程图片抓取进行域名白名单与协议限制。
开发示例(配置选项、自定义按钮、事件与回调)
- 配置编辑器选项:
- UEditor:在 ueditor.config.js 中调整 toolbars、whitList、autoHeightEnabled 等。
- Vditor:在 vditor init.js 中调整 toolbar、mode、height、cdn、cache 等。
- 自定义工具按钮:
- UEditor:通过 toolbars 添加自定义命令或扩展插件。
- Vditor:通过 toolbar 数组添加自定义按钮,并在 after 回调中注册事件。
- 处理编辑器事件与回调:
- UEditor:监听 ready 事件设置高度;使用 getContent/getHTML 获取内容。
- Vditor:使用 input 回调同步内容;after 回调进行格式转换;fullscreen 事件配合 UI 控制。
- 使用MarkdownRenderer:
- 在服务类中注入 MarkdownRenderer 依赖。
- 调用 toHtml() 方法进行智能内容渲染。
- 根据编辑器类型和环境自动处理内容格式。
移动端适配方案
- 高度自适应:UEditor 在 ready 事件中设置高度;Vditor 通过 height='100%' 填满父容器。
- 全屏体验:两者均提供全屏切换,ESC 退出;注意 body overflow 控制与模态框样式。
- 交互优化:Vditor 阻止回车冒泡并触发表单提交,提升移动端操作效率。
- 建议:在小屏设备上精简工具栏,仅保留必要按钮;对图片/视频插入提供预览与尺寸控制。
依赖关系分析
- 模板依赖:editor.tpl 依赖系统配置 site.editor 决定加载 UEditor 或 Vditor 资源。
- 编辑器依赖:
- UEditor:依赖 ueditor.config.js 与 ueditor.all.js;init.js 负责实例化与交互。
- Vditor:依赖 dist/index.js/css 与 init.js;CDN 路径通过 admin_url/editor/vditor 配置。
- 后端依赖:
- FileController 与 route/file.php 提供上传接口。
- ChunkedUploadHandler 提供分块与草稿态处理能力。
- MarkdownRenderer 依赖 Util::containsMarkdownSyntax 进行语法检测。
graph LR
TPL["editor.tpl"] --> UE_CFG["ueditor.config.js"]
TPL --> UE_INIT["ueditor/init.js"]
TPL --> VD_INIT["vditor/init.js"]
UE_INIT --> UE_ALL["ueditor.all.js"]
VD_INIT --> VD_DIST["vditor/dist/index.js"]
TPL --> FC["FileController.php"]
FC --> RT["route/file.php"]
FC --> CUH["ChunkedUploadHandler.php"]
MR["MarkdownRenderer.php"] --> UT["Util.php"]
性能考虑
- 资源加载:按需加载编辑器资源,避免全局引入;Vditor 使用 CDN 加速静态资源。
- 高度计算:UEditor 在 ready 事件中计算高度,减少重排;全屏模式下动态计算可用高度。
- 内容转换:Vditor 仅在 after 时进行一次性转换,避免频繁重算。
- 智能渲染优化:MarkdownRenderer 仅在检测到Markdown语法时才进行渲染,避免不必要的Parsedown处理。
- 语法检测优化:Util::containsMarkdownSyntax 使用预编译的正则表达式数组,提高匹配效率。
- 上传优化:使用分块上传与草稿态暂存,降低大文件失败率;限制文件类型与大小。
- 缓存策略:Vditor 禁用本地缓存以避免不一致;必要时可启用按实例 ID 的缓存。
故障排查指南
- 编辑器未显示:检查 editor.tpl 是否正确加载对应资源;确认 site.editor 配置与路径正确。
- 图片无法插入:确认 FileController 与 route/file.php 已配置;检查上传权限与磁盘空间;验证 draft_token 有效性。
- 内容未同步:Vditor 需确保 input 回调生效;UEditor 需确认表单 name 与模板参数一致。
- Markdown渲染异常:检查 MarkdownRenderer 是否正确注入;确认 Util::containsMarkdownSyntax 正常工作;验证 Parsedown 库可用性。
- 内容格式错误:确认编辑器类型配置正确;检查 IS_ADMIN 常量定义;验证内容是否包含Markdown语法。
- 安全报错:检查 UEditor 的 whitList 是否包含所需标签与属性;必要时在后端二次过滤。
- 全屏异常:确认 ESC 事件与 body overflow 控制逻辑;检查模态框样式类名。
结论
DouPHP 后台管理系统通过统一的模板入口集成了 UEditor 与 Vditor 两种编辑器,并新增了智能Markdown渲染逻辑,提供了丰富的工具栏定制、图片/媒体插入、安全过滤与性能优化能力。新的 MarkdownRenderer 服务能够根据编辑器类型和环境智能处理内容格式,确保UEditor返回HTML而Vditor返回Markdown源码的安全处理方式。开发者可根据业务需求选择合适的编辑器,并结合后端上传与存储能力实现完整的内容创作与发布流程。建议在关键场景下加强内容清洗、版本管理与监控告警,以提升系统的安全性与稳定性。
附录
- 语言提示:文档模块强制要求使用 Vditor 编辑器,可通过设置进行调整。
- 参考路径:各业务页面通过 include editor.tpl 接入编辑器,字段名与初始内容由模板参数控制。
- 新增功能:MarkdownRenderer 服务已在多个业务模块中使用,包括文章、案例、课程、下载等内容的智能渲染。