Otter Wiki 2.26.1 常用命令与页面语法详解

Otter Wiki 2.26.1 日常操作抓手详解:flask user 账户管理 CLI 逐条实测、宿主机 git 数据面运维(log/show/diff/blame)、GIT_WEB_SERVER 克隆推送闭环、版本回滚双路径与页面嵌入扩展语法要点。

Otter WikiOtter WikiWiki2026/10/30

Otter Wiki 2.26.1 常用命令与页面语法详解

目标:把 Otter Wiki 2.26.1 的日常操作抓手一次练全——容器内 flask user 账户管理 CLI 逐条实测、宿主机直接读 git 版本库的运维命令(log/show/diff/blame)、GIT_WEB_SERVER 开启后的 git 克隆/推送闭环、版本回滚的双路径(git revert 与界面 revert),以及页面内嵌与扩展语法要点。全部命令与回显已在下述环境逐条实测通过。

一、环境信息

  • 操作系统:Ubuntu 26.04.1 LTS(x86_64,内核 7.0.0-38-generic)
  • Docker 29.9.2 / Docker Compose v5.6.1;宿主机 git 2.53.0
  • Otter Wiki:2.26.1(官方镜像 redimp/otterwiki:2,构建标识 v2.26.1-0-gbb1aef4)
  • 运行形态:Docker Compose 实例(宿主端口 8137 → 服务内 80,数据目录 /opt/otterwiki/app-data/,已开 GIT_WEB_SERVER=True;部署见 《Otter Wiki Docker Compose 部署指南》)
  • 演示账号:admin@otterwiki.local / q1w2e3r4(ADMIN);示例仓库初始提交 4e55fd2 Initial commit
  • 官方资料实查日期:2026-10-29(源码 otterwiki/cli.py、otterwiki/remote.py、内置语法页 /-/help/syntax)

二、工具概览

Otter Wiki 的命令抓手分三层,按「管账户 → 管数据 → 管版本」的动线选择:

工具载体何时用
flask user CLI容器内 docker exec关闭自助注册后由管理员建号、改密、授权
git 命令(宿主机)数据目录 app-data/repository/浏览版本历史、逐页 diff/blame、脚本化巡检
git 远端(HTTP)GIT_WEB_SERVER 暴露的 /.git异地克隆备份、外部工具批量导入页面

应用版本核对(启动日志版本行):

docker exec otterwiki-2.26.1-server sh -c 'true' && docker compose -f /opt/otterwiki/docker-compose.yml logs 2>&1 | grep 'Starting An Otter Wiki' | head -1

实测回显:

otterwiki-2.26.1-server  | *** Starting An Otter Wiki 2.26.1 v2.26.1-0-gbb1aef4

说明:Otter Wiki 官方 CLI 目前只有 flask user 账户管理一组(源码 otterwiki/cli.py),页面数据的运维主要靠「数据即 git 仓库」这一设计直接用 git 完成——这也是本文把 git 数据面作为主体工具的原因。

三、前置条件

  1. 一套运行中的 Otter Wiki 2.26.1 实例(健康检查回显见部署篇)。
  2. 宿主机已安装 git(git --version 可执行;本文 2.53.0)。
  3. 若用 git 远端功能,确认 compose 中已注入 GIT_WEB_SERVER=True 并重建实例生效。
  4. 容器内 CLI 通过 docker exec otterwiki-2.26.1-server flask <命令> 调用(flask 已在镜像内配置好应用上下文,无需额外环境变量)。

四、各工具详解

4.1 flask user:账户管理 CLI

flask user 是官方唯一的 CLI 组,命令清单(实测 --help 回显):

docker exec otterwiki-2.26.1-server flask user --help
Usage: flask user [OPTIONS] COMMAND [ARGS]...

  User management commands.

Options:
  --help  Show this message and exit.

Commands:
  create    Create a new user account.
  delete    Delete a user account.
  edit      Edit an existing user account.
  list      List all user accounts.
  password  Set or reset a user's password.

列出账户(本文环境已有 2 个账户):

docker exec otterwiki-2.26.1-server flask user list
--------------------------------------------------------------------------------------
Email                   Name        Admin  Approved  Confirmed  Permissions   Password
--------------------------------------------------------------------------------------
admin@otterwiki.local   admin       yes    yes       no         admin         set
reader@otterwiki.local  Reader One  no     yes       yes        read          set
--------------------------------------------------------------------------------------
Total: 2 user(s)

创建账户。先看 create 的参数(实测 flask user create --help 节选):

Usage: flask user create [OPTIONS] EMAIL NAME
...
  -f, --flags TEXT        Comma-separated flags to set: email_confirmed, approved
  -p, --permissions TEXT  Comma-separated permissions to grant: read, write, upload, admin

EMAIL 与 NAME 是位置参数。实测一次误用(排障实录:试图用 --name 传名字):

Usage: flask user create [OPTIONS] EMAIL NAME
Try 'flask user create --help' for help.

Error: No such option '--name'.

正确用法(创建后默认无密码、未批准):

docker exec otterwiki-2.26.1-server flask user create doc-demo@otterwiki.local 'Doc Demo'
User 'Doc Demo' <doc-demo@otterwiki.local> created successfully.
  Admin:          no
  Approved:       no
  Email confirmed:no
  Permissions:    none
  Password:       none

一次到位的写法(批准 + 确认 + 授权):

docker exec otterwiki-2.26.1-server flask user create dev@otterwiki.local 'Dev User' --flags=email_confirmed,approved --permissions=read,write

设置/重置密码。password 子命令只支持四种模式(-i 交互输入、-r 发重置邮件、-d 清除密码、-g 随机生成并打印),实测 --password 直传会报错:

Error: No such option '--password'. Did you mean '--send-password-reset'?

用 --generate 非交互生成强密码:

docker exec otterwiki-2.26.1-server flask user password doc-demo@otterwiki.local --generate
Password for 'doc-demo@otterwiki.local' set to: &zbowsD~sV[i

删除账户:带交互确认,非交互场景用 echo y 管道(注意要加 -i 保持 stdin):

echo y | docker exec -i otterwiki-2.26.1-server flask user delete doc-demo@otterwiki.local
About to delete user 'Doc Demo' <doc-demo@otterwiki.local>.
Are you sure? [y/N]: User 'Doc Demo' <doc-demo@otterwiki.local> deleted successfully.

edit 子命令与 create 同参(改名字/标志/权限),例如把某用户提为管理员:flask user edit dev@otterwiki.local --permissions=read,write,upload,admin。

4.2 git 数据面:宿主机直接读版本库

页面与附件本质是 /opt/otterwiki/app-data/repository/ 里的一个非裸 git 仓库(工作树 + .git,分支 main),宿主机无需进容器即可做版本巡检:

git -C /opt/otterwiki/app-data/repository log --oneline
b6459ba Revert "case retention demo"
1370c00 case retention demo
47af1ea Add Ops Runbook via git push
4e55fd2 Initial commit

看单次提交细节(作者/时间/文件级变化):

git -C /opt/otterwiki/app-data/repository log --stat -1
commit 47af1eac27723765fec76e69c01b98f3e256e3d0
Author: myquzuo <myquzuo@163.com>
Date:   Thu Oct 29 23:18:22 2026 +0800

    Add Ops Runbook via git push

 opsrunbook.md | 3 +++
 1 file changed, 3 insertions(+)

注意:经 git 推送的提交,作者取自推送方 git 配置(user.name/user.email);Web 界面保存的提交,作者为操作账号(初始提交为 Otterwiki Robot)。审计页面改动来源时可据此区分。

版本对比与追溯:

# 相邻两次提交的差异统计
git -C /opt/otterwiki/app-data/repository diff HEAD~1 HEAD --stat
 team handbook.md | 3 +++
 1 file changed, 3 insertions(+)
# 某页逐行追责(谁在哪个提交写的)
git -C /opt/otterwiki/app-data/repository blame -L 1,3 home.md
^4e55fd2 (Otterwiki Robot 2026-10-29 23:16:00 +0800 1) ## Welcome to your wiki!
^4e55fd2 (Otterwiki Robot 2026-10-29 23:16:00 +0800 2)
^4e55fd2 (Otterwiki Robot 2026-10-29 23:16:00 +0800 3) Your Otter Wiki is up and running.

日常巡检建议两条:log --since='1 day ago' --stat 看昨日改动;status 应保持工作树干净(出现未提交改动说明有进程直改文件,需排查)。

4.3 git 远端:GIT_WEB_SERVER 的克隆与推送

compose 中 GIT_WEB_SERVER=True 后,wiki 本身就是一个可 HTTP 访问的 git 远端,URL 是站点根 /.git。认证方式为 HTTP Basic,用户名=wiki 邮箱,密码=wiki 密码。

匿名克隆(READ_ACCESS=ANONYMOUS 时无需凭据):

git clone http://127.0.0.1:8137/.git otterwiki-clone
Cloning into 'otterwiki-clone'...

克隆产物即完整页面工作树(含 home.md 与全部历史),可直接当异地备份。

匿名推送:默认三权限为 ANONYMOUS 时,git 推送端点不要求认证,匿名也能推——这通常不是期望行为。收紧 WRITE_ACCESS=REGISTERED 后,匿名推送被服务端 401 拦下(实测,本地无凭据时):

fatal: could not read Username for 'http://127.0.0.1:8137': terminal prompts disabled

认证推送(把凭据写进 URL 演示;常态化建议配 git credential helper):

cd otterwiki-clone
printf '%s\n' '# Ops Runbook' '' '- git web push demo via http basic auth' > opsrunbook.md
git add opsrunbook.md && git commit -m 'Add Ops Runbook via git push'
git push http://admin%40otterwiki.local:q1w2e3r4@127.0.0.1:8137/.git main
To http://127.0.0.1:8137/.git
   4e55fd2..47af1ea  main -> main

推送即时生效验证——打开 /-/changelog 已出现该提交(时间 23:18:22 与 git log 一致):

2026-10-29 23:18:22
2026-10-29 23:16:00

机制说明:应用在启用 git 端点时自动向仓库写入 receive.denyCurrentBranch = updateInstead(.git/config 实测内容):

[receive]
	denyCurrentBranch = updateInstead

即推送进 main 的同时自动检出更新工作树,wiki 页面立即变化——这也是为什么推送到 main 就等于发布,敏感仓库务必收紧写权限。

4.4 版本回滚:git revert 与界面 revert

Otter Wiki 的回滚语义是 git revert(生成反向提交),不是「重置到某版本」。两条路径:

路径一:Web 界面。页面右上角 History(或全局 /-/changelog)中每个提交有 revert 入口(路由 /-/revert/<提交号>),点击即由应用生成反向提交。适合单人误编辑的快速撤销。

路径二:宿主机 git。等价命令与实测回显:

git -C /opt/otterwiki/app-data/repository revert --no-edit HEAD
 1 file changed, 3 deletions(-)
 delete mode 100644 team handbook.md
git -C /opt/otterwiki/app-data/repository log --oneline | head -3
b6459ba Revert "case retention demo"
1370c00 case retention demo
47af1ea Add Ops Runbook via git push

实测要点:revert「创建页面的那次提交」,页面文件随反向提交被删除(wiki 中该页消失);对「编辑页面的提交」做 revert 则恢复为编辑前内容。回滚可以再回滚——对 b6459ba 再执行一次 revert 即恢复页面。危险操作是 git reset --hard:会抹掉历史且与应用的增量日志模型冲突,数据目录场景不要使用。

4.5 页面语法要点:嵌入与扩展

编辑器内置完整语法帮助页 /-/help/syntax(登录后访问)。标准 Markdown 之外,Otter Wiki 有一组自研扩展,写页面最常用的两类:

嵌入语法(Embeddings),共 8 种,双大括号调用:

语法作用
{{AttachmentList}}把当前页附件渲染成表格
{{DataTable}}渲染可排序、搜索、分页的表格
{{Figure}}内容包裹为带可选标题的图版
{{ImageFrame}}图片以带边框浮框呈现
{{Include}}引用另一页面(或其某章节)内容
{{InfoBox}}正文旁渲染结构化信息框
{{PageIndex}}列出当前页之下的子页索引
{{Video}}按 URL 或附件嵌入视频

⚠️ 勘误:v2.26.1 没有 {{TOC}} 嵌入(源码与内置帮助页双重确认)。页面目录由标题层级自动生成,无需手写。

结构化块语法(非标准 Markdown,帮助页原样示例):

::: info
# 标题行
支持 _格式化_ 的正文。
:::

样式可选 info/success/warning/danger/none。折叠与剧透:

>| # 摘要标题
>| 折叠的正文内容。

>! 点击图标才展开的剧透内容。
>! 第二行。

GitHub 风格告警块可用五种:> [!NOTE]、> [!TIP]、> [!IMPORTANT]、> [!WARNING]、> [!CAUTION]。

其他高频扩展:高亮 ==mark==;脚注 [^1];缩写定义 *[HTML]: Hyper Text Markup Language;Mermaid 图 ​```mermaid ... ​``` ;代码块带行号用 ​```python=(语言后加等号);公式 $a^2+b^2=c^2$(行内)与 ​```math ... ​``` (块级);站内双链 [[页面名]] 与 [[显示文本|页面名]](方向可由 WIKILINK_STYLE 调整,见《Otter Wiki 2.26.1 配置参数详解》4.6 节)。

五、注意事项

  1. 文件名小写化:默认 RETAIN_PAGE_NAME_CASE=False,Team Handbook 落盘为 team handbook.md(实测见配置篇 5.5 节)。脚本批量导入时按全小写命名文件最省事。
  2. 推送到 main 即发布:receive.denyCurrentBranch=updateInstead 使外部推送即时更新工作树,生产务必 WRITE_ACCESS=REGISTERED 起步。
  3. git 身份区分审计:Web 保存的提交作者是 wiki 账号名,git 推送的提交作者取推送方 user.name/user.email;重要仓库建议统一要求 Web 编辑或规范 git 身份。
  4. --generate 密码只打印一次:flask user password --generate 的明文密码仅出现在当次输出里,当场交付用户;-r 邮件重置需要已配好 SMTP。
  5. 回滚用 revert 不用 reset:git reset --hard 会破坏应用所依赖的历史连续性;误 reset 后可用 git reflog 找回,但应避免发生。
  6. CLI 输出前有启动横幅:每次 docker exec ... flask ... 的输出第一行是应用版本横幅(*** Starting An Otter Wiki ...),脚本解析时注意跳过。

六、常见问题(FAQ)

Q1:flask user create 报 Error: No such option '--name'? EMAIL 与 NAME 是两个位置参数,写作 flask user create user@example.com 'User Name',名字不加选项直接跟在邮箱后(实测回显见 4.1 节)。

Q2:想直接给用户设密码却报 No such option '--password'? password 子命令没有明文传参入口,只有 -i(交互)、-r(邮件重置)、-d(清除)、-g(生成并打印)四种模式;非交互自动化用 --generate(4.1 节实测)。

Q3:克隆时报 404? GIT_WEB_SERVER 未开启。端点路径是站点根 /.git(如 http://host:8137/.git),确认 compose 已注入该变量并重建实例。

Q4:推送被要求输入用户名(终端禁用环境下报 fatal)? WRITE_ACCESS 非 ANONYMOUS 时推送必须认证。用邮箱+密码做 HTTP Basic(URL 内嵌写法见 4.3 节,@ 需转义为 %40),或配置 git config credential.helper。

Q5:宿主机 git 操作会不会和 Web 端冲突? 正常顺序操作不冲突:应用每次读写都经 gitpython 实时操作仓库,外部提交对其就是普通新提交。避免在应用保存进行中同时做大批量脚本写入;批量导入后刷新 changelog 即可看到全部提交。

七、参考链接

站内延伸阅读