感觉博客TOC(侧边导航栏,Table of Content)还是挺有必要的,在LeaveIt主题issue有人谈到TOC,但是我实践了一遍好像不太行,所以我自己又另找了方法, 需要说明的是我并没有系统学过前端开发,所以可能会有疏漏的地方,不过从结果上来看是能用的。
这篇文章是根据LeaveIt主题来做的,所以部分文件名可能会有差别。此外,这个方法的toc主要在Chrome浏览器上进行测试。
Step 1. 新建并编写toc.html文件
在文件夹\layouts\partials中新建文件toc.html,写入以下代码。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 | {{ if (.Params.toc | default true ) }}
<div class="post-toc" id="post-toc">
<aside>
    <header>
    <h3>{{.Title}}</h3>
    </header>
    {{ $emtLiPtrn := "(?s)<ul>\\s<li>\\s<ul>(.*)</li>\\s</ul>" }}
    {{ $rplcEmtLi := "<ul>$1" }}
    {{ .TableOfContents | replaceRE $emtLiPtrn $rplcEmtLi | safeHTML }}
    <!-- https://github.com/gohugoio/hugo/issues/1778#issuecomment-483880269 -->
    <!-- {{.TableOfContents}} -->
</aside>
<a href="#" id="toc-toggle"></a>
</div>
{{ end }}
 | 
 
说明:
实际上{{.TableOfContents}} 就够用了,但是在Hugo TOC 的issue里面存在一个开头没有H1的bug,所以以上代码是一种改进方案。
Step 2.  修改single.html文件
在layouts\_default文件夹中找到single.html这个文件,single.html是文章的布局文件,在合适的位置(我直接写在文件的最前面)插入以下代码。
| 1
2
3
 | <div style="position: fixed; right:5px;max-width:300px; overflow:auto; top: 100px; width: 10vw; bottom:50px">
{{ partial "toc.html" . }}
</div>
 | 
 
说明:
max-width:300px;当TOC的内容过长时会换行。
overflow:auto; top: 100px; bottom:50px作用为TOC过长时,出现滚轮。
p.s.优化滚轮外观:
因为默认的滚轮宽度很宽很违和,添加以下代码可以使滚轮变窄(在Chrome浏览器上有效,但是Edge浏览器上样式不会变)。可以直接将下面的代码写入single.html文件开头,即<head><style type="text/css">这里是下面的代码</style></head>
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 | ::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-thumb {
  height: 40px;
  background-color: #eee;
  border-radius: 16px;
  &:hover {
    background-color: #ddd;
  }
}
 | 
 
Step 3. 处理手机兼容性的问题
设置成:如果是移动设备就不要显示TOC了。
在\assets\css\_custom.scss文件中加入以下代码。
| 1
2
3
4
5
 | @media only screen and (max-width: 1224px) {
    .post-toc {
        display: none;
    }
} 
 | 
 
这样就已经完工了~
Step 4. (可选)优化代码
p.s. 如果想将样式分离(这样可能可以避免后期出现滚轮样式冲突的问题),就继续在\assets\css\_custom.scss文件中写入下面的代码。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 | .post-toc{
    position: fixed; left:20px;max-width:300px; overflow:auto; top: 100px; bottom:50px;
}
.toc-wrapper {
    ::-webkit-scrollbar {
      width: 6px;
      height: 8px;
    }
    ::-webkit-scrollbar-thumb {
      height: 40px;
      background-color: #eee;
      border-radius: 16px;
      &:hover {
        background-color: #ddd;
      }
    }
}
 | 
 
并将在Step2介绍的\layouts\partials\toc.html的代码修改成下面的代码(注意class一定要改成toc-wrapper),并删除Step2里面外观优化的<head><style type="text/css">这里是下面的代码</style></head> 这段代码。
| 1
2
3
 | <div class = "toc-wrapper">
{{ partial "toc.html" . }}
</div>
 | 
 
测试一下
H1
H2
H3
H4
H5
这是一个很长的用来测试的H1标题,这是一个很长的用来测试的标题
这是一个很长的用来测试的H2标题,这是一个很长的用来测试的标题很多个H1
很多个H2
很多个H2
很多个H2
很多个H2
很多个H2
很多个H2
很多个H2
很多个H2
很多个H2
很多个H2结束
文章字数统计
可以在侧边栏里面加上字数统计,如果字数多的时候才显示侧边栏。主要利用的是Hugo的一个Variable——WordCount,修改toc.html文件,最终修改之后的代码如下。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 | <div class="post-toc">
{{ if and (gt .WordCount 80 ) (.Params.toc | default true ) }} <!-- 关键是这一行 -->
<aside>
    <header>
    <h4>{{.Title}}の字数: {{ .WordCount }}</h4> 
    </header>
    {{- $toc := .TableOfContents -}}
    {{- $toc := replaceRE `<ul>\n<li>\n<ul>` `<ul>` $toc -}}
    {{- safeHTML $toc -}}
</aside>
<a href="#" id="toc-toggle"></a>
{{ end }} <!-- 不要忘记写end -->
</div>
 | 
 
参考资料
- 添加 gitalk 评论和 disqus 懒加载;添加文章目录导航 https://github.com/liuzc/LeaveIt/pull/11/commits/d5aa80b08057bbdf5ac7f7c319ce68e5646226b9
- Hugo官方文档TOC https://gohugo.io/content-management/toc/
- Hugo TOC的issue https://github.com/gohugoio/hugo/issues/1778