Hugo 生成文章的目录支持
因为一些长篇的博客文章准备作为浏览器导航页之一使用,需要快速定位链接,因此准备在博客模板中加入目录跳转功能。本文的方式主要参考Hugo添加文章目录toc 。
新建 TOC 模板
按照参考文章的内容,在 [theme]/layouts/patials/
目录下建立 toc.html 这一目录模板,并在里面完善如下内容。
<!-- toc.html -->
<!-- ignore empty links with + -->
{{ $headers := findRE "<h[1-4].*?>(.|\n])+?</h[1-4]>" .Content }}
<!-- at least one header to link to -->
{{ if ge (len $headers) 1 }}
{{ $h1_n := len (findRE "(.|\n])+?" .Content) }}
{{ $re := (cond (eq $h1_n 0) "<h[2-4]" "<h[1-4]") }}
{{ $renum := (cond (eq $h1_n 0) "[2-4]" "[1-4]") }}
<!--Scrollspy-->
<div class="toc">
<div class="page-header"><strong>- CATALOG -</strong></div>
<div id="page-scrollspy" class="toc-nav">
{{ range $headers }}
{{ $header := . }}
{{ range first 1 (findRE $re $header 1) }}
{{ range findRE $renum . 1 }}
{{ $next_heading := (cond (eq $h1_n 0) (sub (int .) 1 ) (int . ) ) }}
{{ range seq $next_heading }}
<ul class="nav">
{{end}}
{{ $anchorId := (replaceRE ".* id=\"(.*?)\".*" "$1" $header ) }}
<li class="nav-item">
<a class="nav-link text-left" href="#{{ $anchorId }}">
{{ $header | plainify | htmlUnescape }}
</a>
</li>
<!-- close list -->
{{ range seq $next_heading }}
</ul>
{{ end }}
{{ end }}
{{ end }}
{{ end }}
</div>
</div>
<!--Scrollspy-->
{{ end }}
引入 TOC 模板
由于本文使用的 noteworthy
模板在 single.html 中只定定义了用于博客文章内容显示的content div
,如果直接在里面按照参考文章的方法在其中加入目录模板,点击跳转之后目录会跟着内容一同移动,而不能保持位置不变。因此我们需要另寻解决方案。经考虑,可以将 toc.html 加入 [theme]/layouts/_default/baseof.html
模板中,在其它页面中,因为不存在多级标题,不会显示目录,在内容页面其可以正常显示。修改后的 baseof.html 如下:
<!DOCTYPE html>
<!-- Default base template. Other templates define the "main" portion in this template -->
<html lang="{{ $.Site.LanguageCode | default "en" }}">
{{ partial "head.html" . }}
<body>
{{ partial "nav.html" . }}
<div id="content" class="content-container">
{{ block "main" . }}
{{ end }}
{{ partial "math.html" . }}
</div>
<!-- toc的位置,它与nav、content两者形成页面的三栏结构 -->
<div id="tableofcontent" class="toc">
{{ if .Site.Params.toc | default false }}
{{ partial "toc" . }}
{{ end }}
</div>
{{ partial "footer-mobile.html" . }}
</body>
</html>
样式调整
以上设置后,在 config.toml 中加入参数可以控制是否显示目录,即:
[params]
toc = true
基本架构是可以的,但是相对位置不对,因此需要重新调整下css布局,在 [theme]/assets/css/partials/_breakpoints.scss
中修改 content class 并新增 toc 的样式设计,主要是调整两者的页面宽度。其他的样式就不需要了,能简则简。其他问题目前没有遇到。
.content-container {
// the changed setting
max-width: 720px;
margin-left: 310px;
padding: 0 1.5em 0 0;
height: 100%;
display: flex;
flex-direction: column;
h1 {
font-size: 1.9em;
border-top: none;
padding-top: 0em;
margin-top: 1.4em;
}
}
// new setting
// TOC
.toc {
position: fixed;
overflow: auto;
height: 100%;
top: 3em;
left: 1100px;
width: 280px;
padding: 0px;
}