落地页契约
本契约描述 OINK v1.3.1。主题开发使用同级 checkout;发布验收在关闭替换与 工作区后验证公开模块。消费站升级与部署分别检查。
外壳与数据
任何普通页面都可以声明 layout: landing。它渲染顶部导航栏、全宽画布与页脚,
不显示 docs 侧栏或 TOC 导轨。首页继续把 data/home/<lang>.yaml 作为兼容的创作
路径,并通过同一个渲染器处理。
非首页依次从内联 front matter、data/landing/<key>/<lang>.yaml、单个
data/landing/<key>.yaml 中精确匹配语言的条目,以及英文或无后缀本地数据中
解析 sections。落地页绝不抓取可变事实;星标数、价格、截图与头像必须在 Hugo
运行前提交或生成。
params.ui.landing_search 默认为 true,而且只有启用 offline_search 时才打开
既有本地命令面板。params.ui.github_stars 与 params.ui.alt_site 是可选的本地
界面事实。
区块注册表
注册表恰好有 22 种内置区块:
hero、metrics、capabilities、principles、cards、logo-wall、gallery、testimonials、contributors、faq、markdown、cta;pricing、pricing-compare、command-box、steps、timeline、code-plate、preview、case-study、download、bar-chart。
条目可以是类型字符串,也可以是包含 type、key、id、enabled、内联
data 或有意指定的本地 partial 的 map。作者提供唯一 ID,OINK 把它规范为
锚点安全值。未知类型遵循共享的警告与安全回退策略,绝不静默消失;发布时
--panicOnWarning 会拒绝它。内置区块由 landing/ partial 负责;已经移除的
home/ partial 名称不是 API。
preview 通过站点渲染钩子,把 Markdown source 放在 RenderString 输出旁,
因此其内容会登记与 docs 内容相同的运行时。源码面板使用 Chroma,并带默认值为
page.md 的 file 名称。Markdown 输出使用四个反引号包围的 markdown 围栏;
RSS 省略它。面板标签来自主题 i18n。
hero.align 可取 start 或 center。Center 只适用于文本;与图片组合时会警告,
并回退到 start,同时保留图片。download 消费与 shortcode 相同的
data/download/<key>.yaml 结构,不引入第二套 channel、版本、发布或插值模型。
语言、运行时与无障碍
叙述文件可以按语言拆分。共享事实字段依次解析 <field>_<exact language>——其中
- 规范为 _——再解析 <field>_<primary language>,最后解析无后缀字段。
不接受 camelCase 别名。叙述字段通过站点渲染钩子渲染行内或区块 Markdown;复用
为无障碍名称的值会转为纯文本。区块文案属于站点数据;只有主题控件使用 OINK
i18n。
每次内置 Markdown 渲染都有稳定的区块、条目和字段作用域。重复正文和跑马灯
副本使用不同的自动代码 ID,复制按钮、标题、视口和行链接也随之对应。作用域
不依赖渲染次序或输出次序。显式代码 ID 保持不变;整页出现重复显式 ID 时会
警告,严格构建会失败。自定义 partial 重复调用 Markdown 辅助模板时,应为
每个渲染位置传入不同且稳定的 scope。
区块 Markdown 正文使用共享 .td-content 组件作用域,并登记实际内容所需的
运行时。代码折叠、表格、图片及其他内容组件在落地页内保留正常样式。该作用域
仅包围正文,不改变外层营销标题或网格。
交互式 HTML 设置 hasLanding,从而只按需添加 landing.js。运行时复用
OinkSurfaceCoordinator,负责出现动画、数字递增、复制、紧凑菜单与主题图片
增强。没有 JavaScript 或 Landing 脚本加载失败时,服务端输出仍然完整可见。
出现动画的候选元素默认可见,只有成功安装观察器后才标记为等待动画。数字指标
由服务端按配置输出完整的数字格式、前缀和后缀,递增动画的最后一帧使用同一显示文本。
交互式 HTML 中的代码面板可通过键盘聚焦,包括 capabilities 的代码视图与
code-plate 的逐行代码。读者可以用 Tab 进入长行区域,再用方向键滚动,不依赖
浏览器自动把滚动容器加入焦点顺序。这两种逐行渲染器不为静态 Print 输出添加
焦点入口。
跑马灯只用 CSS 复制;副本带 aria-hidden 与 inert,本地化复选框无需
JavaScript 也能持久保存暂停状态。减少动画会停用动画,强制颜色保留控件,主题
图片响应共享主题事件。顶部导航栏的 mega 面板与其 columns 参数已退役:仍然配置 columns 的菜单会告警并保持单列。紧凑菜单使用真实链接
与按钮,不捕获焦点,也不复制桌面导航树。
输出与兼容性
| 输出 | 契约 |
|---|---|
| HTML | 完整静态区块加渐进增强 |
| 静态网格与内容,移除控件 | |
| Markdown | 不带主题 class 的标题、正文、列表、表格与代码 |
| RSS | 配置后输出有效 RSS 文档;省略落地页区块 |
非 HTML 输出不设置 Landing 标志或运行时。根相对链接与资源遵循部署子路径;普通 构建不下载图片。
启用 RSS 时使用共享 feed 渲染器,实际输出与 HTML head 公布的 feed 地址一致。 章节与首页 feed 保留普通子页面摘要;显式启用 RSS 的普通页面可以输出空 channel。 省略落地页区块不等于生成空文件,也不能公布不存在的 feed。
已经移除的 0.4 组件形态属于迁移工具,不是并行的落地页实现。OINK 不增加价格 周期切换、远程事实 API、热点编辑器、可视化构建器或第二套注册表。既有首页数据 与显式自定义区块 partial 继续有效。
视觉预设
Paper 去掉首屏网格与光晕,使用暖色阴影、Plex Sans 展示标题和链接色主按钮。 Slate 保留技术网格、光晕、Chakra Petch 标题与原有主按钮颜色。两者共用分区结构, 不改变密度。手机抽屉包含共用外观表单,参见外壳契约。
显式开启的 Ink/Terminal 实验也去掉网格、光晕与阴影。Ink 使用高字重 Inter 标题、 直角卡片与红色主按钮;Terminal 使用等宽标题、2 px 圆角、琥珀主按钮与静态光标形 装饰。两者都不新增动画,不改变分区列结构。