How to enable MediaWiki to generate perfect mindmaps

From 清冽之泉
Revision as of 16:19, 22 September 2025 by Mwroot (talk | contribs)
Jump to navigation Jump to search

外部

不论采用外部哪个思维导图,生成的图,都得多一个上传的过程,烦不胜烦,所以只有从 MediaWiki 内部解决。

Diagrams

MediaWiki 的 Diagrams 拓展,提供了四种能力:<graphviz>, <mscgen>, <uml>, and <mermaid>。

<graphviz> 可谓理科思维导图。默认样式几乎没有。要定义节点,给节点连线,非常繁琐,只适合少图精调,不适合批量多图。

<mscgen> 我尚未用过。

<uml> 是我的最终方案。

<mermaid> 可谓文科思维导图。默认样式漂亮。要定义节点,给节点连线,非常繁琐,只适合少图精调,不适合批量多图。

Diagrams 里的 mermaid,目前版本为 9.1.x,太老旧了,没有 mindmap 直接写节点的能力。于是我尝试单独的 Mermaid 拓展。

但最终发现,单独的 Mermaid 拓展,虽然 mermaid 版本较新,但也没支持 mindmap 直接写节点的能力。

<uml>

中文乱码

用 Diagrams 的 <uml> 能力生图,发现中文是乱码。网上有人叫在 <uml> 内部设置中文字体,测了一会儿字体,改了一会儿字体名,均无效。

用下面的命令可以查看 <uml> 支持的字体。

@startuml
listfonts
@enduml

后来发现原因在于,Diagrams 调用 plantuml 时,没有继承到正确的 charset 设置,ChatGPT 多次提醒我改变 plantuml 的环境参数,我不知如何下手,我以为要动 Diagrams 的源码。

ChatGPT 又建议我做一个 plantuml-wrapper,把 plantuml 的二进制文件包裹一层环境参数,看着也挺麻烦,既要新建 plantuml-wrapper,又要改权限,还要同时去 LocalSettings.php 更改设置,我认为流程过于繁琐,不利于未来维护,于是放弃用 wrapper。

经过坚持不懈地翻找,我终于找到 plantuml 官方,里面有提到 utf-8 相关设置,而且我把 Diagrams 拓展的文档界面 发给 ChatGPT,叫它找找线索。细心的 ChatGPT 明确说,在 Diagrams 拓展的文档界面,明确可以自定义 plantuml 的本地环境参数。这并不是对 Diagrams 源码的入侵,而是官方提供的接口,我终于细心看了一下文档,才发现在文档底部明确写着可以自定义本地环境参数。终于,在 LocalSettings.php 里自定义一下 utf-8 就解决了中文乱码的问题。

$wgDiagramsLocalCommands = [
    'plantuml' => '/usr/bin/java -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Dplantuml.include.path="/path/to/wiki/extensions/Diagrams/styles" -jar /usr/share/plantuml/plantuml.jar',
];

样式复用

解决了中文乱码问题,好不容易调试出了一个文科思维导图,界面非常优美,又遇到了每次生图都需要带同样的样式参数的问题,于是查找到 plantuml 具体 !include 的能力,于是引入,但发现总是在 !include 行报错。

plantuml 官网明晃晃写着支持 !include,但是却不生效。ChatGPT 教了一个巨有用的调试技巧,用 www-data 用户查看文本内容,看是否存在权限问题:

sudo -u www-data cat styles/light.puml

如果能查看内容,证明权限无误。如果不能查看内容,证明权限有误。

测试 ChatGPT 建议的,用 !includeurl https://xxxx/light.puml 引入,直接杜绝了权限问题,发现立即可以实现想要的效果了,于是可以推出不是 Diagrams 不支持 !include,而是用路径引用时,权限有问题。

  1. 路径必须是 plantuml 能找到的路径,所以在 LocalSettings.php 里加入路径变量,能解决路径问题
  2. 权限必须是 750 文件夹内的 640 文件,若文件夹限缩至 640 则 light.puml 无法被访问

#tag

{{#tag:tagname
|content
|attribute1=value1
|attribute2=value2
}}

在解决了 uml 中文乱码、 样式复用的问题后,就想用模板解决重复输入的问题。但发现,uml 一见到 {{{1}}} 模板参数就报错,原因在于 <uml> 标签无法先展开参数、再渲染生图。核心就是怎么样让 {{{1}}} 参数先展开,再交给 <uml> 处理,而 #tag 解释器刚好解决了这个问题。

最终模板如下:

<!-- Template:Swdt -->
<includeonly>{{#tag:uml
|@startmindmap
!include light.puml

{{{1}}}
@endmindmap
|format=svg}}</includeonly>
<noinclude>
“思维导图”模板用法:
{{Swdt|
* ChatGPT
** 冷静
*** 耐心
*** 强大
** 博学

}}
</noinclude>