Oink 0.5.0 — 组件 API v5 与收敛后的配置
Oink 0.5.0 是 API 冻结版本。它包含 1.0 线将要冻结的全部变更:组件 API v5 (原生 Markdown 形态优先,29 个 shortcode 作为完整形态)、按三条规则收敛的配置键与 front matter 键、主题产出物统一的命名空间、0.x 兼容层与无人使用的 Docsy 遗留物的 删除,以及能把 0.4 站点改写到位的迁移工具。任何被退役的键、形态或 shortcode 都会让构建失败,并在错误信息里给出替代写法。
对每一个 0.4 站点来说这都是破坏性升级。请先看概览, 再看迁移指南;中间的参考章节逐项列出每一处变化的新旧形态。
概览
- 内容:大多数组件直接用 Markdown 写——
> [!TYPE]提示块、{.steps}/{.cards}列表、{.fields}/{.matrix}/{caption=}/{#id num=}/{tab=}表格、```filetree/```gallery/```echarts/```infographic/```checksums数据围栏、相邻代码围栏成标签页、 带属性行的 Markdown 图片。0.4.2 的 53 个 shortcode 中 32 个删除或改名、8 个新增, 剩下 29 个作为完整形态。scripts/migrations/oink06.py负责改写内容。 - 配置:三条规则——开关就是裸的特性名、单键 map 压平、front matter 键 =
站点键去掉
ui.。约四十个键改名或改形,每个旧键都会让构建失败并指出替代。 主题的全部默认值都声明在主题的hugo.yaml里。 - Front matter:不再有
ui:块;页面覆盖用裸键(section_index: cards),page_context_menu与站点 map 同形,manualLink*改为manual_link*,hide_*/exclude_search删除。 - 命名空间:主题 class 一律
td-*、data 属性data-td-*、自定义属性--td-*、 JS 全局Oink*;oink-*一族和 Docsy 遗留(leaf、has-child、nav-*…) 消失。提示块文案改为callout_*i18n 键。 - 删除:
home/**适配 partial、outputformat.html、td/render-heading.html、 Docsy community 页面与params.links、td/code-dark/td/color-adjustments-dark/td/gcs-search-dark/td/extra这些 Sass 文件、.td-box*与-bg-*调色 class、 Prism、Open Sans、click-to-copy.js、swaggerui(改名swagger)。 - 行为:标题带自链接;print 内容每次构建只渲染一次(修了一个真实的竞态); 三个可缓存的 JS bundle;print 页面加载 8 KB JS 而不是 100 KB;shell 动效在结构上 遵守 reduced-motion;giscus 调色板随主题发布并且只在渲染评论的页面加载。
- 迁移:内容与 front matter 走
oink06.py report → migrate --write → check, 然后构建——报错就是配置清单。 - 发布加固:API 冻结前进行了两轮对抗性评审,修复了客户端命名空间迁移、 动作注册表加载顺序、迁移输入 fail-closed、多实例 OpenAPI 嵌入、通用属性与图片 URL 策略,以及消费站配置预检。
组件 API v5
原生形态优先
v5 的原则:Markdown 块能表达的组件就用 Markdown 写;shortcode 只为块表达不了的 情形存在。渲染钩子识别原生形态,所有钩子共用一套属性策略。
组件:原生形态与完整形态
Callout 提示块,> [!NOTE] Title引用块;[!TYPE]-折叠 /[!TYPE]+展开;可选{icon="fa-solid fa-x"};类型note tip important warning caution success danger question example quote details。没有 shortcode。Tabs 标签页,原生:相邻围栏(或表格)加
{tab= group= value=}。Shortcode:
tabs group= default= label=tab label= value=…/tab/tabs。Steps 步骤,原生:
1.列表 +{.steps}。Shortcode:
steps加标题——唯一用%分隔符书写的 shortcode(正文是页面级 Markdown);步骤里的标题会进入页内目录。Cards 卡片,原生:链接列表 +
{.cards}。Shortcode:
cardscard title= link= icon= badge= image= image_alt=|decorative=正文/card/cards。Fields 字段,原生:表格 +
{.fields [caption=] [id=] [meta="type required default -"]}——第一列是名称,最后一列是说明,中间列是元数据 chip。Shortcode:
fields label= id= class=field name= type= required= default=正文/field/fields——用于块级说明(本列表就是)。两种形态渲染同样的 chip;每个条目有#field-<name>锚点。FileTree 文件树,```filetree {title=}围栏,每个条目一行- name[/] # comment {icon= tone= open= type=};2/4 空格、tab 或tree缩进。CSS + 原生<details>;注释列在构建期对齐。没有 shortcode。Gallery 画廊,```gallery围栏,每张图一行 # description {link= class=};alt 必填,条目可缩放。没有 shortcode。Image 图片,加属性行{#id num= caption= width= height= link= command= options=},承担图注、编号、链接与 Hugo 图片处理。imgproc退役;没有图片 shortcode。表格族,{.full-width}{.fields}{.matrix}{caption=}{#id}{#id num= caption=}{tab= group= value=};站点 class 透传。互斥:fields ⟂ matrix / full-width / num;num ⟂ tab。Fig / Tbl / Eq / Eg,原生:图片 / 表格 /
$$块 / 围栏 +{#id num= caption=}(默认 idfig-、tbl-、eq-、eg-<num>)。Shortcode:
figtbleqeg(eg必须有图注)。代码围栏,围栏属性
{title copy wrap collapse label id tab group value num caption lineNos hl_lines lineNoStart anchorLineNos tabWidth};只有 Chroma。数据围栏,mermaid plantuml markmap math chem echarts infographic checksums filetree gallery;echarts只做声明式配置,$fn:<name>回调来自window.OinkEchartsFunctions。
29 个 shortcode:核心 14(tabs tab steps cards card fields field include kbd badge param comment contributors asciinema)、Book 10(fig tbl eq eg xref book-toc book-figures book-tables book-equations book-examples)、Release 3、
OpenAPI 2。嵌套名(tab、card、field)只在父级里合法;每个 shortcode 都校验
参数,未知参数导致构建失败(0.4 里 asciinema、redoc、swagger、param、
comment、steps 会静默接受任何参数)。
删除的 shortcode 与替代
每个条目上的 chip 是迁移工具键(scripts/migrations/oink06.py migrate --only <key>);
manual 表示报告会列出、需要人工修改。
删除的 shortcode 与替代
alert · details · td-page-notice,0.4:
alert color=… title=…、details、td-page-notice(都是%shortcode)、原生<details><summary>。0.5.0:
> [!TYPE] title提示块,折叠块用> [!DETAILS]-。tabpane · tab · code-group · code-tab,0.4:
tabpane配tab header=…(都是%shortcode)、code-group配code-tab。0.5.0:相邻围栏加
{tab= group= value=}(纯代码面板),或tabs配tab(混合内容)。filetree · filetree/folder · filetree/file,0.4:
filetree与filetree/folder、filetree/file;过渡期的{.filetree}列表标记。0.5.0:
```filetree围栏——label改为title;open、icon、color、comment、link保留。echarts · infographic,0.4:
echarts、infographicshortcode。0.5.0:同名数据围栏;
$fn:回调不变,js子围栏改到window.OinkEchartsFunctions。readfile,0.4:
readfile file=…。0.5.0:
include file=… [code=true lang=…]——依次查页面资源、assets、content 相对路径。example · book-figures kind=,0.4:自闭合的
example …+ 围栏;book-figures kind="tbl"。0.5.0:
eg…/eg;book-tables、book-equations、book-examples。_param · iframe · conditional-text · netlify · 不带 kind 的 xref,带
file:line报告,人工处理;_param占位符由param_placeholders变换处理。
相对 0.4.2 新增:tabs、cards、include、eg、book-tables、book-equations、
book-examples,以及改名而来的 swagger。card 与 tab 名字未变,但现在是
cards / tabs 的子元素,契约不同。
没有图片 shortcode:渲染钩子统一为 Markdown 图片、fig 与配置里的图片来源解析页面
资源、栏目资源、全局 assets 以及 static / 远程路径,并把图注、编号、链接与 Hugo
图片处理(command、options)都放在属性行上——imgproc 能做的它都能做。
块属性策略
所有渲染钩子(表格、图片、代码块、passthrough、引用块、标题)共用一套策略:
白名单键由钩子消费,class 经 token 校验后透传,data-* 与 aria-* 透传,
style、on* 与任何未知键让构建失败。内容上的站点 CSS class 仍然合法;
内联样式和事件处理器永远到不了输出。
代码围栏
{filename="x"}改为{title="x"};同一围栏上title与filename互斥。- Prism 路径删除。
params.prism_syntax_highlighting、static/js/prism.js、static/css/prism.css不复存在;Chroma 加params.highlight_classes(默认true)是唯一的高亮器。Prism 无法与tab、group、value、num、caption共存,任何用了标签页或编号示例的 0.4 站点一开启它就已经构建失败。 - 复制控件依次遵循围栏上的
copy=all|command|true|false、会话类 lexer 默认值 (console、shell-session→command)、再是all。params.ui.code_copy: false只改站点默认值;显式写了copy的围栏仍按自己的写法。旧键disable_click2copy_chroma会静默压过作者的显式值。 - Docsy 的
click-to-copy.js(0.3 起从未加载)及其.td-click-to-copy样式删除。
配置
三条规则
- 布尔开关就是裸的特性名:
ui.annotation: true,不是ui.annotation.enable, 也不是ui.annotation_enabled。仅存的_enabled后缀是ui.navbar_enabled、ui.sidebar_enabled、ui.sidebar_root_enabled——它们的裸名会与同族兄弟键冲突。 - 单键 map 压平成标量。只有拥有多个子设置的特性才保留 map——
comments、ui.feedback、ui.page_context_menu、ui.dark_mode、ui.command_palette、ui.alt_site、taxonomy、print、search、plantuml、drawio、mermaid、copyright、ui.taxonomy_icons——其中开关型的同时接受裸布尔 (comments: false、plantuml: false、dark_mode: true、feedback: true、page_context_menu: false)。 - front matter 键 = 站点键去掉
ui.前缀,没有例外(见 Front matter)。
键名一律 snake_case、正向、按用途命名。camelCase 只在原样透传给外部运行时的地方
保留(comments.giscus.* 是 giscus 自己的属性名,mermaid.* 交给
mermaid.initialize())。
任何旧键或旧形态都会让构建失败并指名替代——站点配置由
layouts/_partials/config-legacy.html 负责,页面由
layouts/_partials/front-matter-legacy.html 负责——升级就是按报错逐条替换。
没有任何东西被静默忽略。
改名与改形的站点键
| 0.4 | 0.5.0 | 说明 |
|---|---|---|
offlineSearch、offlineSearchIndex、offlineSearchMaxResults、offlineSearchOnServe、offlineSearchSummaryLength |
offline_search、offline_search_index、offline_search_max_results、offline_search_on_serve、offline_search_summary_length |
环境变量覆盖写 HUGOxPARAMSxOFFLINE_SEARCH_ON_SERVE=true(Hugo 的备用分隔符 x;_ 无法定位含下划线的键) |
ui.showLightDarkModeMenu(true / false / "enable-only (experimental)") |
ui.dark_mode——true,或 { enable, show_menu } |
show_menu: true 隐含 enable |
ui.scrollSpy.disable |
ui.scroll_spy |
取反;默认 false |
ui.no_left_sidebar |
ui.sidebar_enabled |
取反 |
ui.breadcrumb_disable |
ui.breadcrumb |
取反;默认 true |
print.disable_toc |
print.toc |
取反;默认 true |
disable_click2copy_chroma |
ui.code_copy |
取反;只设默认值 |
ui.readingtime.enable |
ui.reading_time |
裸布尔 |
ui.ul_show |
ui.sidebar_expand_levels |
默认 2 |
Taxonomy.taxonomyCloud、.taxonomyCloudTitle、.taxonomyPageHeader |
taxonomy.cloud、.cloud_title、.page_header |
一个小写 map |
ui.annotation.enable、ui.image_zoom.enable、ui.keyboard_nav.enable |
ui.annotation、ui.image_zoom、ui.keyboard_nav |
裸布尔 |
ui.typography.preset |
ui.typography |
technical | system;环境变量覆盖 HUGO_PARAMS_UI_TYPOGRAPHY=system |
ui.pager.types |
ui.pager_types |
[docs, book, blog] |
markmap.enable |
markmap |
裸布尔 |
content_width(slim | norm | wide) |
reading_width(slim | normal | wide) |
Book 正文测量;body class td-book-content--normal,令牌 --td-book-content-normal |
ui.docs_root |
ui.docs_sidebar_root |
section | home |
github_url |
github_repo |
编辑、历史、Issue 链接由仓库推导 |
algolia_docsearch |
search.algolia 加 appId、apiKey、indexName |
构建失败 |
rss_sections |
删除 | 从未被读取 |
params.links.user[] / .developer[] |
删除 | Docsy community 页面已删 |
plantuml.enable、drawio.enable |
不变,且 map 接受 plantuml: false / drawio: false |
|
comments.enable |
不变,且接受 comments: false |
|
comments.giscus.lightTheme / darkTheme |
默认不设 | 默认使用主题自带调色板(见样式与资源) |
主题的全部默认值现在都在主题 hugo.yaml 里声明并附取值域注释。以前只是模板回退、
现在正式声明的有:offline_search: false、offline_search_summary_length: 70、
ui.breadcrumb: true、ui.reading_time: false、ui.dark_mode: false、
ui.docs_sidebar_root: section、ui.sidebar_icon_policy: all、
ui.section_index_columns: 2、ui.code_copy: true、print.toc: true、
print.section_break_wordcount: 50、markmap: false、plantuml.enable: false、
drawio.enable: false、github_branch: main。两个默认值保持派生并如此记录:
ui.quick_links(来自 docs_section 与 blog_section)和 ui.taxonomy_icons
(内置 categories/tags 图标)。ui.sidebar_expand_levels(2)与
ui.sidebar_menu_truncate(2000)的模板回退与声明值一致。
保持不变、继续可用的 Docsy 键:github_repo、github_project_repo、github_branch、
github_subdir、path_base_for_github_subdir、time_format_blog、
time_format_default、version、versions、version_menu、
version_menu_pagelinks、archived_version、url_latest_version、copyright、
description、author、gcs_engine_id、search.algolia.*、mermaid、
plantuml.*、drawio.*、ui.sidebar_menu_compact、ui.sidebar_menu_foldable、
ui.sidebar_menu_truncate、ui.sidebar_cache_limit、ui.sidebar_root_enabled、
ui.feedback.{enable,reasons}。
大声失败,而非静默
同时配置多个搜索后端(offline_search、gcs_engine_id、search.algolia)现在会让
构建失败(以前只警告)。PlantUML 不设 plantuml.svg_image_url、Diagrams.net 不设
drawio.drawio_server、Algolia 缺任一凭据,与 0.4 一样构建失败。构建错误遵循同一
形状——<component>: <subject> <expectation>; got <value> at <position>——全小写、
位置只用一个介词、配置错误给出完整的 params. 路径;不再指向文档 URL。
Front matter
页面键 = 站点键去掉 ui. 前缀,front matter 里不再有 ui: 块。栏目 cascade 同理
(cascade: { params: { section_index: cards } } 或直接裸键)。一个解析器
(ui-param.html)为每个可按页覆盖的 params.ui.* 设置先读页面值、再读站点值:
sidebar_menu_compact、sidebar_menu_foldable、sidebar_expand_levels、
sidebar_width_min、sidebar_width_max、sidebar_item_overflow、
sidebar_headings、sidebar_enabled、section_index、section_index_columns、
lastmod_commit、breadcrumb、scroll_spy、code_copy、keyboard_nav、
book_draft_banner;再加上显式页面键 navbar_enabled、navbar_autohide、
footer_style、annotation、feedback、image_zoom、reading_time、
page_context_menu、comments、page_width、reading_width。
| 0.4 front matter | 0.5.0 |
|---|---|
params: { ui: { <key>: … } }(任何键) |
顶层(或 params: 下)的 <key>: … |
params.ui.image_zoom.enable |
image_zoom: true | false |
params.ui.keyboard_nav.enable、params.ui.annotation.enable |
keyboard_nav、annotation(裸布尔) |
annotation: { enable: … } |
annotation: true | false |
context_menu |
page_context_menu(true | false,或 { enable, assistant_links }) |
assistant_links(顶层) |
page_context_menu: { assistant_links: false }——页面只能收窄站点策略 |
hide_readingtime: true |
reading_time: false |
hide_feedback: true |
feedback: false |
exclude_search、excludeSearch |
search_exclude |
content_width: norm |
reading_width: normal |
manualLink、manualLinkTitle、manualLinkTarget、manualLinkRelref |
manual_link、manual_link_title、manual_link_target、manual_link_relref |
body_class: td-no-left-sidebar |
sidebar_enabled: false |
contributingUrl |
随 community 页面删除 |
Icon |
icon(Hugo 不区分大小写;主题按小写读取) |
未变的页面键:toc_hide、toc_root、notoc、no_print、no_list、simple_list、
hide_summary、sidebar_root_for、sidebar_divider、sidebar_expanded、
sidebar_root_menu、sidebar_root_link_self、search_keywords、search_boost、
pager、landing、sections、book_number、book_status、release、
release_products、release_group_by_product、upstream_attribution、
downstream_modified、byline、author、body_class。
scripts/migrations/oink06.py migrate --only frontmatter 会改写以上全部页面键,
包括 cascade: map 与列表里的。
模板、partial 与布局
删除项,以及复制或调用过它们的站点应改用什么:
| 0.4 | 0.5.0 |
|---|---|
_partials/home/**(18 个适配器)、_partials/home-data.html |
_partials/landing/**、landing/home-data.html |
_partials/outputformat.html |
.Store.Get "tdOutputFormat"(html | print | markdown | rss,每个 base 模板都会设置) |
_partials/td/render-heading.html 以及调用它的站点侧 _markup/render-heading.html |
主题自己的 _markup/render-heading.html——删掉站点覆盖 |
layouts/community/list.html、layouts/docs/community.html、_partials/community_links.html |
无——Docsy community 页面已删 |
_partials/taxonomy_terms_article.html、taxonomy_terms_article_wrapper.html、taxonomy_terms_cloud.html |
taxonomy-terms-article.html、taxonomy-terms-article-wrapper.html、taxonomy-terms-cloud.html |
_partials/taxonomy_terms_clouds.html、code/markdown-escape.html |
0.4 里就已是死文件;活的是 shell/taxonomy-terms-clouds.html、content/markdown-escape.html |
_shortcodes/swaggerui.html |
_shortcodes/swagger.html |
从 0.4 复制的 layouts/_default/_markup/render-* |
保留任何覆盖前先与 0.5.0 对比——每个钩子都变了 |
有覆盖的站点还应知道的模板层变化:
- 侧栏两个来源——内容树与显式的
data/docs_nav.json——每一行都经shell/sidebar-node.html渲染。shell/config.html仍是品牌、logo、栏目配置的 唯一解析器。 - 每个渲染内容的布局都调用
content/render.html而不是.Content(图片缩放候选扫描在那里进行)。 - Print:
print/page-content.html通过partialCached让每页的 print 内容在一次 构建里只渲染一次;print/render.html、print/content.html、book/print.html与各single.print.html布局都读它。复制过 0.4 print 模板的站点应删掉副本—— 0.4 的流水线在"本身是 section 的章节被父级再次聚合"时会在页面 store 上竞态。 - 标题渲染钩子归主题所有。每个标题带 id 与悬停显示的自链接
(
.td-heading-self-link,文案ui_heading_self_link);print 与 RSS 会剥掉链接。 - DocSearch 容器只有一个
#td-docsearch;写死的#docsearch-0/1两个 id 没有了。
样式与资源
一个命名空间
主题产出的一切都有前缀,scripts/check-namespace.py 守着这条线。站点里挂在旧名字
上的 CSS 或 JS 必须迁移:
| 类别 | 0.4 | 0.5.0 |
|---|---|---|
| class | oink-*(landing 子系统)、leaf、has-child、active-path、is-open、is-active、is-hidden、is-disabled、landing-header、landing-nav、landing-container、article-meta、pageinfo、nav-*、taxonomy-*、ul-N |
全部 td-*;站点页头与导航是 td-site-header、td-site-nav、td-site-container |
| data 属性 | data-oink-* |
data-td-* |
| 自定义属性 | --oink-*、--term-* |
--td-* |
| JS 全局 | oink* / echartsFunctions |
window.OinkActions、OinkEchartsFunctions、OinkLanding、OinkSearchEngine、OinkSurfaceCoordinator |
| 作者标记(无前缀,不变) | — | {.steps} {.cards} {.fields} {.matrix} {.full-width} |
Sass 与令牌
删除的 Sass 文件(站点 _styles_project.scss 若仍 import 会编译失败):
td/code-dark、td/color-adjustments-dark、td/gcs-search-dark、td/extra、
td/extra/bs-defaults、td/extra/buttons、td/extra/main-container、
td/extra/navbar、td/boxes(.td-box、.td-box--<color>、.td-box--height-*)、
td/colors(.-bg-<name>、.-text-<name>)。删除的变量:$td-box-colors、
$td-print-font-name、$td-enable-webfonts。
改名或新增的令牌:--td-book-content-norm → --td-book-content-normal
(.td-book-content--norm → --normal);--td-print-font-family 角色保留但在
两种预设下都跟随 --td-body-font-family;新增 --td-motion-duration-fast
(100 ms)、--td-motion-duration(150 ms)、--td-motion-duration-slow(250 ms),
shell 的每个过渡都引用它们,prefers-reduced-motion: reduce 把它们置零。
排版:UI 与正文使用 Inter(可变字重,Latin/Latin-ext/西里尔/希腊/越南语子集按
unicode-range 提供;CJK 与 emoji 回落到平台字体栈)、无边框行内代码、安静的代码
卡片加悬停显示的复制控件、Mintlify 风格字段行、页末两个文本链接的翻页器、卡片式
栏目索引上方的分隔线。Open Sans(18 个 woff2 子集、652 KB,为一个仅打印用的字体
发布到每个站点)已删除;想在纸面上换字体的站点自己在样式表里设
--td-print-font-family。system 预设依旧不请求任何品牌字体。
shell 图标改为由 shell/icon.html 分发的 Font Awesome class 对
(<i class="td-shell-icon td-shell-icon--<name> fa-solid fa-…">)而不是内联
SVG;--td-shell-icon-size 设置尺寸盒。
发布的资源
- 三个 JavaScript bundle 取代按特性组合生成的单个 bundle:
js/actions.js与js/core.js在每一页字节相同、可以缓存;只有一个小的js/page-<hash>.js随页面变化。ECharts 单独一个<script>。print 输出加载 7.9 KB 而不是 100 KB。 static/css/giscus-oink-{light,dark}.css没有了。调色板以assets/css/giscus-{light,dark}.css随主题提供,只在渲染评论的页面发布, 并且是comments.giscus.lightTheme/darkTheme的默认值;指向旧路径的站点 删掉那两行即可(或写 giscus 内置主题名 / 自己的样式表 URL)。- 删除:
static/js/prism.js、static/css/prism.css、static/webfonts/open-sans/、assets/js/click-to-copy.js。VENDOR.json与 vendor 目录哈希已重新生成。
i18n
- 提示块文案改为带命名空间的键:
callout_note、callout_tip、callout_important、callout_warning、callout_caution、callout_success、callout_danger、callout_question、callout_example、callout_quote、callout_details。 主题不再占用note、example、quote这类裸顶层键;在自己i18n/里覆盖过 这些键的站点需要改名。 - 删除:
community_join、community_introduce、community_learn、community_using、community_develop、community_contribute、community_how_to、community_guideline。 - 新增:
ui_heading_self_link与ui_field_self_link(各语言英文兜底;中文变体已审校)。 - 32 个语言文件保持键完全一致(174 个键)。
数据文件
data/home/<lang>.yaml(或data/home.yaml)必须列出sections;隐式的hero → metrics → capabilities → principles → cta顺序没有了,缺失会构建失败。- 胖页脚只读
data/footer/<lang>.yaml(或data/footer.yaml)。data/home里的footer键会构建失败并指出新位置。 data/landing/<key>/<lang>.yaml、data/docs_nav.json、data/download/<key>.yaml、data/brand.yaml不变。
行为与输出变化
- 标题带悬停显示的自链接;print 与 RSS 输出剥掉锚点,Markdown 输出
(
RenderShortcodes)不受影响。 - print 聚合每次构建对每页内容只渲染一次。0.4 里"本身是 section 的章节"会被自己的
print 输出和父级的 print 输出并发渲染两次,两次渲染在页面 store 上竞态——可见
症状是
_print/里偶发重复的td-code-…id。 <main>不再带role="main";侧栏<aside>不再重复内层<nav>的 “Section navigation” 标签。ui.dark_mode: true同时开启暗色调色板与 System / Light / Dark 菜单; 单独的show_menu: true隐含enable。ui.code_copy: false只设默认值(见代码围栏)。- 首页渲染导航栏;提示块标题满足对比度;Gallery 条目与其它图片同等享有缩放;
标签页运行时保住运行边界、唯一同伴 id 与 print 标题;FileTree 与整个 shell 遵守
prefers-reduced-motion。 - 表格渲染钩子也在 print 与 RSS 输出里运行,表格在交互式 HTML 之外也保留图注、
编号与滚动容器;两种形态的
fields产出同一渲染,每个条目都有#field-<name>锚点。 llms.txt读取params.ui.docs_section,并带描述列出文档页面。- 图片解析器的错误按调用方标注(Markdown 图片是
image:,fig是 shortcode 名), 配置里的图片来源与内容遵循同一 URL 策略。
发布候选加固
最终评审发现了一个系统性迁移缺口:模板已经输出新的 data-td-* 契约,若干运行时与
测试 mock 却仍读取旧 dataset 名称;动作清单还位于同步动作注册 bundle 之后,注册表
可能以空状态初始化。这两项现已修复,并新增结构检查阻止回归。页面动作、命令面板搜索、
代码复制与折叠、反馈页面标识、折叠控件文案、Giscus 主题、图片缩放标签与 Asciinema
计时标签,现在会在测试与真实渲染 DOM 中使用同一组属性。
同一轮加固还完成了以下修正:
report、migrate与check遇到不存在、空、不可读或非 UTF-8 的目标时直接失败, 不再给出误导性的“无残留”结果;JSON front matter 改用 JSON 解码器解析;- Markdown、RSS 与聚合打印输出都会执行旧 front matter 检查,页面评论等覆盖项严格 校验布尔值与 map 形态;
- 数据围栏与提示块会保留允许的
data-*/aria-*属性,同时图表布尔参数保持严格; - 每个 Swagger 与 ReDoc 嵌入都有唯一实例,不再覆盖
window.onload或发布window.ui; - shell Logo、Wordmark 与配置型 Featured Image 统一使用共享 URL 策略;
- 新增
scripts/check-site-markup.py,从消费站解析后的配置中检查原生形态必需的三项 Goldmark 设置。
迁移指南
顺序很重要:先内容(工具默认 dry-run 且幂等),再让构建错误驱动配置与布局的修改。
改写内容前,先确认消费站能够渲染原生形态:
1. 盘点
报告逐站列出工具会改写的每一个 0.4 结构、不会碰的(带 file:line 与原因),
以及改写之后仍会被标记的残留。
2. 内容与 front matter
变换按应用顺序:frontmatter(页面键,含 cascade:)、callout、
param_placeholders、tabs、filetree、gallery、datafence、cards、
fieldsdelim、image、include、fencetitle、badge、eg、reportonly。
--only <key> 选子集。围栏内的文本永远不改写;TOML/JSON front matter 只报告不改写。
在 11 个自有站点上,front matter 变换触及 628 个文件、零 finding。
报告会列出需要人工处理的项:swaggerui → swagger、pageinfo → 提示块、
_param 占位符、iframe/conditional-text/blocks/*、不带 kind 的 xref,
以及必须改成 window.OinkEchartsFunctions 条目的 echarts js 子围栏。
3. 配置
构建站点。每个旧键都会带着替代写法失败:
一份典型的 0.4 hugo.yaml 变成:
删除 params.links、prism_syntax_highlighting、rss_sections、github_url
(改用 github_repo)、algolia_docsearch,以及 giscus 的 lightTheme /
darkTheme URL。
4. cascade 与栏目索引
设置过 params.ui.* 的 cascade 改为裸键——_index.md 里的由变换处理,
hugo.yaml 里手写的 cascade 要自己检查:
5. Sass、布局与站点脚本
assets/scss/_styles_project.scss:删掉@import 'td/color-adjustments-dark'、'td/code-dark'、'td/extra'、'td/extra/bs-defaults'、'td/gcs-search-dark'; 去掉针对.td-navbar-cover、.td-navbar-transparent、.td-box*、-bg-*、oink-*、--oink-*的规则。assets/scss/_variables_project.scss:去掉$td-print-font-name、$td-enable-webfonts、$td-box-colors。layouts/:partial "home-data.html"/"home/section.html"换成landing/…;partial "outputformat.html"换成.Store.Get "tdOutputFormat";删掉调用td/render-heading.html的_markup/render-heading.html;taxonomy_terms_*调用改名;其它复制过的 partial 或钩子在保留前先与 0.5.0 对比。- 站点 JS 与测试:
oink-*id 与data-oink-*属性改为td-*/data-td-*; 动作清单是#td-action-manifest;每页 bundle 是js/page-<hash>.js,旁边是js/actions.js与js/core.js。 - 站点
i18n/覆盖:note、tip… 改名为callout_note、callout_tip…。
6. 数据
把 footer: map 从 data/home/<lang>.yaml 移到 data/footer/<lang>.yaml;
确认 data/home/<lang>.yaml 列出了 sections。
7. 校验
然后检查变化最大的几个面:一个有代码标签页与提示块的文档页、一个有图片的页面
(缩放开与关)、一个 Book 章节及其 _print/ 聚合、index.md Markdown 输出、
一个 RSS feed、首页 landing、暗色调色板。v0.5.0 标签推送后再固定它:
兼容性
- Hugo Extended 0.160.1 仍是最低版本;CI 跑 0.160.1 与 0.164.0,并新增以 Hugo Module 模式构建消费站点。
- 模块路径仍是
github.com/pgsty/oink;消费站点仍不需要 Node.js、CDN 或构建期下载。 - 对 0.4 没有兼容层:改名的键、形态、shortcode、partial、class 要么构建失败要么 直接消失,这是有意的。旧键报错就是迁移指南;其中源自 Docsy 的条目同样服务 从 Docsy 迁来的站点。
- 合理的 Docsy 键保持不变(见配置下的清单);
sidebar_*一族名字未动。 - 交互特性仍然默认关闭:
offline_search、ui.image_zoom、comments、ui.feedback、ui.dark_mode、page_context_menu.assistant_links需要站点主动开启。
验证
主题 CI:34 个检查脚本(i18n 键一致、分类法、字体令牌、导航 / 组件 / 内容原语 /
Book 契约、运行时隔离、侧栏图标、搜索、动作、命令面板、阅读、发布资产、下载、
landing、Book 迁移、共享场景、键盘、shell、命名空间、参数、vendor 清单、输出结构
与安全、30 个面的四态 goldens、代码块、内容与媒体原语、图片缩放、Gallery、组件)、
浏览器运行时单测、迁移工具测试(85)、在 Hugo 0.160.1 与 0.164.0 上无警告构建的
fixture 站点、system 排版预设、遗留 Sass 覆盖、非法预设构建失败,以及新增的
Module 模式消费站点构建。scripts/check-params.py 为每个退役键各构建一个站点
(32 个站点键、14 个页面键),断言每个都失败并指名替代。
本站按上述迁移后在 0.5.0 上无警告构建。最终门禁在 Hugo 0.160.1 与 0.164.0 上各跑 一遍完整矩阵;媒体断言允许各支持版本使用不同的不透明派生缓存哈希,同时仍严格检查 渲染 URL 结构、尺寸、alt 语义与 Zoom 排除。源码校验、本地附注标签、远端标签发布、 消费站固定版本与部署仍是可独立审计的门禁。
完整变更集
完整源码差异见 v0.4.2 到 v0.5.0
与主题的 CHANGELOG.md。
