Hugo 模版应用指南

这是 Hugo 如何使用模板文件来渲染网站内容、资源和数据的全面指南,包括模板的类型、查找顺序、基础模板、特定页面模板以及如何创建自定义输出格式等

Hugo 模板系统位于项目、主题或模块的 layouts 目录下,包含了一系列用于渲染内容、资源和数据的 HTML 文件。这些模板文件可以是不同的类型,包括基础模板、首页模板、单页模板、分类模板、分段模板、部分模板、内容视图模板、自定义短代码、网站地图模板、RSS 模板、404 错误页面模板、robots.txt 模板、菜单模板、分页模板、内嵌模板和自定义输出格式模板。

Hugo 有一套明确的规则来确定为给定页面选择哪个模板,这些规则从最具体的模板开始查找。模板的类型和用途多样,可以用来定制网站的外观和功能,如创建网站的皮肤、定义首页的独特布局、渲染单个页面、列出特定分类的页面、实现菜单和分页等。此外,Hugo 还提供了一些内嵌模板,以及支持多种输出格式,包括日历事件、电子书格式、Google AMP 和 JSON 搜索索引,或任何自定义文本格式。

1. Introduction

模板系统介绍,包括模板的基础知识、上下文、操作、变量、函数、方法、注释、包含其他模板以及示例等。

Hugo 使用 Go 的 text/templatehtml/template 包来处理模板,其中

  • text/template 用于生成文本输出
  • html/template 用于生成安全的 HTML 输出,防止代码注入

模板文件位于项目的 layouts 目录中,它们使用变量函数方法来转换内容、资源和数据,生成最终的发布页面。

{{ $v1 := 6 }}
{{ $v2 := 7 }}
<p>The product of {{ $v1 }} and {{ $v2 }} is {{ mul $v1 $v2 }}.</p>

Context

模板中的上下文是指传递给模板的数据,可以是简单值,也可以是对象和相关方法。点(.)表示当前的上下文。

模板操作通过大括号 {{}}} 表示,可以包含文字值、变量、函数和方法。

<h2>{{ .Title }}</h2>

{{ range slice "foo" "bar" }}
  <p>{{ . }}</p>
{{ end }}

{{ with "baz" }}
  <p>{{ . }}</p>
{{ end }}

Actions

A template action may contain literal values (booleanstringinteger, and float), variables, functions, and methods.

Whitespace

{{- $convertToLower := true -}}
{{- if $convertToLower -}}
  <h2>{{ strings.ToLower .Title }}</h2>
{{- end -}}

消除空行,包括 spaces, horizontal tabs, carriage returns, and newlines

Pipes

{{ strings.TrimSuffix "o" (strings.ToLower "Hugo") }} → hug
{{ "Hugo" | strings.ToLower | strings.TrimSuffix "o" }} → hug

{{ mul 6 (add 2 5) }} → 42
{{ 5 | add 2 | mul 6 }} → 42

Line splitting

You can split a template action over two or more lines.

{{ $v := or .Site.Language.LanguageName .Site.Language.Lang }}

{{ $v := or 
  .Site.Language.LanguageName
  .Site.Language.Lang
}}

{{ $msg := "This is line one.\nThis is line two." }}

{{ $msg := `This is line one.
This is line two.`
}}

Variables

Hugo 还支持变量的声明和赋值,以及对变量进行操作,如切片和 map。Hugo 提供了大量自定义函数,分为不同的命名空间,并且支持管道操作符来连续调用函数和方法。

With variables that represent a slice or map, use the index function to return the desired value.

{{ $slice := slice "foo" "bar" "baz" }}
{{ index $slice 2 }} → baz

{{ $map := dict "a" "foo" "b" "bar" "c" "baz" }}
{{ index $map "c" }} → baz

With variables that represent a map or object, chain identifiers to return the desired value or to access the desired method.

{{ $map := dict "a" "foo" "b" "bar" "c" "baz" }}
{{ $map.c }} → baz

{{ $homePage := .Site.Home }}
{{ $homePage.Title }} → My Homepage

Functions

Hugo provides hundreds of custom functions categorized by namespace.

{{ $total := add 1 2 3 4 }}

Methods

The most commonly accessed objects are the Page and Site objects. This is a small sampling of the methods available to each object.

{{ .Site.Title }} → My Site Title
{{ .Title }} → My Page Title

{{ $page := .Page.GetPage "/books/les-miserables" }}
{{ $page.Title }} → Les Misérables

Comments

模板中的注释需要使用特定的语法,而不是 HTML 注释,以避免在渲染过程中被错误处理。

{{/* This is an inline comment. */}}
{{- /* This is an inline comment with adjacent whitespace removed. */ -}}

{{ "<!-- I am an HTML comment. -->" | safeHTML }}
{{ printf "<!-- This is the %s site. -->" .Site.Title | safeHTML }}

Include

Hugo 允许通过 template、partial 和 partialCached 函数包含其他模板文件。

Examples

多个示例,展示了如何使用条件语句、循环、重新绑定上下文以及访问站点和页面参数等。

Please see the functionsmethods, and templates documentation for specific examples.

2. Template types

Hugo 静态网站生成器提供了多种模板类型,用于渲染网站内容、资源和数据。

Structure

Hugo 允许开发者通过在项目根目录下的 layouts 目录中创建不同类型的模板来定制网站的渲染效果。

layouts/
├── _default/
│   ├── _markup/
│   │   ├── render-image.html   <-- render hook
│   │   └── render-link.html    <-- render hook
│   ├── baseof.html
│   ├── home.html
│   ├── section.html
│   ├── single.html
│   ├── taxonomy.html
│   └── term.html
├── articles/
│   └── card.html               <-- content view
├── partials/
│   ├── footer.html
│   └── header.html
└── shortcodes/
    ├── audio.html
    └── video.html

开发者需要熟悉 Hugo 的模板查找顺序,以便准确地选择和创建适用的模板类型。

Types

  • 基础模板(baseof.html),用于定义网站的通用外壳结构;
  • 首页模板(home.html),用于渲染网站首页;
  • 单页模板(single.html),用于渲染单个页面;
  • 分区模板(section.html),用于渲染网站内容的分区列表;
  • 分类模板(taxonomy.html),用于渲染分类列表;
  • 术语模板(term.html),用于渲染与特定术语关联的页面列表;
  • 部分模板(如 partials/footer.html),用于渲染网站的组件部分;
  • 内容视图模板,用于在特定内容类型或分区中渲染页面组件;
  • 渲染钩子模板(_markup/*.html),用于自定义 Markdown 转换为 HTML 的过程;
  • 短代码模板(shortcodes/*.html),用于在内容页面中嵌入可重用组件;
  • 其他特殊模板,用于生成站点地图、RSS 订阅、404 错误页面和 robots.txt 文件

3. Template lookup order

模板查找顺序的规则和示例,详细说明了如何根据页面的类型、布局、输出格式、语言和分类等参数来选择合适的模板。

Lookup rules

Hugo 使用一系列预定义的规则来选择用于渲染特定页面的模板。这些规则基于页面的种类(如单页、列表页)、布局设置、输出格式(如 HTML、AMP、JSON、RSS)、语言、类型(根据 front matter 中的 type 或节的根名称)以及部分(对于 section、taxonomy 和 term 类型的页面)。

Target a template

模板查找顺序从最具体性到最不具体性排列,包括项目和主题的布局文件夹中的模板。网页提供了多个示例,包括首页、单页、部分、分类和 RSS 模板的查找顺序,以及如何通过在 front matter 中指定 typelayout 或两者来定位特定模板。此外,还介绍了如何为不同的输出格式和语言设置模板,以及如何为特定的页面类型创建基础模板。最后,网页还提供了一些基于示例配置的模板查找顺序表格,以帮助用户更好地理解和应用这些规则。

4. Base Templates

https://www.youtube.com/watch?v=QVOMCYitLEc

Base templates 主要介绍了 Hugo 静态网站生成器中的基础模板(base templates)和块(block)构造的使用方法,以及如何通过它们定义和覆盖网站的主要模板结构。

在 _default/baseof.html 文件中定义了一个简单的基础模板,它为所有页面提供了一个通用的 HTML 结构,包括头部、标题和页脚块。这些块可以包含默认内容,并且可以在特定的模板中被覆盖。

5. Home Templates

https://www.youtube.com/watch?v=ut1xtRZ1QOA

Home templates 介绍了 Hugo 网站首页模板的使用和配置方法。

Hugo 允许用户为网站的首页创建一个独特的模板。首页模板是构建网站时唯一必需的模板,对于引导新网站和模板或开发单页网站非常有用。

Hugo 在查找首页模板时按照以下顺序进行查找:

  1. layouts/index.html
  2. layouts/home.html
  3. layouts/list.html
  4. layouts/_default/{index, home, list}.html 首页内容和 front matter 可以通过在 content 文件夹根目录下的 _index.md 文件添加。

vi themes/twotwo/layouts/_default/home.html

{{ define "main" }}
  {{ .Content }}
  {{ range first 7 site.RegularPages }}
    <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
    {{ .Summary }}
  {{ end }}
{{ end }}

首页显示最新 7 篇(first 7) Post。

6. Single templates

Single templates 介绍了如何在 Hugo 静态网站生成器中创建和使用单页模板(single templates),以及如何通过继承基础模板来定制页面内容的展示。

单页模板的使用和创建过程。首先,介绍了如何创建一个基本的单页模板,该模板继承自网站的基础模板,并展示了如何在模板中使用 .Title 和 .Content 变量来显示页面标题和内容。接着,网页提供了一个更高级的单页模板示例,该示例展示了如何在页面中包含创建日期、内容以及与页面相关的 “标签” 分类列表。此外,还提到了模板查找顺序的重要性,强调在选择模板路径时应考虑到所需的具体程度。最后,网页还提供了关于如何改进该页面内容的信息,并注明了上次更新的日期和具体更新内容。

{{ define "main" }}
  <h1>{{ .Title }}</h1>

  {{ $dateMachine := .Date | time.Format "2006-01-02T15:04:05-07:00" }}
  {{ $dateHuman := .Date | time.Format ":date_long" }}
  <time datetime="{{ $dateMachine }}">{{ $dateHuman }}</time>

  {{ .Content }}
  {{ partial "terms.html" (dict "taxonomy" "tags" "page" .) }}
{{ end }}

7. Section templates

Section 模板 的使用方法,包括如何向 Section 模板添加内容和前端数据,以及如何设置和查找 Section 模板,还给出了创建默认 Section 模板和使用 .Site.GetPage 方法的示例。

Section 模板是 Hugo 中用于列出 section list 的模板,可以通过 _index.md 文件添加内容和前端数据。

Section 模板的查找顺序遵循 Hugo 的模板查找机制。

创建默认 Section 模板时,可以使用 .Content 来显示内容,使用 where 和 .Paginate 来过滤和分页列出页面。

.Site.GetPage 方法可以用来获取 Section 的标题,但它需要对应 Section 目录下存在 _index.md 文件。如果文件不存在,将返回 nil 并输出 Section 的默认标题。

Example: creating a default section template

layouts/_default/section.html

{{ define "main" }}
  <main>
    {{ .Content }}

    {{ $pages := where site.RegularPages "Type" "posts" }}
    {{ $paginator := .Paginate $pages }}

    {{ range $paginator.Pages }}
      <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
    {{ end }}

    {{ template "_internal/pagination.html" . }}
  </main>
{{ end }}

Site Method: MainSections

params:
  mainSections:
  - books
  - films
{{ range where .Site.RegularPages "Section" "in" .Site.MainSections }}
  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}

8. Taxonomy templates

Taxonomy (分类)模板功能,允许开发者自定义分类页面的外观和内容。通过创建 layouts/_default/taxonomy.html 文件,可以定义一个基本的分类模板,该模板可以继承网站的基础布局,并显示当前分类下的所有项。

在模板中,可以使用 .Data.Singular 和 .Data.Plural 来获取分类的单数和复数名称,使用 .Data.Terms 来获取包含所有分类项和相关页面的 Taxonomy 对象。分类项可以按字母顺序排列使用 .Data.Terms.Alphabetical,或者按项关联页面数量排列使用 .Data.Terms.ByCount。此外,可以创建特定分类的模板文件,例如 layouts/authors/taxonomy.html,以提供更具体性的自定义。在分类模板中,还可以展示每个分类项的元数据,例如作者的机构和头像图片。这些功能使得 Hugo 用户能够灵活地管理和展示网站内容的分类结构。

Sort

{{ define "main" }}
  <h1>{{ .Title }}</h1>
  {{ .Content }}
  {{ range .Data.Terms.ByCount }}
    <h2><a href="{{ .Page.RelPermalink }}">{{ .Page.LinkTitle }}</a> ({{ .Count }})</h2>
  {{ end }}
{{ end }}
  • {{ range .Data.Terms.ByCount }} Sort by term count
  • {{ range .Data.Terms.Alphabetical }} Sort alphabetically

Display metadata

通过在内容目录中创建对应的分支捆绑包(branch bundle),可以为每个分类项添加元数据,并在分类模板中展示这些信息,如作者的机构和头像。

9. Term templates

Term (术语)模版,渲染与当前术语关联的页面列表,定制和展示术语的元数据。

ugo 允许用户通过创建术语模板来定制特定术语的页面展示。术语模板继承自基础模板,并在 layouts/_default/term.html 中渲染与当前术语相关联的页面列表。

用户可以通过设置 capitalizeListTitles 为 false 来避免术语名称的自动大写。

layouts/_default/term.html

{{ define "main" }}
  <h1>{{ .Title }}</h1>
  {{ .Content }}
  {{ range .Pages }}
    <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
  {{ end }}
{{ end }}

10. Partial templates

https://www.youtube.com/watch?v=pjS4pOLyB7c

Partial templates 介绍如何使用和组织局部模板,以及如何在模板中传递和返回值,以及如何缓存局部模板以提高性能。

layouts/
└── partials/
    ├── footer/
    │   ├── scripts.html
    │   └── site-footer.html
    ├── head/
    │   ├── favicons.html
    │   ├── metadata.html
    │   ├── prerender.html
    │   └── twitter.html
    └── header/
        ├── site-header.html
        └── site-nav.html

Partial Templates 是 Hugo 中用于创建更加模块化和可重用的组件的工具。它们位于 layouts/partials 目录下,可以通过子目录进行组织。

在模板中调用局部模板时,需要使用 {{ partial "<PATH>/<PARTIAL>.html" . }} 的格式,并确保传递了上下文(.)。

Examples

header.html

The following header.html partial template is used for spf13.com:

layouts/partials/header.html

<!DOCTYPE html>
<html class="no-js" lang="en-US" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
<head>
    <meta charset="utf-8">

    {{ partial "meta.html" . }}

    <base href="{{ .Site.BaseURL }}">
    <title> {{ .Title }} : spf13.com </title>
    <link rel="canonical" href="{{ .Permalink }}">
    {{ if .RSSLink }}<link href="{{ .RSSLink }}" rel="alternate" type="application/rss+xml" title="{{ .Title }}" />{{ end }}

    {{ partial "head_includes.html" . }}
</head>

footer.html

The following footer.html partial template is used for spf13.com:

layouts/partials/footer.html

<footer>
  <div>
    <p>
    &copy; 2013-14 Steve Francia.
    <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons Attribution">Some rights reserved</a>;
    please attribute properly and link back.
    </p>
  </div>
</footer>

11. Content view templates

使用 Content view templates 创建不同的内容展示方式,以便在列表和摘要视图中灵活呈现内容。

开发者可以通过在每个内容类型目录中创建具有特定视图名称的模板来实现这一点。例如,可以为 posts 和 projects 内容类型创建 li 和 summary 视图,这些视图位于 single.html 旁边。

12. Create your own shortcodes

Create your own shortcodes 主要介绍了如何在 Hugo 静态网站生成器中创建和使用自定义短代码(shortcodes),以及如何通过短代码模板文件扩展 Hugo 的功能,实现在内容文件中嵌入复杂布局和功能的方法。

自定义短代码的 HTML 模板文件需要放置在 layouts/shortcodes 目录下,并且可以通过文件名来调用短代码。

13. Sitemap templates

Hugo 提供了内置的网站地图模板(Sitemap templates),支持单语言和多语言项目,并允许用户配置和覆盖默认设置。

14. RSS templates

RSS templates

15. Custom 404 page

Custom 404 page

16. robots.txt template

robots.txt template

17. Menus

Menus 主要介绍了在 Hugo 静态网站生成器中如何使用模板创建和渲染菜单。

Overview

决定菜单渲染方式的三个因素:

  1. 菜单项的定义方法(自动、前置元数据或站点配置)
  2. 菜单结构(扁平或嵌套)
  3. 菜单项的本地化方法(站点配置或翻译表)

Example

示例模板,展示了如何递归地 “遍历” 菜单结构,渲染出本地化且可访问性良好的嵌套列表。该模板还展示了如何在当前页面上标记菜单项的活动状态。

18. Pagination

Pagination 介绍了 Hugo 静态网站生成器中的分页功能,包括分页的概念、配置、方法、示例、缓存、分组以及导航。

大型列表页面不仅不利于用户导航,还会导致加载时间延长和信息检索困难。为了改善这一点,Hugo 提供了对 homesectiontaxonomy 和 term 页面进行分页的配置选项,包括是否禁用首页别名(disableAliases)、每个分页器中的页面数量(pagerSize)和分页 URL 路径(path)。在多语言站点中,可以为每种语言定义不同的分页行为。

Configuration

pagination:
  disableAliases: false
  pagerSize: 10
  path: page

Examples

{{ $pages := where site.RegularPages "Type" "posts" }}
{{ $paginator := .Paginate $pages.ByTitle 7 }}

{{ range $paginator.Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}

{{ template "_internal/pagination.html" . }}

Grouping

{{ $pages := where site.RegularPages "Type" "posts" }}
{{ $paginator := .Paginate ($pages.GroupByDate "Jan 2006") }}

{{ range $paginator.PageGroups }}
  <h2>{{ .Key }}</h2>
  {{ range .Pages }}
    <h3><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h3>
  {{ end }}
{{ end }}

{{ template "_internal/pagination.html" . }}

19. Embedded templates

Hugo 提供了一系列内嵌模板(Embedded templates),用于实现常见的网站功能,如 Disqus 评论系统、Google Analytics 分析、Open Graph 协议、Schema 微数据以及 Twitter Cards 等。

Disqus

Hugo 内置了 Disqus 评论系统的模板,用户可以通过在 layouts/partials 目录下创建同名文件来覆盖内嵌模板,并在模板中通过 {{ partial "disqus.html" . }} 调用。配置 Disqus 需要在网站配置文件中设置 shortname,并且可以在内容的前端元数据中设置 disqus_identifierdisqus_title 和 disqus_url

Google Analytics

Hugo 支持 Google Analytics 4,并提供了相应的内嵌模板。开发者可以通过将模板代码复制到 layouts/partials 目录下的文件中来自定义模板,并通过 {{ partial "google_analytics.html" . }} 调用。在配置文件中设置 googleAnalytics.ID 来配置跟踪 ID。

Open Graph

Hugo 提供了 Open Graph 协议的内嵌模板,用于定义网页在社交图谱中作为丰富对象的元数据。开发者可以通过 {{ partial "opengraph.html" . }} 调用模板,并在网站配置文件和内容的前端元数据中设置相关参数,如 descriptionimages 和 title

Schema

Hugo 包含了用于渲染微数据 meta 标签的内嵌模板,可以通过 {{ partial "schema.html" . }} 调用。

Twitter Cards

Hugo 提供了 Twitter Cards 的内嵌模板,用于在推文中链接到网站时展示丰富媒体内容。开发者可以通过 {{ partial "twitter_cards.html" . }} 调用模板,并在配置文件和内容的前端元数据中设置 descriptionimages 和 title。如果没有在前端元数据中指定 images,Hugo 将搜索带有 featurecover 或 thumbnail 的图片资源。

20. Custom output formats

Hugo 网站构建工具支持多种自定义输出格式(Custom output formats),包括日历事件、电子书格式、Google AMP 和 JSON 搜索索引,以及任何自定义文本格式,并提供了如何配置媒体类型和输出格式以及创建相应模板的指南。

Built with Hugo