83、【Ubuntu】【Hugo】搭建私人博客:文章目录(二)

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Hugo】搭建私人博客:文章目录(一)

分析了文章的目录 TOC 功能,并分析了 PaperMod 主题下的默认 toc.html 模板,其中分析完了【提取标题】,下面继续【<details> 可折叠容器】的分析

搭建私人博客

继续看 【<details> 可折叠容器】

  • {``{if (.Param "TocOpen") }} open{``{ end }}:Hugo 模板语法,作用是如果在文章的标题开头写了 TocOpen = true,比如

    或者在 hugo.toml 配置文件中,加入了这个全局配置项,那么 Hugo 在渲染这里时,会自动加上 open 这个属性,这里就会变成 <details open>,表示页面一打开,目录就展开(本来默认是收起的)
  • accesskey="c"设置一个快捷键 ,在大多数浏览器中,按下 Alt + C(Windows)就能聚焦到这个 <summary>
  • titile="...":鼠标悬停在这里时,显示的提示文字,告诉用户这里可以使用快捷键

OK,看第三部分:选择 TOC 的生成方式

如果在文章,或 hugo.toml 的全局配置中,启用了配置项 UseHugoToc = true,就会直接使用 Hugo 内置的 .TableOfContents,更简单,但样式(风格)和 PaperMod 不一定是匹配的,否则就执行下面复杂的手动解析过程(PaperMod 默认方式,样式更统一)

第四部分:手动构建嵌套列表(核心难点)

这部分很复杂,因为 Hugo 模板语言没有循环栈,或者递归函数,只能用模拟栈的方式去处理嵌套层级

这里要区分下 Hugo 模板语言和 Go 语言,虽然 Hugo 是用 Go 语言开发的,但在比如 toc.html 这样模板文件上,写的不是 Go 代码,而是 Hugo 的模板语言(基于 Go 的 text/templatehtml/template

这个模板语言有如下特点:

  • 支持变量,if 条件判断,range 循环等
  • 不支持函数定义,递归,复杂数据结构的操作(比如栈,队列等)
  • 不能直接把字符串转成整数,所以这里需要用 len (seq "$headerLevel") 这样的技巧

简单来说,Hugo 模板是一个受限,表达能力有限的 DSL(领域特定语言),和完整的 Go 语言有很大区别

OK,继续看这段代码

go 复制代码
 {{- $largest := 6 -}}
 {{- range $headers -}}
 {{- $headerLevel := index (findRE "[1-6]" . 1) 0 -}}
 {{- $headerLevel := len (seq $headerLevel) -}}
 {{- if lt $headerLevel $largest -}}
 {{- $largest = $headerLevel -}}

这段代码的的含义是,找出最小标题级别,比如(h22h33,则最小是 2),这里 $largest 实际上是最小的标题数字(对应最高层级,比如 h2 在标题上比 h3 要大)

这里可能有人会有疑问,如果按这么说的话,那最小的不都是 h1 吗?

答案是不一定,因为有人可能不按常理出牌,他可能会跳过 h1 标题,直接用 h2,甚至 h3 标题开头,就比如

md 复制代码
---
title: "跳过 h1 的文章"
toc: true
---

## 这是 h2 标题
一些内容...

### 这是 h3 子标题
更多内容...

可以看到,这里并没有 h1 标题,所以 PaperMod 的 toc.html 处理中,并不假设必须有 h1h2,而是动态找出所有标题中最小的层级(比如全是 h3/h4,就以 h3 为根),并以这个最小层级作为 TOC 的顶层,所有更深的标题都作为它的子项,相当于把 h3 当做逻辑上的顶级标题来对待,就好像一本书,如果第一章直接从 【1.3 小节】开始(中间没有【1.1 小节】,【1.2 小节】),那就把 【1.3 小节】当成第一章的主标题来列目录,虽然奇怪,但是技术上可行


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Hugo】搭建私人博客:文章目录(三)

相关推荐
想进部的张同学10 小时前
RK3588开发板安装GStreamer硬件加速插件完整指南 成功版本(docker)
运维·docker·容器·rkmpp
康康的AI博客10 小时前
AI辅助文献综述:基于Gemini 2.5 Pro的自动化研究革命
运维·自动化
陈聪.10 小时前
HRCE简单实验
linux·运维·数据库
涟漪海洋10 小时前
docker启动容器覆盖镜像中的命令
运维·docker·容器
haluhalu.10 小时前
从 Linux 线程控制到 pthread 库
java·linux·服务器
水境传感 张园园10 小时前
自来水厂水质监测站:用数据守护饮水安全
运维·服务器·网络
2023自学中10 小时前
Cortex-M系列,Cortex-A系列,汇编启动文件的区别
linux·嵌入式硬件
APIshop10 小时前
实战代码解析:item_get——获取某鱼商品详情接口
java·linux·数据库
楼田莉子10 小时前
Linux系统小项目——“主从设计模式”进程池
linux·服务器·开发语言·c++·vscode·学习
七夜zippoe10 小时前
2026年1月远程工具横评:UU远程以全能六边形战士之姿,重塑行业性能标杆
运维·效率·远程·uu·安全锁