Draw.io
.drawio.svg 当普通图片放进页面,读者鼠标移上去就能点开 Draw.io 编辑器改图。Draw.io 集成没有围栏也没有 shortcode,用的是普通 Markdown 图片。Draw.io 导出时勾上「Include a copy of my diagram」,SVG 或 PNG 里会带一份 mxfile 源码;主题的运行时识别这份副本后,给图片加一个编辑按钮。适合需要读者取走修改的图;只用于展示的图按普通图片处理。
最简例子
写法与普通图片相同,文件名不受限制,.drawio.svg 只是惯例。
这张图嵌着一份 mxfile 副本,因此被包进了 .drawio 容器。鼠标移到图上时,右下角出现一个铅笔按钮;点击后在当前页面盖一层全屏 iframe,加载站点配置的编辑器。
副本检测
运行时的判断依据只有一条:文件内容里有没有 mxfile 字样,与文件名无关。下面这张同样是 SVG、同样是块级图片,但它是手写的,没有副本,也就没有按钮。
带图注
Draw.io 图片走的是普通图片渲染钩子,图片的属性照常可用。加 caption 得到带图注的 figure,编辑按钮仍然出现在图上。
编号成书里的图
加 {#id num=…} 得到一张可交叉引用的编号图,与别的图片一样能被 xref 引用、进入图目录。
编号与交叉引用的完整规则见书籍出版。
SVG 还是 PNG
两种都识别。Draw.io 导出 PNG 时同样能带上副本,存在 PNG 的文本块里,运行时的判断逻辑相同。

文档里优先用 SVG:缩放不失真,文字是真实文本(可被搜索、可被读屏器读取),改动的 diff 也读得懂。图特别复杂、或目标平台不支持 SVG 时用 PNG。只有 PNG 能走 Hugo 的图片处理;SVG 上的处理操作会告警并保留原图,严格构建会拒绝该告警。
编辑流程
按钮依次做三件事。
盖一层遮罩
页面上插入一个全屏的 div.drawioframe,里面是一个 iframe,地址是配置的 drawio_server 加上一串固定参数(embed=1&ui=atlas&proto=json&saveAndEdit=1&noSaveBtn=1)。
把图送进编辑器
编辑器就绪后,运行时把这张图片的内容(含 mxfile 副本)作为 data URL 发进 iframe。这一步不经过你的服务器。
保存与回写
在编辑器里点保存,运行时让编辑器按原格式(SVG 或 PNG)导出,由浏览器下载成同名文件。运行时不写回仓库:把下载到的文件覆盖 content/ 里那一份,再自行提交。
编辑按钮供读者取走图去改,不是站点的在线编辑功能。
编辑器地址
enable: true却没写drawio_server时会告警并关闭编辑;严格构建会因该告警失败。主题不代替站点选择公共服务。- 编辑过程必须留在组织内部时,部署一份自托管编辑器,把地址指向它。
- 公共端点
https://embed.diagrams.net/可用,读者的图会进入第三方页面。
这两个键的完整定义在配置总览。
输出形态
| 输出 | 呈现 |
|---|---|
| HTML | 普通 <img>(或 <figure>);启用后运行时把带副本的图包进 <div class="drawio"> 并加按钮 |
| 打印 | 图片照常打印;按钮默认隐藏(只在悬停时出现),打印上不会有它 |
| Markdown | 普通 Markdown 图片语法 |
| RSS | 普通 <img>,绝对 URL,没有按钮 |
图片本身在四态里都在,编辑按钮是增量能力。
参数参考
没有专属的围栏或 shortcode 参数。图片属性行沿用图片那一套(caption width height link #id num command options)。
站点参数(hugo.yml):
限制与常见问题
- 运行时只在渲染内容含
.svg或.png候选图的页面加载;同一 URL 的图片合并检查,只读取一次以查找mxfile。 - 导出时忘了勾「Include a copy of my diagram」,图就只是一张图,没有按钮。
- 编辑依赖编辑器,且不写回仓库:离线环境里图片正常显示,按钮点了没有反应;编辑器保存等于浏览器下载,替换文件与提交都要手动做。
- 按钮只在悬停时出现:触屏设备上没有 hover,读者不容易发现它,不要把可编辑当成关键功能来讲。
- 配色不跟随深浅色:导出的 SVG 颜色是固定的;把填充设成
none、线条与文字用中性灰,两种模式下都能看(本页这两张图就是这么做的)。