将目录添加到Hugo主题

目录

置 简码 单页模板/部分 i18n 造型 用法 结论

这篇文章介绍了雨果主题的另一个增强功能 - 目录 (TOC)。它基于 Hugo 的内置功能,可以解析 Markdown 内容并生成可在模板中使用的目录。本文是“雨果主题食谱”系列的第二篇。

通常,我的教程或文章从介绍部分开始。然后是详细步骤或实现细节,其中每个部分都以 H3() 标题为标题。为了使我的文章中的导航更容易,在介绍部分之后,我向以下部分添加了锚链接列表;例如,链接将对应于标题为 .这样的清单只不过是一个目录。###Install Hugo### Install Hugo

因此,我想自动创建目录,而不是手动添加锚链接列表。这可以通过使用 Hugo 的内置功能自动解析 Markdown 内容并创建目录来实现。基于此功能,我实现了一个解决方案,该解决方案允许使用简码或页面模板显示目录。

因此,让我们检查一下此解决方案的详细信息。我在下面描述的实现的源代码可以在我对 Bilberry 主题的贡献中找到。

配置

要定义目录中需要包含的标题级别,您必须将以下内容添加到站点配置文件中,例如:config.toml

1
2
3
4
5
[markup]
  [markup.tableOfContents]
    startLevel = 2
    endLevel = 5
    ordered = false

该设置定义 Hugo 开始呈现目录时的标题级别。设置当 Hugo 停止生成目录时的标题级别(包括)。在上面的配置中,从 H2() 到 H5()(包括 H<>() 和 H<>()的所有标题都将用于创建目录。该设置确定要生成的列表类型,即使用标记的有序列表或使用标记的无序列表。

简码

根据 Hugo 文档,如果您的降价中有适当的标题,Hugo 将提取它们并存储在名为 的页面变量中。 由于它只能在 Go 模板中使用,因此您不能仅放置在内容文件中并期望显示目录。您可以做的是将其包装在简码中。在站点根目录中,创建包含以下内容的文件:.TableOfContents.TableOfContentslayouts/shortcodes/toc.html

1
{{ .Page.TableOfContents }}

单页模板/部分

然后,您可以更进一步,完全自动化目录的创建。То 这样做,首先,您需要将前言变量添加到默认原型模板中,该模板用于在 Hugo 主题中创建空内容文件。在Bilberry 主题中,它是原型/default.md。变量的默认值应设置为 :toc toc false

1
toc: false

其次,如果要根据内容中的字数使TOC呈现成为条件,请将参数添加到站点配置文件中并设置您认为合适的值,例如:tocMinWordCount500

1
2
3
[param]
  # Minimum word count to display the Table of Contents
  tocMinWordCount = 500

第三,在单页模板中,在显示内容之前添加以下代码片段:

1
2
3
4
{{ if and (.Params.toc) (gt .WordCount .Site.Params.tocMinWordCount ) }}
  <h2>{{ i18n "tableOfContents" }}</h2>
  {{ .TableOfContents }}
{{ end }}

例如,一个简单的页面模板可能如下所示:layout/_default/single.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{{ define "main" }}
<main>
  <article>
    <header>
      <h1>{{ .Title }}</h1>
    </header>

    {{ if and (.Params.toc) (gt .WordCount .Site.Params.tocMinWordCount ) }}
      <h2>{{ i18n "tableOfContents" }}</h2>
      {{ .TableOfContents }}
    {{ end }}

    {{ .Content }}
  </article>
</main>
{{ end }}

因此,在上面的示例中,仅当满足以下条件时,才会呈现目录:

  • 页面变量设置为toctrue
  • 内容中的字数大于“站点配置”设置中定义的值tocMinWordCount
  • 内容具有适当的标题,这些标题在 和 站点配置设置定义的范围内startLevelendLevel

i18n

由于该函数用于显示标签,因此请在相应的 i18n 配置文件中为键定义一个值,例如 i18n/en.toml:i18nTable of ContentstableOfContents

1
2
[tableOfContents]
  other = "Table of Contents"

造型

最后,最后要做的是使用 CSS 设置变量生成的 HTML 输出的样式。HTML 输出由一个具有子元素(或取决于设置)的元素组成,该子元素又包含一个带有元素列表的子 /。每个都包含一个指向相应内容标题的元素。 下面是此类 HTML 的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<nav id="TableOfContents">
  <ul>
    <li>
      <ul>
        <li><a href="#header-h2-1">Header H2 1</a></li>
        <li><a href="#header-h2-2">Header H2 2</a></li>
        <li><a href="#header-h2-3">Header H2 3</a></li>
      </ul>
    </li>
  </ul>
</nav>

如何设置目录的样式在很大程度上取决于您使用的主题。在我的 Bilberry 主题中,样式是使用 SCSS 语法实现的,如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#TableOfContents {
  display: block;
  background: transparent;
  padding-bottom: 2rem;
  font-size: 1.2em;

  ul {
    display: list-item;
    padding-left: 0;
    
    &:not(:first-child) {
      display: list-item;
      padding-left: 0.9rem;
      font-size: 95%;
    }
  }

  li {
    display: inherit;
    color: $text-color;

    a {
      color: inherit;
      text-align: left;
      padding: 0;

      &:hover {
        color: $highlight-color;
        background-color: transparent;
      }
    }
  }
}

具有上述样式的目录将如下所示:

[图片]

用法

如果要在降价内容中的特定点显示目录,请使用简码:toc.html

1
{{ <toc> }}

如果要在内容的开头显示目录,请将页面变量设置为 :toc true

1
toc: true

结论

总而言之,所提出的解决方案提供了两个用于自动创建目录的选项。您可以使用其中之一或两者。简码方法更直接,对您选择的雨果主题的实现的依赖性更小。此外,您可以将简码放置在降价内容中的任何位置。另一方面,单页模板/部分方法更依赖于主题,并且生成的目录在显示的内容中具有固定的位置。不过,只需启用相应的页面变量即可更轻松地使用。

updatedupdated2023-06-092023-06-09