# Oink 0.7.1：页面不再外泄，坏输入不再中断构建

> Oink 0.7.1 是一次安全与校验修补。Swagger UI 不再把你的 spec 地址发给第三方， 配错的参数会告警并回退而不是中断普通构建，OpenAPI 与终端录像组件也终于像其他组件一样， 在打印、Markdown 和 RSS 中表现正常。

---

LLMS 索引： [llms.txt](/zh/llms.txt)

---

Oink 0.7.1 不改动任何组件 API，也不需要修改内容。它修复了对 0.7.0 主线外部审查发现的
代码问题：一个真实的隐私外泄、一类会直接中断构建的配置值，以及三个从未被告知
"非 HTML 输出"存在的组件。

**v0\.7\.1 · 2026-08-26**
- [查看发布](https://github.com/pgsty/oink/releases/tag/v0.7.1)
- [源码 · tar\.gz](https://github.com/pgsty/oink/archive/refs/tags/v0.7.1.tar.gz)
- [源码 · zip](https://github.com/pgsty/oink/archive/refs/tags/v0.7.1.zip)
- [pgsty\/oink](https://github.com/pgsty/oink)

## 概览 {#at-a-glance}

- Swagger UI 不再联系在线 validator。已发布的 API 页面每次被浏览都会发出一个第三方请求，现在不会了。
- 写在站点配置里的 URL，现在和作者写的 URL 走同一道安全检查。
- `params` 中数值或布尔值写错，会告警并回退，而不是终止普通的 `hugo server`。
- `swagger`、`redoc`、`asciinema` 在打印、Markdown 和 RSS 中输出纯链接，只在交互 HTML 中装载运行时。

## Swagger 不再向外汇报 {#swagger-validator}

Swagger UI 默认开启在线 validator，地址指向 `validator.swagger.io`。它对 `localhost`
跳过这个请求——这正是本地预览和浏览器测试从来看不到它的原因，也意味着每一个已经部署上线的
API 页面，都在悄悄把你的 spec 地址交给第三方。在内网站点上，那个地址就是一个内部主机名。

现在初始化写死 `validatorUrl: null`，并从内联 `<script>` 移入可缓存的
`js/chunks/swagger-init.js`。普通构建依然不下载任何东西，而现在普通的浏览也不再上传任何东西。

## 配置里的 URL 与作者写的走同一道门 {#url-policy}

有两处设置未经检查就进入了 `href`：`params.ui.page_context_menu.links` 里的自定义链接，
以及归档站点横幅的 `params.url_latest_version`。在其中任何一处写 `javascript:` URL，
都会渲染成一个可点击、可执行的脚本链接。

现在两者都走主题的统一 URL 策略：不支持的 scheme 会告警并丢弃该链接，而不是尝试修补。
归档版本横幅在写入页面时还会额外做 HTML 转义——因为"scheme 合法"和"放进 HTML 属性里安全"
不是一回事。

自定义链接还会跳过缺少名称或名称不是文本的条目，并且只有当确实有链接留下来时，
才渲染它们上方的分隔线。

## 配置写错会告警，而不再让预览挂掉 {#validation}

主题一直有一条规则：非法的作者或配置输入应当告警、回退到有文档记载的默认值，
并保持 `hugo server` 可用；而 `--panicOnWarning` 会在发布时把这个告警变成失败。
只是有一批数值和布尔配置从来没有接入这条规则。

在 0.7.1 之前，`blog_index_size: nope` 会以一个 Go 模板错误终止构建。另一些则因为安静而更糟：
`sidebar_width_min: -50` 一声不响地输出了负的像素宽度，`blog_index_columns: 2.5`
把一个小数送进了 CSS 网格。

现在每一个数值与布尔配置都经过统一校验器：

| 输入 | 之前 | 现在 |
| --- | --- | --- |
| `blog_index_size: nope` | 构建失败 | 告警，使用 `12` |
| `blog_index_size: 0` | 静默变成 `12` | 告警，使用 `12` |
| `sidebar_width_min: -50` | 输出 `-50px` | 告警，使用 `220` |
| `sidebar_width_min: 300` 且 `max: 200` | 布局反转 | 告警，使用 `220`/`480` |
| `blog_index_columns: 2.5` | 小数进入 CSS | 告警，使用 `3` |
| `sidebar_item_overflow: clip` | 静默当作 `ellipsis` | 告警，使用 `ellipsis` |
| `print.toc: nope` | 静默当作 `true` | 告警，使用 `true` |

同样的处理覆盖了 Landing 各区块：hero 的 `media.ratio` 与 `media.max_width`、
capabilities 的 `columns` 与 `rules`、以及跑马灯的 `rows`。其中 hero 的两个样式输入尤其值得一提——
它们此前被原样拼进 `style` 属性，因此页面自己的 front matter 就能往页面上注入任意 CSS。
现在 `ratio` 只接受两个轨道尺寸（`'1fr 240px'`），`max_width` 只接受一个纯 CSS 长度。

如果你的站点此前一直用着某个被主题静默纠正过的值，升级后会看到新的告警。这正是目的所在——
升级后用 `--panicOnWarning` 构建一次，把它们找出来。

## OpenAPI 与终端录像尊重其他输出 {#outputs}

Oink 的每个组件都只渲染一次，然后适配它所在的输出：交互 HTML、静态打印、
给智能体读的纯 Markdown，以及 RSS。已有十六个组件这样做，而 `swagger`、`redoc`、
`asciinema` 没有——它们把交互标记原样渲染进了全部四种输出。

结果是：Markdown 输出里带着 `<div class="td-asciinema">` 和一整块 JSON 配置，
打印页面上是一个本该有播放器的空壳，而单页打印甚至真的下载了播放器运行时，
只为显示一帧静止画面。

现在三者都读取输出格式：

| 输出 | 你会得到 |
| --- | --- |
| HTML | 完整的交互组件 |
| 打印 | 一行带标题的静态链接，地址可见 |
| Markdown / LLMS | 一个纯 Markdown 链接，仅此而已 |
| RSS | 同样的纯链接 |

只有交互 HTML 会登记运行时，因此打印与机器输出不再装载播放器、Swagger 包或 ReDoc 包。
录像与 spec 地址现在同样走统一 URL 策略，而写错的 `speed`、`cols`、`rows` 或标记时间
会告警并被忽略，不再终止构建。

## 其他修复 {#smaller-repairs}

- capabilities 的横条现在按作者写的宽度渲染。模板一直在输出这些宽度，只是样式表从未读取。
- 生成的配置 Schema 与 Hugo 实际解析的结果一致。`hugo.yaml` 的行尾注释此前污染了十一个默认值——
  `print.toc` 是以字符串 `"true # section print views…"` 发布的——另有四段注释挂在了错误的键上。
  仅用于提示重命名的旧键不再出现在编辑器补全里。
- `hero` 的 `media` 不是一个映射时会告警并丢弃该媒体，而不是终止构建。

## 升级 {#upgrading}

```bash
hugo mod get github.com/pgsty/oink@v0.7.1
hugo mod tidy
```

不需要修改内容、配置或模板。升级后建议做一件事：用 `--panicOnWarning` 构建一次。
那些过去被静默纠正的配置现在会开口，而这次构建就是你听到它们的地方。

完整清单见 [CHANGELOG.md](https://github.com/pgsty/oink/blob/main/CHANGELOG.md)。

---

反链：

- [2026-08-26 全面审查](/zh/docs/design/research/2026-08-26-comprehensive-review/)
