目录

Hugo博客侧边导航栏

感觉博客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>

参考资料

  1. 添加 gitalk 评论和 disqus 懒加载;添加文章目录导航 https://github.com/liuzc/LeaveIt/pull/11/commits/d5aa80b08057bbdf5ac7f7c319ce68e5646226b9
  2. Hugo官方文档TOC https://gohugo.io/content-management/toc/
  3. Hugo TOC的issue https://github.com/gohugoio/hugo/issues/1778