这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

文档

1 - 关于Hugo

关于 Hugo

https://gohugo.io/about/

Hugo is not your average static site generator.

​ Hugo 不是一般的静态站点生成器。

1.1 - Hugo 的安全模型

Hugo’s Security Model - Hugo 的安全模型

https://gohugo.io/about/security-model/

Hugo 安全模型的概述。

运行时安全

​ Hugo 生成静态输出,因此一旦构建完成,运行时就是浏览器(假设输出为 HTML)和任何与之集成的服务器(API)。

​ 但在开发和构建站点时,运行时是 hugo 可执行文件。保护运行时可能是一个真正的挑战

​ Hugo 的主要方法是沙盒化和采用严格默认的安全策略:

  • Hugo 有一个虚拟文件系统,只有主项目(而不是第三方组件)可以挂载项目根目录外的目录或文件。
  • 只有主项目可以遍历符号链接。
  • 用户定义的组件只能以只读方式访问文件系统。
  • 我们调用一些外部二进制文件来支持 Asciidoctor等功能,但这些二进制文件及其标志都是预定义的,并且默认情况下被禁用(请参见以下安全策略)。运行任意外部操作系统命令的一般函数已经讨论过,但由于安全问题而未实现。

安全策略

​ Hugo 具有内置的安全策略,限制对 os/exec、远程通信等的访问。

​ 默认配置如下。任何使用安全策略允许列表中不存在的功能构建都将失败,并显示详细的消息,说明需要进行哪些操作。这些设置大多是允许列表(字符串或切片、正则表达式none不匹配任何内容)。

=== “yaml”

```yaml
security:
  enableInlineShortcodes: false
  exec:
    allow:
    - ^dart-sass-embedded$
    - ^go$
    - ^npx$
    - ^postcss$
    osEnv:
    - (?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+)$
  funcs:
    getenv:
    - ^HUGO_
    - ^CI$
  http:
    methods:
    - (?i)GET|POST
    urls:
    - .*
```

=== “toml”

```toml
[security]
  enableInlineShortcodes = false
  [security.exec]
    allow = ['^dart-sass-embedded$', '^go$', '^npx$', '^postcss$']
    osEnv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\w+)$']
  [security.funcs]
    getenv = ['^HUGO_', '^CI$']
  [security.http]
    methods = ['(?i)GET|POST']
    urls = ['.*']
```

=== “json”

```json
{
   "security": {
      "enableInlineShortcodes": false,
      "exec": {
         "allow": [
            "^dart-sass-embedded$",
            "^go$",
            "^npx$",
            "^postcss$"
         ],
         "osEnv": [
            "(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\\w+)$"
         ]
      },
      "funcs": {
         "getenv": [
            "^HUGO_",
            "^CI$"
         ]
      },
      "http": {
         "methods": [
            "(?i)GET|POST"
         ],
         "urls": [
            ".*"
         ]
      }
   }
}
```

​ 注意,Hugo 中的这些和其他配置设置可以被操作系统环境覆盖。如果您想阻止所有远程 HTTP 获取数据:

1
HUGO_SECURITY_HTTP_URLS=none hugo

依赖安全性

​ Hugo 作为一个静态二进制文件使用 Go Modules 来管理其依赖项。Go Modules 有几个保障措施,其中之一是 go.sum 文件。这是所有依赖项(包括传递依赖项)的预期密码校验和的数据库。

Hugo Modules 是在 Go Modules 的功能之上构建的一个功能。像 Go Modules 一样,使用 Hugo Modules 的 Hugo 项目将有一个 go.sum 文件。我们建议将此文件提交到您的版本控制系统中。如果存在校验和不匹配,则 Hugo 构建将失败,这将表明依赖项被篡改

Web 应用程序安全性

​ 以下是 OWASP定义的安全威胁。

​ 对于 HTML 输出,这是核心安全模型:

https://pkg.go.dev/html/template#hdr-Security_Model

简而言之:

​ 模板和配置作者(您)是可信任的,但您发送的数据不是。这就是为什么有时需要使用安全函数,如 safeHTML,以避免转义您知道是安全的数据。正如文档中所指出的一样,上述规则有一个例外:如果您启用内联shortcode,您也表明在内容文件中shortcode和数据处理是可信的,因为这些宏被视为纯文本。值得一提的是,Hugo 是一个静态站点生成器,没有动态用户输入的概念。

​ 对于内容, 默认的 Markdown 渲染器配置为删除或转义潜在的不安全内容。如果您信任自己的内容,则可以重新配置此行为。

另请参阅 :

1.2 - Hugo and GDPR

Hugo and the General Data Protection Regulation (GDPR)

https://gohugo.io/about/hugo-and-gdpr/

​ 关于如何配置您的 Hugo 站点以符合新的法规。

​ 《一般数据保护条例》(GDPR)是欧盟法律中关于所有在欧盟和欧洲经济区内的个人数据保护和隐私的规定。它于2018年5月25日开始生效。

​ Hugo 是一个静态站点生成器。通过使用 Hugo,您已经站在了非常坚实的地面上。与服务器和数据库驱动的站点相比,磁盘上的静态 HTML 文件要容易理解得多。

​ 但即使是静态站点也可以与外部服务集成,因此从版本0.41开始,Hugo提供了一个隐私配置,涵盖了相关的内置模板。

请注意:

  • 这些设置默认设置为off,即 Hugo 0.41之前的工作方式。您必须对您的站点进行评估,并应用适当的设置。
  • 这些设置适用于内部模板。一些主题可能包含用于嵌入 Google Analytics 等服务的自定义模板。在这种情况下,这些选项将没有效果。
  • 我们将继续这项工作,并在未来的 Hugo 版本中进一步改进。

所有隐私设置

​ 以下是所有隐私设置及其默认值。这些设置需要放置在您的站点配置文件中(例如 config.toml)。

=== “yaml”

```yaml
privacy:
  disqus:
    disable: false
  googleAnalytics:
    anonymizeIP: false
    disable: false
    respectDoNotTrack: false
    useSessionStorage: false
  instagram:
    disable: false
    simple: false
  twitter:
    disable: false
    enableDNT: false
    simple: false
  vimeo:
    disable: false
    enableDNT: false
    simple: false
  youtube:
    disable: false
    privacyEnhanced: false
```

=== “toml”

```toml
[privacy]
  [privacy.disqus]
    disable = false
  [privacy.googleAnalytics]
    anonymizeIP = false
    disable = false
    respectDoNotTrack = false
    useSessionStorage = false
  [privacy.instagram]
    disable = false
    simple = false
  [privacy.twitter]
    disable = false
    enableDNT = false
    simple = false
  [privacy.vimeo]
    disable = false
    enableDNT = false
    simple = false
  [privacy.youtube]
    disable = false
    privacyEnhanced = false
```

=== “json”

```json
{
   "privacy": {
      "disqus": {
         "disable": false
      },
      "googleAnalytics": {
         "anonymizeIP": false,
         "disable": false,
         "respectDoNotTrack": false,
         "useSessionStorage": false
      },
      "instagram": {
         "disable": false,
         "simple": false
      },
      "twitter": {
         "disable": false,
         "enableDNT": false,
         "simple": false
      },
      "vimeo": {
         "disable": false,
         "enableDNT": false,
         "simple": false
      },
      "youtube": {
         "disable": false,
         "privacyEnhanced": false
      }
   }
}
```

禁用所有服务

​ 一个禁用Hugo中所有相关服务的隐私配置示例。使用此配置,其他设置将不会生效。

=== “yaml”

```yaml
privacy:
  disqus:
    disable: true
  googleAnalytics:
    disable: true
  instagram:
    disable: true
  twitter:
    disable: true
  vimeo:
    disable: true
  youtube:
    disable: true
```

=== “toml”

```toml
[privacy]
  [privacy.disqus]
    disable = true
  [privacy.googleAnalytics]
    disable = true
  [privacy.instagram]
    disable = true
  [privacy.twitter]
    disable = true
  [privacy.vimeo]
    disable = true
  [privacy.youtube]
    disable = true
```

=== “json”

```json
{
   "privacy": {
      "disqus": {
         "disable": true
      },
      "googleAnalytics": {
         "disable": true
      },
      "instagram": {
         "disable": true
      },
      "twitter": {
         "disable": true
      },
      "vimeo": {
         "disable": true
      },
      "youtube": {
         "disable": true
      }
   }
}
```

隐私设置的说明

GoogleAnalytics

  • anonymizeIP

    启用此选项将使用户的 IP 地址在 Google Analytics 中匿名化。

  • respectDoNotTrack

    启用此选项将使 GA 模板遵循"Do Not Track"HTTP标头。

  • useSessionStorage

    启用此选项将禁用使用 Cookies,并使用 Session Storage 存储 GA 客户端 ID。

​ 使用 Google Analytics v4(gtag.js)时不支持 useSessionStorage

Instagram

  • simple

    如果启用simple 模式,将构建 Instagram 图像卡的静态和无 JS 版本。请注意,这仅支持图像卡,并且图像本身将从 Instagram 的服务器获取。

注意:如果您使用 Instagram 的simple模式和一个使用 Bootstrap 4 样式的站点,则可能需要禁用 Hugo 提供的内联样式。

=== “yaml”

```yaml
services:
  instagram:
    disableInlineCSS: true
```

=== “toml”

```toml
[services]
  [services.instagram]
    disableInlineCSS = true
```

=== “json”

```json
{
   "services": {
      "instagram": {
         "disableInlineCSS": true
      }
   }
}
```

Twitter

  • enableDNT

    启用此选项后,Twitter/Tweet短代码中的推文及其在您站点上的嵌入页面不会用于包括个性化建议和个性化广告在内的用途。

  • simple

    如果启用simple模式,则会构建一个静态且不包含JavaScript的推文版本。

注意:如果您在Twitter中使用simple模式,并且站点使用Bootstrap 4进行样式设置,则可能需要禁用Hugo提供的内联样式。

=== “yaml”

```
services:
  twitter:
    disableInlineCSS: true
```

=== “toml”

```toml
[services]
  [services.twitter]
    disableInlineCSS = true
```

=== “json”

```
{
   "services": {
      "twitter": {
         "disableInlineCSS": true
      }
   }
}
```

YouTube

  • privacyEnhanced

    启用隐私增强模式后,YouTube将不会存储与访问者有关的信息,除非用户播放嵌入的视频。

Vimeo

  • enableDNT

    启用此选项后,Vimeo shortcode会阻止Vimeo播放器跟踪任何会话数据,包括所有cookie和统计数据。

  • simple

    如果启用简单模式,则会从Vimeo的服务器获取视频缩略图,并在其上覆盖一个播放按钮。如果用户点击播放视频,则会在新标签页中直接打开Vimeo站点中的视频。

另请参阅

1.3 - 什么是 Hugo

What is Hugo - 什么是 Hugo

https://gohugo.io/about/what-is-hugo/

​ Hugo 是一个用 Go 语言编写的快速现代静态站点生成器,旨在重新让站点创建变得有趣。

​ Hugo 是一个通用的站点框架。从技术上讲,Hugo 是一个静态站点生成器。与每个访问者请求动态构建页面的系统不同,Hugo 在创建或更新内容时构建页面。由于站点被查看的频率远远高于它们被编辑的频率,因此 Hugo 的设计旨在为您站点的最终用户提供最佳的查看体验,为站点作者提供理想的编写体验。

​ 使用 Hugo 构建的站点极快且安全。 Hugo 站点可以托管在任何地方,包括 NetlifyHerokuGoDaddyDreamHostGitHub PagesGitLab PagesSurgeFirebaseGoogle Cloud StorageAmazon S3RackspaceAzureCloudFront ,并且可以很好地与 CDN 协作。 Hugo 站点无需数据库或依赖于昂贵的运行时,如 Ruby、Python 或 PHP。

​ 我们认为 Hugo 是理想的站点创建工具,几乎可以在瞬间完成构建,并能够在进行更改时重新构建。

Hugo 有多快?

Hugo 做了什么?

​ 在技术上,Hugo 接受一个源目录的文件和模板作为输入,并使用这些内容创建一个完整的站点。

谁应该使用 Hugo?

​ Hugo 适用于更喜欢在文本编辑器中编写而不是在浏览器中的人。

​ Hugo 适用于想要手动编写自己站点的人,而不必担心设置复杂的运行时、依赖项和数据库。

​ Hugo 适用于构建博客、公司站点、组合站点、文档、单个着陆页或包含数千个页面的站点的人。

1.4 - Hugo的特性

Hugo Features - Hugo的特性

https://gohugo.io/about/features/

Hugo boasts blistering speed, robust content management, and a powerful templating language making it a great fit for all kinds of static websites.

Hugo 拥有极快的构建速度、强大的内容管理和功能强大的模板语言,非常适合各种静态站点的开发。

常规

组织

内容

其他特性

1.5 - 静态站点生成器的好处

The Benefits of Static Site Generators - 静态站点生成器的好处

https://gohugo.io/about/benefits/

​ 改进的性能、安全性和易用性是静态站点生成器如此吸引人的几个原因之一。

​ 站点生成器的目的是将内容渲染成HTML文件。大多数都是"动态站点生成器"。这意味着HTTP服务器——即将文件发送到浏览器以供查看的程序——在每次终端用户请求页面时运行生成器创建一个新的HTML文件。

​ 随着时间的推移,动态站点生成器被编程以缓存其HTML文件,以防止向终端用户提供页面时不必要的延迟。缓存的页面是网页的静态版本。

​ Hugo在缓存方面更进了一步,所有HTML文件都在您的计算机上渲染。您可以在将文件复制到托管HTTP服务器的计算机之前在本地查看这些文件。由于HTML文件不是动态生成的,我们称Hugo是一个静态站点生成器。

​ 这有许多好处。最明显的是性能。HTTP服务器非常擅长发送文件——事实上,您可以使用动态站点所需内存和CPU的一小部分有效地提供相同数量的页面。

更多关于静态站点生成器的信息

另请参阅

1.6 - Apache License

Apache License

https://gohugo.io/about/license/

Hugo v0.15 and later are released under the Apache 2.0 license.

Hugo v0.15 and later are released under the Apache 2.0 license. Earlier versions of Hugo were released under the Simple Public License.

Version 2.0, January 2004 https://www.apache.org/licenses/LICENSE-2.0

Terms and Conditions for use, reproduction, and distribution

1. Definitions

“License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

“Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

“Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

“Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

“Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

“Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

“Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

“Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

“Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

3. Grant of Patent License

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

4. Redistribution

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

  • (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
  • (b) You must cause any modified files to carry prominent notices stating that You changed the files; and
  • (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
  • (d) If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

5. Submission of Contributions

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

6. Trademarks

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

8. Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets [] replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

apache-notice.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

2 - 安装Hugo

Installation - 安装

https://gohugo.io/installation/

​ 在macOS、Linux、Windows、BSD上,以及任何可以运行Go编译器工具链的机器上都可以安装Hugo。

2.1 - macOS

macOS

https://gohugo.io/installation/macos/

Install Hugo on macOS.

Editions

Hugo is available in two editions: standard and extended. With the extended edition you can:

  • Encode WebP images (you can decode WebP images with both editions)
  • Transpile Sass to CSS using the embedded LibSass transpiler

We recommend that you install the extended edition.

Prerequisites

Although not required in all cases, Git and Go are often used when working with Hugo.

Git is required to:

Go is required to:

  • Use the Hugo Modules feature
  • Build Hugo from source

Please refer to the Git and Go documentation for installation instructions.

Prebuilt binaries

Prebuilt binaries are available for a variety of operating systems and architectures. Visit the latest release page, and scroll down to the Assets section.

  1. Download the archive for the desired edition, operating system, and architecture
  2. Extract the archive
  3. Move the executable to the desired directory
  4. Add this directory to the PATH environment variable
  5. Verify that you have execute permission on the file

Please consult your operating system documentation if you need help setting file permissions or modifying your PATH environment variable.

If you do not see a prebuilt binary for the desired edition, operating system, and architecture, install Hugo using one of the methods described below.

Package managers

Homebrew

Homebrew is a free and open source package manager for macOS and Linux. This will install the extended edition of Hugo:

1
brew install hugo

MacPorts

MacPorts is a free and open source package manager for macOS. This will install the extended edition of Hugo:

1
sudo port install hugo

Docker

Erlend Klakegg Bergheim graciously maintains Docker images based on images for Alpine Linux, Busybox, Debian, and Ubuntu.

1
docker pull klakegg/hugo

Build from source

To build Hugo from source you must:

  1. Install Git
  2. Install Go version 1.18 or later
  3. Update your PATH environment variable as described in the Go documentation

The install directory is controlled by the GOPATH and GOBIN environment variables. If GOBIN is set, binaries are installed to that directory. If GOPATH is set, binaries are installed to the bin subdirectory of the first directory in the GOPATH list. Otherwise, binaries are installed to the bin subdirectory of the default GOPATH ($HOME/go or %USERPROFILE%\go).

Then build and test:

1
2
go install -tags extended github.com/gohugoio/hugo@latest
hugo version

Comparison

Prebuilt binariesPackage managersDockerBuild from source
Easy to install?✔️✔️✔️✔️
Easy to upgrade?✔️✔️✔️✔️
Easy to downgrade?✔️✔️ 1✔️✔️
Automatic updates?22
Latest version available?✔️✔️✔️✔️

  1. Easy if a previous version is still installed. ↩︎
  2. Possible but requires advanced configuration. ↩︎ ↩︎

另请参阅

2.2 - Linux

Linux

https://gohugo.io/installation/linux/

​ 在Linux上安装Hugo。

版本

​ Hugo有两个版本:标准版和扩展版。使用扩展版可以:

  • 编码WebP图像(使用两个版本都可以解码WebP图像)
  • 使用内置的LibSass编译器将Sass转换为CSS

​ 我们建议您安装扩展版。

前提条件

​ 虽然并非所有情况下都需要,但在使用Hugo时通常使用Git和Go。

​ 需要Git的情况:

​ 需要Go的情况:

  • 使用Hugo Modules功能
  • 从源代码构建Hugo

​ 请参阅GitGo文档以获取安装说明。

预构建二进制文件

​ 预构建的二进制文件可用于各种操作系统和架构。访问最新版本页面,然后向下滚动到Assets 部分。

  1. 下载所需版本、操作系统和架构的存档
  2. 解压缩存档
  3. 将可执行文件移动到所需目录
  4. 将此目录添加到PATH环境变量中
  5. 验证您对该文件具有执行权限

​ 如果需要帮助设置文件权限或修改PATH环境变量,请参考操作系统文档。

​ 如果您没有看到所需版本、操作系统和架构的预构建二进制文件,请使用以下方法之一安装Hugo。

包管理器

Snap

Snap是Linux的免费开源软件包管理器。Snap包适用于大多数发行版,易于安装并且会自动更新。

​ Hugo snap包是严格隔离的。严格隔离的snap运行在完全隔离的环境中,最小访问级别被认为是始终安全的。您创建和构建的站点必须位于您的主目录内或可移动媒体上。

​ 这将安装Hugo的扩展版:

1
sudo snap install hugo

Homebrew

Homebrew是macOS和Linux的免费开源软件包管理器。这将安装Hugo的扩展版:

1
brew install hugo

存储库包

​ 大多数Linux发行版都维护着一个通用安装应用程序的软件仓库。请注意,这些仓库可能不包含最新版本

Arch Linux

​ 基于Arch Linux的Linux发行版包括EndeavourOSGaruda LinuxManjaro等。这将安装Hugo的扩展版:

1
sudo pacman -S hugo

Debian

​ 基于Debian的Linux发行版包括elementary OSKDE neonLinux LiteLinux MintMX LinuxPop!_OSUbuntuZorin OS等。这将安装Hugo的扩展版:

1
sudo apt install hugo

​ 您也可以从最新版本页面下载Debian包。

Fedora

​ 基于Fedora的Linux发行版包括CentOSRed Hat Enterprise Linux等。这将安装Hugo的扩展版:

1
sudo dnf install hugo

openSUSE

​ 基于openSUSE的Linux发行版包括GeckoLinuxLinux Karmada等。这将安装Hugo的扩展版:

1
sudo zypper install hugo

Solus

​ Solus的Linux发行版在其包存储库中包含Hugo。这将安装Hugo的标准版:

1
sudo eopkg install hugo

Docker

Erlend Klakegg Bergheim慷慨地维护了基于Alpine Linux、Busybox、Debian和Ubuntu的Docker images

1
docker pull klakegg/hugo

从源代码构建

​ 要从源代码构建Hugo,您必须:

  1. 安装 Git
  2. 安装Go版本1.18或更高版本
  3. Go文档中的说明更新PATH环境变量

安装目录由GOPATH和GOBIN环境变量控制。如果设置了GOBIN,那么二进制文件将安装到该目录中。如果设置了GOPATH,则二进制文件将安装到GOPATH列表中第一个目录的bin子目录中。否则,二进制文件将安装到默认GOPATH的bin子目录($HOME/go%USERPROFILE%\go)。

然后构建和测试:

1
2
go install -tags extended github.com/gohugoio/hugo@latest
hugo version

对比

Prebuilt binariesPackage managersRepository packagesDockerBuild from source
Easy to install?✔️✔️✔️✔️✔️
Easy to upgrade?✔️✔️varies✔️✔️
Easy to downgrade?✔️✔️ 1varies✔️✔️
Automatic updates?varies 23
Latest version available?✔️✔️varies✔️✔️

  1. 如果之前安装了旧版本,安装将变得容易。 ↩︎
  2. Snap 包会自动更新。Homebrew 需要高级配置。 ↩︎
  3. 虽然可能,但需要高级配置。 ↩︎

另请参阅

2.3 - Windows

Windows

https://gohugo.io/installation/windows/

​ 在 Windows 上安装 Hugo。

版本

​ Hugo 有两个版本:标准版和扩展版。使用扩展版,您可以:

  • 将 WebP 图像进行编码(标准版和扩展版都可以解码 WebP 图像)
  • 使用内置的 LibSass 转译器将 Sass 转译为 CSS

​ 我们建议您安装扩展版。

先决条件

​ 虽然在某些情况下不是必需的,但在使用 Hugo 时经常使用 Git 和 Go。

​ 需要Git的情况:

​ 需要Go的情况:

  • 使用Hugo Modules功能
  • 从源代码构建Hugo

​ 请参阅GitGo文档以获取安装说明。

预构建二进制文件

​ 预构建的二进制文件可用于各种操作系统和架构。访问最新版本页面,然后向下滚动到Assets 部分。

  1. 下载所需版本、操作系统和架构的存档
  2. 解压缩存档
  3. 将可执行文件移动到所需目录
  4. 将此目录添加到PATH环境变量中
  5. 验证您对该文件具有执行权限

​ 如果需要帮助设置文件权限或修改PATH环境变量,请参考操作系统文档。

​ 如果您没有看到所需版本、操作系统和架构的预构建二进制文件,请使用以下方法之一安装Hugo。

包管理器

Chocolatey

Chocolatey是 Windows 的一个免费开源软件包管理器。这将安装 Hugo 的扩展版:

1
choco install hugo-extended

Scoop

Scoop是 Windows 的一个免费开源软件包管理器。这将安装 Hugo 的扩展版:

1
scoop install hugo-extended

Winget

Winget是微软的官方免费开源软件包管理器。这将安装 Hugo 的扩展版:

1
winget install Hugo.Hugo.Extended

Docker

Erlend Klakegg Bergheim 慷慨地维护基于 Alpine Linux、Busybox、Debian 和 Ubuntu 的 Docker 映像

1
docker pull klakegg/hugo

从源代码构建

要从源代码构建 Hugo,您必须:

  1. 安装Git
  2. 安装 Go 版本 1.18 或更高版本
  3. 按照 Go 文档中的说明更新 PATH 环境变量。

​ 安装目录由GOPATH和GOBIN环境变量控制。如果设置了GOBIN,则二进制文件将安装到该目录。如果设置了GOPATH,则二进制文件将安装到GOPATH列表中第一个目录的bin子目录中。否则,二进制文件将安装到默认的GOPATH的bin子目录中($HOME/go%USERPROFILE%\go)。

​ 然后进行构建和测试:

1
2
go install -tags extended github.com/gohugoio/hugo@latest
hugo version

​ 在Windows上构建Hugo的扩展版时,还需要安装GCC编译器。请参考这些详细的说明

比较

Prebuilt binariesPackage managersDockerBuild from source
Easy to install?✔️✔️✔️✔️
Easy to upgrade?✔️✔️✔️✔️
Easy to downgrade?✔️✔️ 1✔️✔️
Automatic updates?22
Latest version available?✔️✔️✔️✔️

  1. 如果先前安装了旧版本,则易于安装。↩︎
  2. 可能,但需要高级配置。↩︎ ↩︎

See 另请参阅

2.4 - BSD

BSD

https://gohugo.io/installation/bsd/

Install Hugo on BSD derivatives.

Editions

Hugo is available in two editions: standard and extended. With the extended edition you can:

  • Encode WebP images (you can decode WebP images with both editions)
  • Transpile Sass to CSS using the embedded LibSass transpiler

We recommend that you install the extended edition.

Prerequisites

Although not required in all cases, Git and Go are often used when working with Hugo.

Git is required to:

Go is required to:

  • Use the Hugo Modules feature
  • Build Hugo from source

Please refer to the Git and Go documentation for installation instructions.

Prebuilt binaries

Prebuilt binaries are available for a variety of operating systems and architectures. Visit the latest release page, and scroll down to the Assets section.

  1. Download the archive for the desired edition, operating system, and architecture
  2. Extract the archive
  3. Move the executable to the desired directory
  4. Add this directory to the PATH environment variable
  5. Verify that you have execute permission on the file

Please consult your operating system documentation if you need help setting file permissions or modifying your PATH environment variable.

If you do not see a prebuilt binary for the desired edition, operating system, and architecture, install Hugo using one of the methods described below.

Repository packages

Most BSD derivatives maintain a repository for commonly installed applications. Please note that these repositories may not contain the latest release.

DragonFly BSD

DragonFly BSD includes Hugo in its package repository. This will install the extended edition of Hugo:

1
sudo pkg install gohugo

FreeBSD

FreeBSD includes Hugo in its package repository. This will install the extended edition of Hugo:

1
sudo pkg install gohugo

NetBSD

NetBSD includes Hugo in its package repository. This will install the extended edition of Hugo:

1
sudo pkgin install go-hugo

OpenBSD

OpenBSD includes Hugo in its package repository. This will prompt you to select which edition of Hugo to install:

1
doas pkg_add hugo

Build from source

To build Hugo from source you must:

  1. Install Git
  2. Install Go version 1.18 or later
  3. Update your PATH environment variable as described in the Go documentation

The install directory is controlled by the GOPATH and GOBIN environment variables. If GOBIN is set, binaries are installed to that directory. If GOPATH is set, binaries are installed to the bin subdirectory of the first directory in the GOPATH list. Otherwise, binaries are installed to the bin subdirectory of the default GOPATH ($HOME/go or %USERPROFILE%\go).

Then build and test:

1
2
go install -tags extended github.com/gohugoio/hugo@latest
hugo version

Comparison

Prebuilt binariesRepository packagesBuild from source
Easy to install?✔️✔️✔️
Easy to upgrade?✔️varies✔️
Easy to downgrade?✔️varies✔️
Automatic updates?varies
Latest version available?✔️varies✔️

另请参阅

3 - 开始入门

Get Started - 开始入门

https://gohugo.io/getting-started/

​ 如果这是您第一次使用 Hugo,而且已经在计算机上安装了 Hugo,则建议使用快速入门。您也可以使用外部学习资源学习 Hugo。

3.1 - 快速入门

Quick Start - 快速入门

https://gohugo.io/getting-started/quick-start/

​ 学习如何在几分钟内创建一个 Hugo 站点。

​ 在本教程中,您将会:

  1. 创建一个站点
  2. 添加内容
  3. 配置站点
  4. 发布站点

先决条件

​ 在开始本教程之前,您必须:

  1. 安装 Hugo(扩展版)
  2. 安装 Git

​ 您还必须熟悉使用命令行操作。

创建一个站点

命令

如果您是 Windows 用户:

  • 不要使用命令提示符
  • 不要使用 Windows PowerShell
  • 请在 PowerShell 或类似于 WSL 或 Git Bash 的 Linux 终端中运行这些命令。

PowerShell 和 Windows PowerShell 是不同的应用程序。

​ 运行以下命令创建带有 Ananke主题的 Hugo 站点。下一节将对每个命令进行解释。

1
2
3
4
5
6
hugo new site quickstart
cd quickstart
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke
echo "theme = 'ananke'" >> config.toml
hugo server

​ 在终端中显示的 URL 上查看您的站点。按 Ctrl + C 停止 Hugo 的开发服务器。

命令解释

​ 在 quickstart 目录中为项目创建目录结构

1
hugo new site quickstart

​ 将当前目录切换为项目根目录:

1
cd quickstart

​ 在当前目录中初始化一个空的 Git 存储库:

1
git init

​ 将 Ananke主题克隆到 themes 目录中,并将其作为 Git submodule添加到项目中。

1
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke

​ 在站点配置文件中添加一行,指示当前主题:

1
echo "theme = 'ananke'" >> config.toml

​ 启动 Hugo 的开发服务器以查看站点:

1
hugo server

​ 按 Ctrl + C 停止 Hugo 的开发服务器。

添加内容

​ 在站点中添加一个新页面:

1
hugo new posts/my-first-post.md

​ Hugo 在 content/posts 目录中创建了该文件。使用您的编辑器打开该文件。

1
2
3
4
5
---
title: "My First Post"
date: 2022-11-20T09:03:20-08:00
draft: true
---

​ 请注意,前置元数据中的draft值为 true。默认情况下,Hugo 不会在构建站点时发布草稿(draft)内容。了解有关草稿(draft)、将来(future)和过期(expired)内容的更多信息。

​ 在文章的正文中添加一些 markdown,但不要更改draft的值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
---
title: "My First Post"
date: 2022-11-20T09:03:20-08:00
draft: true
---
## Introduction

This is **bold** text, and this is *emphasized* text.

Visit the [Hugo](https://gohugo.io) website!

​ 保存文件,然后启动 Hugo 的开发服务器以查看站点。您可以运行以下任一命令来包含草稿内容。

1
2
hugo server --buildDrafts
hugo server -D

​ 在终端中显示的 URL 上查看您的站点。随着您继续添加和更改内容,请保持开发服务器运行。

​ Hugo 的渲染引擎符合 CommonMark 的 markdown 规范。CommonMark组织提供了一个有用(由参考实现驱动)的实时测试工具

配置站点

​ 使用编辑器打开项目根目录中的站点配置文件(config.toml)。

1
2
3
4
baseURL = 'http://example.org/'
languageCode = 'en-us'
title = 'My New Hugo Site'
theme = 'ananke'

​ 进行以下更改:

  1. baseURL设置为您的生产站点。此值必须以协议开头,并以斜杠结尾,如上所示。
  2. languageCode设置为您的语言和地区。
  3. 设置生产站点的title

​ 启动Hugo的开发服务器以查看更改,记得包括草稿内容。

1
hugo server -D

​ 大多数主题作者都会提供配置指南和选项。请务必访问您的主题存储库或文档站点了解详情。

​ Ananke主题的作者The New Dynamic为配置和使用提供文档。他们还提供演示站点

发布站点

​ 在此步骤中,您将发布站点,但不会部署它。

​ 发布站点时,Hugo会在项目根目录中的public目录中创建整个静态站点。这包括HTML文件和assets,如图片、CSS文件和JavaScript文件。

​ 在发布站点时,通常不希望包括草稿(draft)、将来(future)和过期(expired)内容。命令很简单。

1
hugo

​ 要了解如何部署站点,请参阅主机和部署部分。

寻求帮助

​ Hugo的论坛是一个活跃的用户和开发者社区,他们回答问题、分享知识和提供示例。超过20,000个主题的快速搜索通常可以回答您的问题。请确保在提问之前阅读有关请求帮助的信息。

其他资源

​ 有关帮助您学习Hugo的其他资源,包括书籍和视频教程,请参见外部学习资源页面。

另请参阅

3.2 - 基础用法

Basic usage - 基础用法

https://gohugo.io/getting-started/usage/

​ Hugo的命令行界面(CLI)功能齐全但简单易用,即使对于那些在命令行上有限经验的人也是如此。

测试您的安装

安装完Hugo后,请通过运行以下命令来测试您的安装:

1
hugo version

​ 您应该会看到类似于以下的输出:

1
hugo v0.105.0-0e3b42b4a9bdeb4d866210819fc6ddcf51582ffa+extended linux/amd64 BuildDate=2022-10-28T12:29:05Z VendorInfo=snap:0.105.0

显示可用命令

​ 要查看可用命令和标志的列表:

1
hugo help

​ 要获取子命令的帮助,请使用--help标志。例如:

1
hugo server --help

构建您的站点

​ 要构建您的站点,请cd进入您的项目目录并运行:

1
hugo

hugo命令将构建您的站点,将文件发布到public目录中。要将您的站点发布到不同的目录中,请使用--destination标志在您的站点配置中设置publishDir

​ Hugo在构建您的站点之前不会清除public目录。现有的文件将被覆盖,但不会被删除。这种行为是有意的,以防止意外删除您在构建之后添加到public目录中的文件。

​ 根据您的需求,您可能希望在每次构建之前手动清除public目录的内容。

草稿、未来和过期内容

​ Hugo允许您在内容的前置元数据中设置draftdatepublishDateexpiryDate。默认情况下,Hugo不会发布以下内容:

  • draft值为true
  • date在未来时
  • publishDate在未来时
  • expiryDate在过去时

​ 您可以在运行hugohugo server时使用命令行标志来覆盖默认行为:

1
2
3
hugo --buildDrafts    # or -D
hugo --buildExpired   # or -E
hugo --buildFuture    # or -F

​ 尽管您也可以在站点配置中设置这些值,但除非所有内容作者都知道并理解这些设置,否则可能会导致意想不到的结果。

​ 正如上面所述,Hugo 在构建站点之前不会清除 public 目录。根据上述四个条件的当前评估,构建后您的 public 目录可能包含来自上一次构建的不必要的文件。

​ 一种常见的做法是在每次构建之前手动清除 public 目录的内容,以删除草稿、过期和未来的内容。

开发和测试您的站点

​ 为了在开发布局或创建内容时查看您的站点,请cd进入项目目录并运行:

1
hugo server

hugo server 命令将您的站点构建到内存中,并使用最小的 HTTP 服务器提供您的页面。运行 hugo server 时,它将显示您本地站点的 URL:

1
Web Server is available at http://localhost:1313/ 

​ 在服务器运行时,它会监视项目目录中的资源、配置、内容、数据、布局、翻译和静态文件的更改。当它检测到更改时,服务器会重新构建您的站点并使用 LiveReload刷新您的浏览器。

​ 大多数 Hugo 构建速度都非常快,除非您直接查看浏览器,否则可能不会注意到更改。

LiveReload

​ 在服务器运行时,Hugo 会将 JavaScript 注入生成的 HTML 页面中。LiveReload 脚本通过 Web sockets 创建了一个从浏览器到服务器的连接。您不需要安装任何软件或浏览器插件,也不需要任何配置。

自动重定向

​ 当编辑内容时,如果您希望浏览器自动重定向到您最后修改的页面,请运行:

1
hugo server --navigateToChanged

部署您的站点

​ 如上所述,Hugo 在构建站点之前不会清空 public 目录。在每次构建之前手动清空 public 目录以删除草稿、已过期和未来的内容。

​ 当您准备部署您的站点时,运行:

1
hugo

​ 这会构建您的站点,并将文件发布到 public 目录。目录结构将类似于:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public/
├── categories/
│   ├── index.html
│   └── index.xml  <-- RSS feed for this section
├── post/
│   ├── my-first-post/
│   │   └── index.html
│   ├── index.html
│   └── index.xml  <-- RSS feed for this section
├── tags/
│   ├── index.html
│   └── index.xml  <-- RSS feed for this section
├── index.html
├── index.xml      <-- RSS feed for the site
└── sitemap.xml

​ 在一个简单的托管环境中,您通常会通过 ftprsyncscp 将您的文件传输到虚拟主机的根目录,public 目录的内容就是您所需的全部内容。

​ 我们的大多数用户使用 CI/CD 工作流部署其站点,其中对 GitHub 或 GitLab 存储库的推送触发了构建和部署。流行的提供者包括 AWS AmplifyCloudCannonCloudflare PagesGitHub PagesGitLab PagesNetlify

​ 在托管和部署部分中了解更多信息。


  1. Git 存储库包含整个项目目录,通常不包括 public 目录,因为在push之后才构建站点。↩︎

另请参阅

3.3 - 目录结构

Directory Structure - 目录结构

https://gohugo.io/getting-started/directory-structure/

​ Hugo的CLI脚手架会创建一个项目目录结构,然后使用该单个目录作为输入来创建一个完整的站点。

新建站点脚手架

​ 从命令行运行hugo new site example会创建一个带有以下元素的目录结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
example/
├── archetypes/
│   └── default.md
├── assets/
├── content/
├── data/
├── layouts/
├── public/
├── static/
├── themes/
└── config.toml

目录结构说明

​ 以下是每个目录的高级概述,并提供了链接到Hugo文档中各自部分的链接。

  • archetypes

    您可以使用hugo new命令在Hugo中创建新的内容文件。默认情况下,Hugo将创建带有datetitle(从文件名推断)和draft = true的新内容文件。这节省了时间,并为使用多个内容类型的站点促进了一致性。您还可以创建自己的原型(archetypes),其中包含自定义的预配置前置元数据字段。

  • assets

    存储需要由Hugo Pipes处理的所有文件。只有使用.Permalink.RelPermalink的文件将被发布到public目录。

  • config

    Hugo带有大量的配置指令config目录是存储这些指令的地方,以JSON、YAML或TOML文件的形式存储。每个根设置对象都可以作为自己的文件,并按环境结构化。设置最少且不需要环境感知的项目可以在其根目录使用单个config.toml文件。

    许多站点可能不需要任何配置,但Hugo提供了大量的配置指令,用于更精细的指导如何构建您的站点。注意:config目录不会默认创建。

  • content

    您站点的所有内容都将位于此目录中。Hugo中的每个顶层文件夹都被视为内容章节。例如,如果您的站点有三个主要章节——博客(blog)、文章(articles)和教程(tutorials)——则在content/blogcontent/articlescontent/tutorials中将会有三个目录。Hugo使用章节来分配默认内容类型

  • data

    此目录用于存储在生成站点时Hugo可以使用的配置文件。您可以按YAML、JSON或TOML格式编写这些文件。除了将这些文件添加到此文件夹中外,您还可以创建从动态内容中提取的数据模板

  • layouts

    存储模板,以.html文件的形式指定如何将您的内容视图渲染为静态站点。模板包括列表页面主页分类法模板局部单页模板等。

  • static

    存储所有的静态内容:图片、CSS、JavaScript等。当Hugo构建您的站点时,static目录内的所有资源都将按原样复制。一个使用static目录的好例子是在Google Search Console上验证站点所有权,您希望Hugo复制完整的HTML文件而不修改其内容。

​ 从 Hugo 0.31 版本开始,您可以有多个静态目录。

  • resources

    缓存一些文件以加速生成。也可以由模板作者用于分发已构建的 Sass 文件,这样您就不必安装预处理器。注意:默认情况下不会创建resources 目录。

另请参阅

3.4 - 配置 Hugo

Configure Hugo - 配置 Hugo

https://gohugo.io/getting-started/configuration/

​ 如何配置您的 Hugo 站点。

配置文件

​ Hugo 使用 config.tomlconfig.yamlconfig.json(如果在站点根目录中找到)作为默认的站点配置文件。

​ 用户可以使用命令行 --config 开关选择覆盖默认设置的一个或多个站点配置文件。

例如:

1
2
hugo --config debugconfig.toml
hugo --config a.toml,b.toml,c.toml

​ 可以将多个站点配置文件指定为逗号分隔的字符串传递给 --config 开关。

hugo.toml vs config.toml

​ 在 Hugo 0.110.0 中,我们将默认的配置基础文件名更改为 hugo,例如 hugo.toml。我们仍会查找 config.toml 等文件,但我们建议您最终将其重命名(但如果您想支持旧版本的 Hugo,则需要等待)。我们这样做的主要原因是为了让代码编辑器和构建工具更容易识别这是 Hugo 的配置文件和项目。

v0.110.0 新功能

配置目录

​ 除了使用单个站点配置文件外,您还可以使用 configDir 目录(默认为 config/)来维护更易于组织和特定于环境的设置。

  • 每个文件都代表一个配置根对象,例如 params.toml 代表 [Params]menu(s).toml 代表 [Menu]languages.toml 代表 [Languages] 等等…
  • 每个文件的内容必须是顶级的,例如:

config.

=== “yaml”

```yaml
Params:
  foo: bar
```

=== “toml”

```toml
[Params]
  foo = 'bar'
```

=== “json”

```json
{
    "Params": {
          "foo": "bar"
    }
}
```

params.

=== “yaml”

```yaml
foo: bar
```

=== “toml”

```toml
foo = 'bar'
```

=== “json”

```json
{
   "foo": "bar"
}
```
  • 每个目录保存了一组文件,包含特定环境的设置。
  • 文件可以本地化,变成特定语言。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
├── config
│   ├── _default
│   │   ├── config.toml
│   │   ├── languages.toml
│   │   ├── menus.en.toml
│   │   ├── menus.zh.toml
│   │   └── params.toml
│   ├── production
│   │   ├── config.toml
│   │   └── params.toml
│   └── staging
│       ├── config.toml
│       └── params.toml

​ 考虑上述结构,在运行hugo --environment staging命令时,Hugo将使用config/_default中的所有设置,并在其上合并staging的设置。

​ 让我们举个例子来更好地理解这个过程。假设您的站点使用Google Analytics。这要求您在config.toml中指定googleAnalytics = "G-XXXXXXXX"。现在考虑以下场景:

  • 您不希望在开发中加载分析代码,即在localhost上。
  • 您想为生产和staging环境使用不同的googleAnalytics ID:
    • 生产环境的G-PPPPPPPP
    • staging环境的G-SSSSSSSS

​ 考虑上述情况,您需要如何配置您的config.toml文件:

  1. _default/config.toml中,您根本不需要提及googleAnalytics参数。这可以确保在您运行hugo server时,即在您的开发服务器上不加载Google Analytics代码。这是因为,当您运行hugo server时,默认情况下Hugo设置Environment=development,它使用_default文件夹中的配置文件。

  2. production/config.toml中,您只需要有一行:

    googleAnalytics = "G-PPPPPPPP"

    您不需要在此配置文件中再次提及所有其他参数,如titlebaseURLtheme等。您只需要提及那些不同或新的生产环境参数。这是由于Hugo将在_default/config.toml之上合并此参数。现在,当您运行hugo(build命令)时,默认情况下hugo设置Environment=production,因此G-PPPPPPPP分析代码将存在于您的生产站点中。

  3. 同样,在staging/config.toml中,您只需要有一行:

    googleAnalytics = "G-SSSSSSSS"

    现在,您需要告诉Hugo您正在使用staging环境。因此,您的构建命令应该是hugo --environment staging,这将在您的staging站点中加载G-SSSSSSSS分析代码。

​ 默认环境是hugo server下的development和hugo下的production

合并主题配置

_merge 的配置值可以是以下之一:

  • none

    不合并。

  • shallow

    仅添加新键的值。

  • deep

    添加新键的值,合并现有键的值。

​ 请注意,您不需要像下面的默认设置那样冗长;如果未设置,则会继承更高的_merge值。

config.

=== “yaml”

```yaml
build:
  _merge: none
caches:
  _merge: none
cascade:
  _merge: none
frontmatter:
  _merge: none
imaging:
  _merge: none
languages:
  _merge: none
  en:
    _merge: none
    menus:
      _merge: shallow
    params:
      _merge: deep
markup:
  _merge: none
mediatypes:
  _merge: shallow
menus:
  _merge: shallow
minify:
  _merge: none
module:
  _merge: none
outputformats:
  _merge: shallow
params:
  _merge: deep
permalinks:
  _merge: none
privacy:
  _merge: none
related:
  _merge: none
security:
  _merge: none
sitemap:
  _merge: none
taxonomies:
  _merge: none
```

=== “toml”

```toml
[build]
  _merge = 'none'
[caches]
  _merge = 'none'
[cascade]
  _merge = 'none'
[frontmatter]
  _merge = 'none'
[imaging]
  _merge = 'none'
[languages]
  _merge = 'none'
  [languages.en]
    _merge = 'none'
    [languages.en.menus]
      _merge = 'shallow'
    [languages.en.params]
      _merge = 'deep'
[markup]
  _merge = 'none'
[mediatypes]
  _merge = 'shallow'
[menus]
  _merge = 'shallow'
[minify]
  _merge = 'none'
[module]
  _merge = 'none'
[outputformats]
  _merge = 'shallow'
[params]
  _merge = 'deep'
[permalinks]
  _merge = 'none'
[privacy]
  _merge = 'none'
[related]
  _merge = 'none'
[security]
  _merge = 'none'
[sitemap]
  _merge = 'none'
[taxonomies]
  _merge = 'none'
```

=== “json”

```json
{
   "build": {
      "_merge": "none"
   },
   "caches": {
      "_merge": "none"
   },
   "cascade": {
      "_merge": "none"
   },
   "frontmatter": {
      "_merge": "none"
   },
   "imaging": {
      "_merge": "none"
   },
   "languages": {
      "_merge": "none",
      "en": {
         "_merge": "none",
         "menus": {
            "_merge": "shallow"
         },
         "params": {
            "_merge": "deep"
         }
      }
   },
   "markup": {
      "_merge": "none"
   },
   "mediatypes": {
      "_merge": "shallow"
   },
   "menus": {
      "_merge": "shallow"
   },
   "minify": {
      "_merge": "none"
   },
   "module": {
      "_merge": "none"
   },
   "outputformats": {
      "_merge": "shallow"
   },
   "params": {
      "_merge": "deep"
   },
   "permalinks": {
      "_merge": "none"
   },
   "privacy": {
      "_merge": "none"
   },
   "related": {
      "_merge": "none"
   },
   "security": {
      "_merge": "none"
   },
   "sitemap": {
      "_merge": "none"
   },
   "taxonomies": {
      "_merge": "none"
   }
}
```

所有配置设置

​ 以下是Hugo定义的变量的完整列表。用户可以选择在其站点配置文件中覆盖这些值。

archetypeDir

​ 默认值:“archetypes”

​ Hugo查找原型文件(内容模板)的目录。另请参阅模块挂载配置,以了解配置此目录的另一种替代方式(从Hugo 0.56开始)。

assetDir

​ 默认值:“assets”

​ Hugo查找Hugo Pipes中使用的资产文件的目录。另请参阅模块挂载配置,以了解配置此目录的另一种替代方式(从Hugo 0.56开始)。

baseURL

​ 您发布站点的绝对 URL(协议、主机、路径和尾随斜杠),例如 https://www.example.org/docs/

build

​ 请参阅配置构建

buildDrafts (false)

​ 默认值:false

​ 在构建时包括草稿。

buildExpired

​ 默认值:false

​ 包括已过期的内容。

buildFuture

​ 默认值:false

​ 包括发布日期在未来的内容。

caches

​ 请参阅配置文件缓存

cascade

​ 将默认配置值(正面)传递到内容树中的页面。站点配置中的选项与页面前置元数据相同,请参阅前置元数据层叠

canonifyURLs

​ 默认值:false

​ 启用将相对URL转换为绝对URL。

cleanDestinationDir

​ 默认值:false

​ 在构建时,从目标中删除在static 目录中找不到的文件。

contentDir

​ 默认值:“content”

​ Hugo读取内容文件的目录。也可以参考模块安装配置的另一种方式来配置此目录(从Hugo 0.56开始)。

​ 默认值:""

​ 站点的版权声明,通常显示在页脚上。

dataDir

​ 默认值:“data”

​ Hugo读取数据文件的目录。也可以参考模块安装配置的另一种方式来配置此目录(从Hugo 0.56开始)。

defaultContentLanguage <-

​ 默认值:“en”

​ 没有语言标识的内容将默认为此语言。

defaultContentLanguageInSubdir

​ 默认值:false

​ 在子目录中呈现默认的内容语言,例如content/en/。站点根目录/将重定向到/en/

disableAliases

​ 默认值:false

​ 禁用别名重定向的生成。请注意,即使设置了disableAliases,别名本身仍将保留在页面上。这样做的动机是能够在.htaccess、Netlify _redirects文件或类似的输出格式中使用301重定向。

disableHugoGeneratorInject

​ 默认值:false

​ Hugo默认情况下仅在主页的HTML头中插入一个生成器元标记。您可以关闭它,但我们真的很希望您不要这样做,因为这是观察Hugo的受欢迎程度的好方法。

disableKinds

​ 默认值:[]

​ 启用禁用指定类型的所有页面。在此列表中允许的值为:"page""home""section""taxonomy""term""RSS""sitemap""robotsTXT""404"

disableLiveReload

​ 默认值:false

​ 禁用浏览器窗口的自动实时重新加载。

disablePathToLower

​ 默认值:false

​ 不要将url/path转换为小写。

enableEmoji <-

​ 默认值:false

​ 为页面内容启用表情符号支持;参见Emoji备忘表

enableGitInfo <-

​ 默认值:false

​ 为每个页面启用.GitInfo对象(如果Hugo站点已经通过Git进行版本控制)。这将使用每个内容文件的最后git提交日期来更新每个页面的Lastmod参数。

enableInlineShortcodes

​ 默认值:false

​ 启用内联shortcode 支持。参见内联shortcode

enableMissingTranslationPlaceholders

​ 默认值:false

​ 如果缺少翻译,则显示占位符,而不是默认值或空字符串。

enableRobotsTXT <-

​ 默认值:false

​ 启用robots.txt文件的生成。

frontmatter

​ 请参阅前置元数据配置

googleAnalytics

​ 默认值:""

​ Google Analytics 跟踪 ID。

hasCJKLanguage <-

​ 默认值:false

​ 如果为 true,则自动检测内容中的中文/日文/韩文语言。这将使得 .Summary.WordCount 在 CJK 语言中正确工作。

imaging

​ 请参阅图像处理配置

languageCode

​ 默认值:""

​ 由 RFC 5646 定义的语言标签。此值用于填充:

languages

​ 请参阅配置语言

disableLanguages

​ 请参阅禁用语言

markup

​ 请参阅配置标记

mediaTypes

​ 请参阅配置媒体类型

​ 请参阅菜单

minify

​ 请参阅配置 Minify

module

​ 模块配置,请参阅模块配置

newContentEditor

​ 默认值:""

​ 创建新内容时要使用的编辑器。

noChmod

​ 默认值:false

​ 不同步文件的权限模式。

noTimes

​ 默认值:false

​ 不同步文件的修改时间。

outputFormats

​ 请参阅配置输出格式

paginate <-

​ 默认值:10

分页中每页的默认元素数。

paginatePath

​ 默认值:“page”

​ 在分页期间使用的路径元素(https://example.com/page/2)。

​ 请参阅内容管理

pluralizeListTitles

​ 默认值:true

​ 在列表中使用复数形式的标题。

publishDir

​ 默认值:“public”

​ Hugo将生成的最终静态站点(HTML文件等)写入的目录。

​ 请参阅相关内容(Related Content)。

relativeURLs

​ 默认值:false

​ 启用此选项可使所有相对URL相对于内容根目录。请注意,这不会影响绝对URL。

refLinksErrorLevel

​ 默认值:“ERROR”

​ 使用refrelref解析页面链接时,如果无法解析链接,将以此日志级别记录。有效值为ERROR(默认值)或WARNING。任何ERROR将导致构建失败(exit -1)。

refLinksNotFoundURL

​ 在refrelref中找不到页面引用时要使用的URL占位符。按原样使用。

removePathAccents

​ 默认值:false

​ 从内容路径中的组合字符中删除非间隔标记

1
content/post/hügó.md --> https://example.org/post/hugo/

rssLimit

​ 默认值:-1(无限制)

​ RSS feed中的最大项目数。

sectionPagesMenu

​ 请参阅菜单(Menus)。

security

​ 请参阅安全策略(Security Policy)。

sitemap

​ 默认站点地图配置

summaryLength

​ 默认值:70

​ 在.Summary中显示的文本长度(以单词计算)。

taxonomies

​ 请参阅分类(Configure Taxonomies)。

theme

​ 请参阅模块配置(Module Config)以了解如何导入主题。

themesDir

​ 默认值:“themes”

​ Hugo从中读取主题的目录。

timeout

​ 默认值:“30s”

​ 生成页面内容的超时时间,以持续时间或毫秒表示。注意:这用于退出递归内容生成。如果页面生成较慢(例如因为它们需要大量的图像处理或依赖于远程内容),则可能需要提高此限制。

timeZone <-

​ 用于解析前置元数据日期(不带此信息)和time function的时区(或位置),例如Europe/Oslo。有效值列表可能因系统而异,但应包括UTCLocalIANA时区数据库中的任何位置。

title

​ 站点标题。

titleCaseStyle

​ 默认值:“AP”

​ 请参阅配置标题大小写(Configure Title Case)。

uglyURLs

​ 默认值:false

​ 启用时,将创建形式为/filename.html而不是/filename/的URL。

watch

​ 默认值:false

​ 监视文件系统以进行更改,并根据需要重新创建。

​ 如果您在*nix机器上开发您的站点,这是一个方便的从命令行查找配置选项的快捷方式:

1
2
cd ~/sites/yourhugosite
hugo config | grep emoji

显示输出如下:

1
enableemoji: true

配置构建 -> [build]

build配置部分包含全局构建相关的配置选项。

config.

=== “yaml”

```yaml
build:
  noJSConfigInAssets: false
  useResourceCacheWhen: fallback
  writeStats: false
```

=== “toml”

```toml
[build]
  noJSConfigInAssets = false
  useResourceCacheWhen = 'fallback'
  writeStats = false
```

=== “json”

```json
{
   "build": {
      "noJSConfigInAssets": false,
      "useResourceCacheWhen": "fallback",
      "writeStats": false
   }
}
```
  • useResourceCacheWhen

    决定在 PostCSS 和 ToCSS 中何时使用 /resources/_gen 中的缓存资源。有效值为 neveralwaysfallback。最后一个值表示如果 PostCSS/extended版本不可用,则尝试使用缓存。

  • writeStats

    启用后,将在项目根目录下写入一个名为 hugo_stats.json 的文件,其中包含有关构建的一些汇总数据,例如已发布的 HTML 实体列表,可用于进行 CSS pruning。如果您仅在生产构建中使用此功能,则应考虑将其放在 config/production 下面。值得一提的是,由于部分服务器构建的本质,当您添加或更改 HTML 实体时,将添加新的 HTML 实体,但旧值不会在您重启服务器或运行常规的 hugo 构建之前被删除。

请注意,这是清除未使用的 CSS 的主要用例;它专为速度而建,可能会出现误报(例如,检测到不是 HTML 元素的 HTML 元素)。

  • noJSConfigInAssets

    关闭在 /assets 文件夹中写入一个 jsconfig.json,其中包含来自运行 js.Build 的导入映射。此文件旨在帮助在诸如 VS Code 等代码编辑器内进行智能感知/导航。请注意,如果您不使用 js.Build,则不会写入任何文件。

Configure Server -> [server]

​ 仅在运行 hugo server 时相关,在开发过程中可以设置 HTTP 标头,从而可以测试您的内容安全策略等。配置格式与 Netlify 的格式相匹配,并具有略微更强大的全局匹配功能

config.

=== “yaml”

```yaml
server:
  headers:
  - for: /**
    values:
      Content-Security-Policy: script-src localhost:1313
      Referrer-Policy: strict-origin-when-cross-origin
      X-Content-Type-Options: nosniff
      X-Frame-Options: DENY
      X-XSS-Protection: 1; mode=block
```

=== “toml”

```toml
[server]
[[server.headers]]
  for = '/**'
  [server.headers.values]
    Content-Security-Policy = 'script-src localhost:1313'
    Referrer-Policy = 'strict-origin-when-cross-origin'
    X-Content-Type-Options = 'nosniff'
    X-Frame-Options = 'DENY'
    X-XSS-Protection = '1; mode=block'
```

=== “json”

```json
{
   "server": {
      "headers": [
         {
            "for": "/**",
            "values": {
               "Content-Security-Policy": "script-src localhost:1313",
               "Referrer-Policy": "strict-origin-when-cross-origin",
               "X-Content-Type-Options": "nosniff",
               "X-Frame-Options": "DENY",
               "X-XSS-Protection": "1; mode=block"
            }
         }
      ]
   }
}
```

​ 由于这仅适用于"development only",因此将其放置在development环境下可能是有意义的:

config/development/server.

=== “yaml”

```yaml
headers:
- for: /**
  values:
    Content-Security-Policy: script-src localhost:1313
    Referrer-Policy: strict-origin-when-cross-origin
    X-Content-Type-Options: nosniff
    X-Frame-Options: DENY
    X-XSS-Protection: 1; mode=block
```

=== “toml”

```toml
[[headers]]
for = '/**'
[headers.values]
  Content-Security-Policy = 'script-src localhost:1313'
  Referrer-Policy = 'strict-origin-when-cross-origin'
  X-Content-Type-Options = 'nosniff'
  X-Frame-Options = 'DENY'
  X-XSS-Protection = '1; mode=block'
```

=== “json”

```json
{
   "headers": [
      {
         "for": "/**",
         "values": {
            "Content-Security-Policy": "script-src localhost:1313",
            "Referrer-Policy": "strict-origin-when-cross-origin",
            "X-Content-Type-Options": "nosniff",
            "X-Frame-Options": "DENY",
            "X-XSS-Protection": "1; mode=block"
         }
      }
   ]
}
```

​ 您还可以为服务器指定简单的重定向规则。 语法与Netlify类似。

​ 请注意,status200会触发URL重写,这是在SPA情况下所需要的,例如:

config/development/server.

=== “yaml”

```yaml
redirects:
- force: false
  from: /myspa/**
  status: 200
  to: /myspa/
```

=== “toml”

```toml
[[redirects]]
force = false
from = '/myspa/**'
status = 200
to = '/myspa/'
```

=== “json”

```json
{
   "redirects": [
      {
         "force": false,
         "from": "/myspa/**",
         "status": 200,
         "to": "/myspa/"
      }
   ]
}
```

​ 设置force=true将使重定向即使路径中存在现有内容也会生效。 请注意,在Hugo 0.76之前,force是默认行为,但这符合Netlify的处理方式。

404服务器错误页面 -> [[redirects]]

New in v0.103.0

​ 当运行hugo server时,默认情况下,Hugo将使用404.html模板呈现所有404错误。 请注意,如果您已经添加了一个或多个重定向到服务器配置中,则需要显式添加404重定向,例如:

config/development/server.

=== “yaml”

```yaml
redirects:
- from: /**
  status: 404
  to: /404.html
```

=== “toml”

```toml
[[redirects]]
from = '/**'
status = 404
to = '/404.html'
```

=== “json”

```json
{
   "redirects": [
      {
         "from": "/**",
         "status": 404,
         "to": "/404.html"
      }
   ]
}
```

配置标题大小写 -> titleCaseStyle

​ 设置titleCaseStyle以指定title模板函数和Hugo中自动部分标题使用的标题样式。

​ 默认情况下,Hugo遵循美联社 (Associated Press(AP))风格指南中的大写规则。 如果您想遵循芝加哥风格(Chicago Manual of Style)手册,则将titleCaseStyle设置为chicago,或将其设置为go以使用Go的惯例,即每个单词都大写。

配置环境变量

  • HUGO_NUMWORKERMULTIPLIER

    可以设置为增加或减少在Hugo中并行处理中使用的工作程序数量。 如果未设置,则将使用逻辑CPU的数量。

配置查找顺序

​ 与模板查找顺序类似,Hugo有一组默认规则,用于在站点源目录的根目录中搜索配置文件作为默认行为:

  1. ./config.toml
  2. ./config.yaml
  3. ./config.json

​ 在config文件中,您可以指导Hugo如何渲染您的站点,控制您的站点菜单,并任意定义特定于您的项目的站点范围(site-wide)参数。

示例配置

​ 以下是典型的配置文件示例。在params:下嵌套的值将填充.Site.Params变量,供模板使用:

config.

=== “yaml”

```yaml
baseURL: https://yoursite.example.com/
params:
  AuthorName: Jon Doe
  GitHubUser: spf13
  ListOfFoo:
  - foo1
  - foo2
  SidebarRecentLimit: 5
  Subtitle: Hugo is Absurdly Fast!
permalinks:
  posts: /:year/:month/:title/
title: My Hugo Site
```

=== “toml”

```toml
baseURL = 'https://yoursite.example.com/'
title = 'My Hugo Site'
[params]
  AuthorName = 'Jon Doe'
  GitHubUser = 'spf13'
  ListOfFoo = ['foo1', 'foo2']
  SidebarRecentLimit = 5
  Subtitle = 'Hugo is Absurdly Fast!'
[permalinks]
  posts = '/:year/:month/:title/'
```

=== “json”

```json
{
   "baseURL": "https://yoursite.example.com/",
   "params": {
      "AuthorName": "Jon Doe",
      "GitHubUser": "spf13",
      "ListOfFoo": [
         "foo1",
         "foo2"
      ],
      "SidebarRecentLimit": 5,
      "Subtitle": "Hugo is Absurdly Fast!"
   },
   "permalinks": {
      "posts": "/:year/:month/:title/"
   },
   "title": "My Hugo Site"
}
```

使用环境变量配置

​ 除了已经提到的三个配置选项外,可以通过操作系统环境变量定义配置键值。

​ 例如,以下命令将在类Unix系统上有效地设置站点标题:

1
$ env HUGO_TITLE="Some Title" hugo

​ 如果您使用像Netlify这样的服务部署您的站点,则这非常有用。请参阅Hugo文档中的Netlify配置文件示例

​ 名称必须以HUGO_为前缀,并且设置操作系统环境变量时必须将配置键设置为大写。

​ 要设置配置参数,请使用HUGO_PARAMS_作为前缀。

​ 如果您使用了下划线命名法,则上述方法将无法正常工作。Hugo通过HUGO之后的第一个字符确定要使用的分隔符。这允许您使用任何[允许的](https://stackoverflow.com/questions/2821043/allowed-characters-in-linux-environment-variable-names#:~:text=So names may contain any,not begin with a digit)分隔符来定义形式为HUGOxPARAMSxAPI_KEY=abcdefgh的环境变量。

忽略内容和数据文件的渲染 -> ignoreFiles

​ 注意:这个方法可行,但我们建议您使用更新且更强大的includeFiles和excludeFiles挂载选项。

​ 要在渲染站点时排除特定的contentdata目录中的文件,请将ignoreFiles设置为一个或多个正则表达式,以匹配绝对文件路径。

​ 要忽略以.foo.boo结尾的文件:

=== “yaml”

```yaml
ignoreFiles:
- \.foo$
- \.boo$
```

=== “toml”

```toml
ignoreFiles = ['\.foo$', '\.boo$']
```

=== “json”

```json
{
   "ignoreFiles": [
      "\\.foo$",
      "\\.boo$"
   ]
}
```

​ 通过绝对文件路径忽略一个文件:

=== “yaml”

```yaml
ignoreFiles:
- ^/home/user/project/content/test\.md$
```

=== “toml”

```toml
ignoreFiles = ['^/home/user/project/content/test\.md$']
```

=== “json”

```json
{
   "ignoreFiles": [
      "^/home/user/project/content/test\\.md$"
   ]
}
```

配置Front Matter -> [frontmatter]

配置日期

​ 日期在Hugo中很重要,您可以通过向config.toml添加frontmatter部分来配置Hugo如何为您的内容页面分配日期。

默认配置如下:

config.

=== “yaml”

```yaml
frontmatter:
  date:
  - date
  - publishDate
  - lastmod
  expiryDate:
  - expiryDate
  lastmod:
  - :git
  - lastmod
  - date
  - publishDate
  publishDate:
  - publishDate
  - date
```

=== “toml”

```toml
[frontmatter]
  date = ['date', 'publishDate', 'lastmod']
  expiryDate = ['expiryDate']
  lastmod = [':git', 'lastmod', 'date', 'publishDate']
  publishDate = ['publishDate', 'date']
```

=== “json”

```json
{
   "frontmatter": {
      "date": [
         "date",
         "publishDate",
         "lastmod"
      ],
      "expiryDate": [
         "expiryDate"
      ],
      "lastmod": [
         ":git",
         "lastmod",
         "date",
         "publishDate"
      ],
      "publishDate": [
         "publishDate",
         "date"
      ]
   }
}
```

​ 如果您的一些内容中具有非标准日期参数,您可以覆盖date的设置:

config.

=== “yaml”

```yaml
frontmatter:
  date:
  - myDate
  - :default
```

=== “toml”

```toml
[frontmatter]
  date = ['myDate', ':default']
```

=== “json”

```json
{
   "frontmatter": {
      "date": [
         "myDate",
         ":default"
      ]
   }
}
```

:default是默认设置的快捷方式。以上设置将根据需要将.Date设置为myDate中的日期值,如果不存在,则会查找datepublishDatelastmod并选择第一个有效日期。

​ 在右侧的列表中,以":“开头的值是具有特殊含义的日期处理程序(见下文)。其他的只是您的正文数据配置中日期参数的名称(大小写不敏感)。另请注意,Hugo有一些内置别名:lastmod => modifiedpublishDate => pubdatepublishedexpiryDate => unpublishdate。例如,使用front matter中的pubDate作为日期将默认分配给.PublishDate

​ 特殊日期处理程序为:

  • :fileModTime

    从内容文件的最后修改时间戳中提取日期。

例如:

config.

=== “yaml”

```yaml
frontmatter:
  lastmod:
  - lastmod
  - :fileModTime
  - :default
```

=== “toml”

```toml
[frontmatter]
  lastmod = ['lastmod', ':fileModTime', ':default']
```

=== “json”

```json
{
   "frontmatter": {
      "lastmod": [
         "lastmod",
         ":fileModTime",
         ":default"
      ]
   }
}
```

​ 上面的配置将首先尝试从front matter参数中lastmod 提取.Lastmod的值,然后再从内容文件的修改时间戳中提取日期值。最后,:default在这里不需要,但是Hugo最终会在:gitdatepublishDate中查找有效的日期。

  • :filename

    从内容文件的文件名中提取日期。例如,2018-02-22-mypage.md将提取日期2018-02-22。此外,如果slug未设置,则mypage将作为.Slug的值。

例如:

config.

=== “yaml”

```yaml
frontmatter:
  date:
  - :filename
  - :default
```

=== “toml”

```toml
[frontmatter]
  date = [':filename', ':default']
```

=== “json”

```json
{
   "frontmatter": {
      "date": [
         ":filename",
         ":default"
      ]
   }
}
```

​ 以上配置将首先尝试从文件名中提取.Date的值,然后再从front matter参数的datepublishDatelastmod中查找。

  • :git

    这是此内容文件的最后修订版的Git作者日期。这只有在设置了 --enableGitInfo 或在站点配置中设置了 enableGitInfo = true 时才会被设置。

配置其他输出格式

​ Hugo v0.20引入了将内容呈现为多种输出格式(例如JSON、AMP html或CSV)的能力。请参阅输出格式,了解如何将这些值添加到您的Hugo项目配置文件中。

配置压缩 -> [minify]

默认配置:

config.

=== “yaml”

```yaml
minify:
  disableCSS: false
  disableHTML: false
  disableJS: false
  disableJSON: false
  disableSVG: false
  disableXML: false
  minifyOutput: false
  tdewolff:
    css:
      keepCSS2: true
      precision: 0
    html:
      keepComments: false
      keepConditionalComments: true
      keepDefaultAttrVals: true
      keepDocumentTags: true
      keepEndTags: true
      keepQuotes: false
      keepWhitespace: false
    js:
      keepVarNames: false
      noNullishOperator: false
      precision: 0
    json:
      keepNumbers: false
      precision: 0
    svg:
      keepComments: false
      precision: 0
    xml:
      keepWhitespace: false
```

=== “toml”

```toml
[minify]
  disableCSS = false
  disableHTML = false
  disableJS = false
  disableJSON = false
  disableSVG = false
  disableXML = false
  minifyOutput = false
  [minify.tdewolff]
    [minify.tdewolff.css]
      keepCSS2 = true
      precision = 0
    [minify.tdewolff.html]
      keepComments = false
      keepConditionalComments = true
      keepDefaultAttrVals = true
      keepDocumentTags = true
      keepEndTags = true
      keepQuotes = false
      keepWhitespace = false
    [minify.tdewolff.js]
      keepVarNames = false
      noNullishOperator = false
      precision = 0
    [minify.tdewolff.json]
      keepNumbers = false
      precision = 0
    [minify.tdewolff.svg]
      keepComments = false
      precision = 0
    [minify.tdewolff.xml]
      keepWhitespace = false
```

=== “json”

```json
{
   "minify": {
      "disableCSS": false,
      "disableHTML": false,
      "disableJS": false,
      "disableJSON": false,
      "disableSVG": false,
      "disableXML": false,
      "minifyOutput": false,
      "tdewolff": {
         "css": {
            "keepCSS2": true,
            "precision": 0
         },
         "html": {
            "keepComments": false,
            "keepConditionalComments": true,
            "keepDefaultAttrVals": true,
            "keepDocumentTags": true,
            "keepEndTags": true,
            "keepQuotes": false,
            "keepWhitespace": false
         },
         "js": {
            "keepVarNames": false,
            "noNullishOperator": false,
            "precision": 0
         },
         "json": {
            "keepNumbers": false,
            "precision": 0
         },
         "svg": {
            "keepComments": false,
            "precision": 0
         },
         "xml": {
            "keepWhitespace": false
         }
      }
   }
}
```

配置文件缓存 -> [caches]

​ 自Hugo 0.52版本以来,您可以配置的不仅是cacheDir。这是默认配置:

=== “yaml”

```yaml
caches:
  assets:
    dir: :resourceDir/_gen
    maxAge: -1
  getcsv:
    dir: :cacheDir/:project
    maxAge: -1
  getjson:
    dir: :cacheDir/:project
    maxAge: -1
  getresource:
    dir: :cacheDir/:project
    maxAge: -1
  images:
    dir: :resourceDir/_gen
    maxAge: -1
  modules:
    dir: :cacheDir/modules
    maxAge: -1
```

=== “toml”

```toml
[caches]
  [caches.assets]
    dir = ':resourceDir/_gen'
    maxAge = -1
  [caches.getcsv]
    dir = ':cacheDir/:project'
    maxAge = -1
  [caches.getjson]
    dir = ':cacheDir/:project'
    maxAge = -1
  [caches.getresource]
    dir = ':cacheDir/:project'
    maxAge = -1
  [caches.images]
    dir = ':resourceDir/_gen'
    maxAge = -1
  [caches.modules]
    dir = ':cacheDir/modules'
    maxAge = -1
```

=== “json”

```json
{
   "caches": {
      "assets": {
         "dir": ":resourceDir/_gen",
         "maxAge": -1
      },
      "getcsv": {
         "dir": ":cacheDir/:project",
         "maxAge": -1
      },
      "getjson": {
         "dir": ":cacheDir/:project",
         "maxAge": -1
      },
      "getresource": {
         "dir": ":cacheDir/:project",
         "maxAge": -1
      },
      "images": {
         "dir": ":resourceDir/_gen",
         "maxAge": -1
      },
      "modules": {
         "dir": ":cacheDir/modules",
         "maxAge": -1
      }
   }
}
```

​ 您可以在自己的config.toml中覆盖这些缓存设置。

关键字的解释

  • :cacheDir

    这是cacheDir配置选项的值,如果设置了的话(也可以通过OS环境变量HUGO_CACHEDIR设置)。如果在Netlify上,将回退到/opt/build/cache/hugo_cache/,对于其他的操作系统,将位于操作系统临时目录下的hugo_cache目录。这意味着,如果您在Netlify上运行构建,所有配置为:cacheDir的缓存都将保存并在下一次构建时恢复。对于其他的CI供应商,请阅读其文档。有关CircleCI示例,请参见此配置

  • :project

    当前Hugo项目的基本目录名称。这意味着,在默认设置中,每个项目都有单独的文件缓存,这意味着当您运行hugo --gc时,您不会触及与其他在同一台电脑上运行的Hugo项目相关的文件。

  • :resourceDir

    这是resourceDir配置选项的值。

  • maxAge

    这是缓存条目被清除之前的持续时间,-1表示永远,0有效地关闭该特定缓存。使用Go的time.Duration,所以有效值是"10s"(10秒),"10m"(10分钟)和"10h"(10小时)。

  • dir

    这是用于存储此缓存文件的绝对路径。允许的起始占位符是:cacheDir:resourceDir(见上文)。

配置格式规范

参见

3.5 - Configure Markup

Configure Markup

How to handle Markdown and other markup related configuration.

Configure Markup

See Goldmark for settings related to the default Markdown handler in Hugo.

Below are all markup related configuration in Hugo with their default settings:

config.

=== “yaml”

```yaml
markup:
  asciidocExt:
    attributes: {}
    backend: html5
    extensions: []
    failureLevel: fatal
    noHeaderOrFooter: true
    preserveTOC: false
    safeMode: unsafe
    sectionNumbers: false
    trace: false
    verbose: false
    workingFolderCurrent: false
  defaultMarkdownHandler: goldmark
  goldmark:
    extensions:
      definitionList: true
      footnote: true
      linkify: true
      linkifyProtocol: https
      strikethrough: true
      table: true
      taskList: true
      typographer: true
    parser:
      attribute:
        block: false
        title: true
      autoHeadingID: true
      autoHeadingIDType: github
      wrapStandAloneImageWithinParagraph: true
    renderer:
      hardWraps: false
      unsafe: false
      xhtml: false
  highlight:
    anchorLineNos: false
    codeFences: true
    guessSyntax: false
    hl_Lines: ""
    hl_inline: false
    lineAnchors: ""
    lineNoStart: 1
    lineNos: false
    lineNumbersInTable: true
    noClasses: true
    noHl: false
    style: monokai
    tabWidth: 4
  tableOfContents:
    endLevel: 3
    ordered: false
    startLevel: 2
```

=== “toml”

```toml
[markup]
  defaultMarkdownHandler = 'goldmark'
  [markup.asciidocExt]
    backend = 'html5'
    extensions = []
    failureLevel = 'fatal'
    noHeaderOrFooter = true
    preserveTOC = false
    safeMode = 'unsafe'
    sectionNumbers = false
    trace = false
    verbose = false
    workingFolderCurrent = false
    [markup.asciidocExt.attributes]
  [markup.goldmark]
    [markup.goldmark.extensions]
      definitionList = true
      footnote = true
      linkify = true
      linkifyProtocol = 'https'
      strikethrough = true
      table = true
      taskList = true
      typographer = true
    [markup.goldmark.parser]
      autoHeadingID = true
      autoHeadingIDType = 'github'
      wrapStandAloneImageWithinParagraph = true
      [markup.goldmark.parser.attribute]
        block = false
        title = true
    [markup.goldmark.renderer]
      hardWraps = false
      unsafe = false
      xhtml = false
  [markup.highlight]
    anchorLineNos = false
    codeFences = true
    guessSyntax = false
    hl_Lines = ''
    hl_inline = false
    lineAnchors = ''
    lineNoStart = 1
    lineNos = false
    lineNumbersInTable = true
    noClasses = true
    noHl = false
    style = 'monokai'
    tabWidth = 4
  [markup.tableOfContents]
    endLevel = 3
    ordered = false
    startLevel = 2
```

=== “json”

```json
{
   "markup": {
      "asciidocExt": {
         "attributes": {},
         "backend": "html5",
         "extensions": [],
         "failureLevel": "fatal",
         "noHeaderOrFooter": true,
         "preserveTOC": false,
         "safeMode": "unsafe",
         "sectionNumbers": false,
         "trace": false,
         "verbose": false,
         "workingFolderCurrent": false
      },
      "defaultMarkdownHandler": "goldmark",
      "goldmark": {
         "extensions": {
            "definitionList": true,
            "footnote": true,
            "linkify": true,
            "linkifyProtocol": "https",
            "strikethrough": true,
            "table": true,
            "taskList": true,
            "typographer": true
         },
         "parser": {
            "attribute": {
               "block": false,
               "title": true
            },
            "autoHeadingID": true,
            "autoHeadingIDType": "github",
            "wrapStandAloneImageWithinParagraph": true
         },
         "renderer": {
            "hardWraps": false,
            "unsafe": false,
            "xhtml": false
         }
      },
      "highlight": {
         "anchorLineNos": false,
         "codeFences": true,
         "guessSyntax": false,
         "hl_Lines": "",
         "hl_inline": false,
         "lineAnchors": "",
         "lineNoStart": 1,
         "lineNos": false,
         "lineNumbersInTable": true,
         "noClasses": true,
         "noHl": false,
         "style": "monokai",
         "tabWidth": 4
      },
      "tableOfContents": {
         "endLevel": 3,
         "ordered": false,
         "startLevel": 2
      }
   }
}
```

See each section below for details.

Goldmark

Goldmark is from Hugo 0.60 the default library used for Markdown. It’s fast, it’s CommonMark compliant and it’s very flexible.

This is the default configuration:

config.

=== “yaml”

```yaml
markup:
  goldmark:
    extensions:
      definitionList: true
      footnote: true
      linkify: true
      linkifyProtocol: https
      strikethrough: true
      table: true
      taskList: true
      typographer: true
    parser:
      attribute:
        block: false
        title: true
      autoHeadingID: true
      autoHeadingIDType: github
      wrapStandAloneImageWithinParagraph: true
    renderer:
      hardWraps: false
      unsafe: false
      xhtml: false
```

=== “toml”

```toml
[markup]
  [markup.goldmark]
    [markup.goldmark.extensions]
      definitionList = true
      footnote = true
      linkify = true
      linkifyProtocol = 'https'
      strikethrough = true
      table = true
      taskList = true
      typographer = true
    [markup.goldmark.parser]
      autoHeadingID = true
      autoHeadingIDType = 'github'
      wrapStandAloneImageWithinParagraph = true
      [markup.goldmark.parser.attribute]
        block = false
        title = true
    [markup.goldmark.renderer]
      hardWraps = false
      unsafe = false
      xhtml = false
```

=== “json”

```json
{
   "markup": {
      "goldmark": {
         "extensions": {
            "definitionList": true,
            "footnote": true,
            "linkify": true,
            "linkifyProtocol": "https",
            "strikethrough": true,
            "table": true,
            "taskList": true,
            "typographer": true
         },
         "parser": {
            "attribute": {
               "block": false,
               "title": true
            },
            "autoHeadingID": true,
            "autoHeadingIDType": "github",
            "wrapStandAloneImageWithinParagraph": true
         },
         "renderer": {
            "hardWraps": false,
            "unsafe": false,
            "xhtml": false
         }
      }
   }
}
```

For details on the extensions, refer to this section of the Goldmark documentation

Some settings explained:

  • hardWraps

    By default, Goldmark ignores newlines within a paragraph. Set to true to render newlines as <br> elements.

  • unsafe

    By default, Goldmark does not render raw HTMLs and potentially dangerous links. If you have lots of inline HTML and/or JavaScript, you may need to turn this on.

  • typographer

    This extension substitutes punctuations with typographic entities like smartypants.

  • attribute

    Enable custom attribute support for titles and blocks by adding attribute lists inside single curly brackets ({.myclass class="class1 class2" }) and placing it after the Markdown element it decorates, on the same line for titles and on a new line directly below for blocks.

Hugo supports adding attributes (e.g. CSS classes) to Markdown blocks, e.g. tables, lists, paragraphs etc.

A blockquote with a CSS class:

1
2
3
> foo
> bar
{.myclass}

There are some current limitations: For tables you can currently only apply it to the full table, and for lists the ul/ol-nodes only, e.g.:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
* Fruit
  * Apple
  * Orange
  * Banana
  {.fruits}
* Dairy
  * Milk
  * Cheese
  {.dairies}
{.list}

Note that attributes in code fences must come after the opening tag, with any other highlighting processing instruction, e.g.:

1
2
3
```go {.myclass linenos=table,hl_lines=[8,"15-17"],linenostart=199}
// ... code
```
  • autoHeadingIDType (“github”)

    The strategy used for creating auto IDs (anchor names). Available types are github, github-ascii and blackfriday. github produces GitHub-compatible IDs, github-ascii will drop any non-Ascii characters after accent normalization, and blackfriday will make the IDs compatible with Blackfriday, the default Markdown engine before Hugo 0.60. Note that if Goldmark is your default Markdown engine, this is also the strategy used in the anchorize template func.

Highlight

This is the default highlight configuration. Note that some of these settings can be set per code block, see Syntax Highlighting.

config.

=== “yaml”

```yaml
markup:
  highlight:
    anchorLineNos: false
    codeFences: true
    guessSyntax: false
    hl_Lines: ""
    hl_inline: false
    lineAnchors: ""
    lineNoStart: 1
    lineNos: false
    lineNumbersInTable: true
    noClasses: true
    noHl: false
    style: monokai
    tabWidth: 4
```

=== “toml”

```toml
[markup]
  [markup.highlight]
    anchorLineNos = false
    codeFences = true
    guessSyntax = false
    hl_Lines = ''
    hl_inline = false
    lineAnchors = ''
    lineNoStart = 1
    lineNos = false
    lineNumbersInTable = true
    noClasses = true
    noHl = false
    style = 'monokai'
    tabWidth = 4
```

=== “json”

```json
{
   "markup": {
      "highlight": {
         "anchorLineNos": false,
         "codeFences": true,
         "guessSyntax": false,
         "hl_Lines": "",
         "hl_inline": false,
         "lineAnchors": "",
         "lineNoStart": 1,
         "lineNos": false,
         "lineNumbersInTable": true,
         "noClasses": true,
         "noHl": false,
         "style": "monokai",
         "tabWidth": 4
      }
   }
}
```

For style, see these galleries:

For CSS, see Generate Syntax Highlighter CSS.

Table Of Contents

config.

=== “yaml”

```yaml
markup:
  tableOfContents:
    endLevel: 3
    ordered: false
    startLevel: 2
```

=== “toml”

```toml
[markup]
  [markup.tableOfContents]
    endLevel = 3
    ordered = false
    startLevel = 2
```

=== “json”

```json
{
   "markup": {
      "tableOfContents": {
         "endLevel": 3,
         "ordered": false,
         "startLevel": 2
      }
   }
}
```

These settings only works for the Goldmark renderer:

  • startLevel

    The heading level, values starting at 1 (h1), to start render the table of contents.

  • endLevel

    The heading level, inclusive, to stop render the table of contents.

  • ordered

    Whether or not to generate an ordered list instead of an unordered list.

Markdown Render Hooks

See Markdown Render Hooks.

See Also

3.6 - 外部学习资源

External Learning Resources - 外部学习资源

https://gohugo.io/getting-started/external-learning-resources/

​ 关于 Hugo 的教程和书籍列表。

书籍

Hugo 实战

Hugo In Action

《Hugo 实战》是一本使用 Hugo 创建静态站点的逐步指南。您将使用一个完整的示例站点和源代码示例来学习如何构建和托管一个低维护、高性能的站点,它将为您的用户提供令人惊叹的体验,并且不需要依赖于第三方服务器。

Hugo 实战主页

使用 Hugo 构建站点

《使用 Hugo 构建站点:使用 Markdown 进行快速 Web 开发》(2020) 作者 Brian P. Hogan。

初学者教程

CloudCannon 的 Hugo 教程

逐步书面教程,教您创建 Hugo 站点的基础知识。

视频教程

另请参阅

4 - Hugo模块

Hugo Modules - Hugo 模块

https://gohugo.io/hugo-modules/

​ Hugo 模块是 Hugo 的核心构建块。一个模块可以是您的主项目或一个较小的模块,提供 Hugo 中定义的 7 种组件类型之一或多个组件类型:staticcontentlayoutsdataassetsi18narchetypes

​ 您可以以任何组合方式组合模块,甚至挂载来自非 Hugo 项目的目录,形成一个大的虚拟联合文件系统。

​ Hugo 模块由 Go 模块驱动。有关 Go 模块的更多信息,请参见:

​ 这一切都是全新的,只有很少几个示例项目:

4.1 - 配置模块

Configure Modules - 配置模块

https://gohugo.io/hugo-modules/configuration/

​ 本页描述了模块的配置选项。

模块配置:Top level -> [module]

config.

=== “yaml”

```yaml
module:
  noProxy: none
  noVendor: ""
  private: '*.*'
  proxy: direct
  replacements: ""
  workspace: "off"
```

=== “toml”

```toml
[module]
  noProxy = 'none'
  noVendor = ''
  private = '*.*'
  proxy = 'direct'
  replacements = ''
  workspace = 'off'
```

=== “json”

```json
{
   "module": {
      "noProxy": "none",
      "noVendor": "",
      "private": "*.*",
      "proxy": "direct",
      "replacements": "",
      "workspace": "off"
   }
}
```

noVendor

​ 一个可选的 Glob 模式,用于匹配在vendoring时跳过的模块路径,例如"github.com/**"

vendorClosest

​ 当启用时,我们将选择与使用它的模块最接近的vendored模块。默认行为是选择第一个。请注意,每个给定模块路径仍然只能有一个依赖项,因此一旦使用它,就无法重新定义它。

proxy

​ 定义用于下载远程模块的代理服务器。默认值为 direct,表示"git clone"等。

noProxy

​ 逗号分隔的 glob 列表,匹配不应使用上述配置的代理的路径。

private

​ 逗号分隔的 glob 列表,匹配应视为私有的路径。

workspace

​ 要使用的工作区文件。这启用了 Go 工作区模式。请注意,这也可以通过操作系统 env 设置,例如 export HUGO_MODULE_WORKSPACE=/my/hugo.work。这仅适用于 Go 1.18+。在 Hugo v0.109.0 中,我们将默认设置为 off,并且现在会将任何相对的工作文件名解析为相对于工作目录。

replacements

​ 从模块路径到目录的映射的逗号分隔列表,例如 github.com/bep/my-theme -> ../..,github.com/bep/shortcodes -> /some/path。这对于临时本地开发模块非常有用,在这种情况下,您可能希望将其保存为环境变量,例如:env HUGO_MODULE_REPLACEMENTS="github.com/bep/my-theme -> ../.."。相对路径相对于 themesDir。允许使用绝对路径。

​ 请注意,上述术语直接映射到 Go 模块中的对应项。设置其中的一些可能会自然地设置为操作系统环境变量。例如,要设置要使用的代理服务器:

1
env HUGO_MODULE_PROXY=https://proxy.example.org hugo

​ Hugo 模块的大多数命令需要安装更新版本的 Go(请参阅 https://golang.org/dl/)和相关的 VCS 客户端(例如 Git,请参阅 https://git-scm.com/downloads/)。如果您在 Netlify 上运行"旧"站点,则可能必须在环境设置中将 GO_VERSION 设置为 1.12。

​ 有关 Go 模块的更多信息,请参见:

模块配置:hugoVersion -> [module.hugoVersion]

​ 如果您的模块需要特定版本的Hugo才能正常工作,您可以在module部分中指示,并且如果使用过于旧或新的版本,用户将收到警告。

config.

=== “yaml”

```yaml
module:
  hugoVersion:
    extended: false
    max: ""
    min: ""
```

=== “toml”

```toml
[module]
  [module.hugoVersion]
    extended = false
    max = ''
    min = ''
```

=== “json”

```json
{
   "module": {
      "hugoVersion": {
         "extended": false,
         "max": "",
         "min": ""
      }
   }
}
```

​ 以上任何内容均可省略。

min

​ 支持的最低Hugo版本,例如0.55.0

max

​ 支持的最高Hugo版本,例如0.55.0

extended

​ 是否需要Hugo的扩展版本。

模块配置:imports ->[[module.imports]]

config.

=== “yaml”

```yaml
module:
  imports:
  - disable: false
    ignoreConfig: false
    ignoreImports: false
    path: github.com/gohugoio/hugoTestModules1_linux/modh1_2_1v
  - path: my-shortcodes
```

=== “toml”

```toml
[module]
[[module.imports]]
  disable = false
  ignoreConfig = false
  ignoreImports = false
  path = 'github.com/gohugoio/hugoTestModules1_linux/modh1_2_1v'
[[module.imports]]
  path = 'my-shortcodes'
```

=== “json”

```json
{
   "module": {
      "imports": [
         {
            "disable": false,
            "ignoreConfig": false,
            "ignoreImports": false,
            "path": "github.com/gohugoio/hugoTestModules1_linux/modh1_2_1v"
         },
         {
            "path": "my-shortcodes"
         }
      ]
   }
}
```

path

​ 可以是一个有效的 Go 模块路径,例如 github.com/gohugoio/myShortcodes,或者是存储在您主题文件夹中的模块目录名称。

ignoreConfig

​ 如果启用,将不会加载任何模块配置文件,例如 config.toml。请注意,这也会停止加载任何传递模块依赖项。

ignoreImports

​ 如果启用,将不跟随模块导入。

disable

​ 将其设置为true以禁用该模块,同时保留go.*文件中的任何版本信息。

noMounts

​ 不要在此导入中挂载任何文件夹。

noVendor

​ 永远不要将此导入内容纳入 vendor(仅允许在主项目中)。

​ 大多数Hugo模块命令需要安装更新的Go版本(请参见https://golang.org/dl/)和相关的VCS客户端(例如Git,请参见https://git-scm.com/downloads/)。如果您在Netlify上运行"旧"站点,则可能需要在环境设置中将GO_VERSION设置为1.12。

​ 有关Go模块的更多信息,请参见:

模块配置:mounts -> [[module.mounts]]

​ 在Hugo 0.56.0中引入mounts配置时,我们小心地保留了现有的contentDirstaticDir等配置,以确保所有现有站点都能继续工作。但是,您不应同时使用两者:如果您添加了mounts部分,则应删除旧的contentDirstaticDir等设置。

​ 当您添加mount时,有关目标根目录的默认mount将被忽略:请确保明确添加它。

默认挂载点

config.

=== “yaml”

```yaml
module:
  mounts:
  - source: content
    target: content
  - source: static
    target: static
  - source: layouts
    target: layouts
  - source: data
    target: data
  - source: assets
    target: assets
  - source: i18n
    target: i18n
  - source: archetypes
    target: archetypes
```

=== “toml”

```toml
[module]
[[module.mounts]]
  source = 'content'
  target = 'content'
[[module.mounts]]
  source = 'static'
  target = 'static'
[[module.mounts]]
  source = 'layouts'
  target = 'layouts'
[[module.mounts]]
  source = 'data'
  target = 'data'
[[module.mounts]]
  source = 'assets'
  target = 'assets'
[[module.mounts]]
  source = 'i18n'
  target = 'i18n'
[[module.mounts]]
  source = 'archetypes'
  target = 'archetypes'
```

=== “json”

```json
{
   "module": {
      "mounts": [
         {
            "source": "content",
            "target": "content"
         },
         {
            "source": "static",
            "target": "static"
         },
         {
            "source": "layouts",
            "target": "layouts"
         },
         {
            "source": "data",
            "target": "data"
         },
         {
            "source": "assets",
            "target": "assets"
         },
         {
            "source": "i18n",
            "target": "i18n"
         },
         {
            "source": "archetypes",
            "target": "archetypes"
         }
      ]
   }
}
```

source

挂载点的源目录。对于主项目,可以是相对于项目的路径,也可以是绝对路径,甚至可以是符号链接。对于其他模块,它必须是相对于项目的路径。

target

它应该被挂载到Hugo虚拟文件系统中的位置。它必须以Hugo的组件文件夹之一开头:staticcontentlayoutsdataassetsi18narchetypes。例如,content/blog

lang

语言代码,例如"en"。只适用于content挂载和多主机模式下的static挂载。

includeFiles (string or slice)

​ 一个或多个用于匹配要包括的文件或目录的glob(通配符)。如果未设置excludeFiles,则与includeFiles匹配的文件将被挂载。

​ 这些通配符从source根开始匹配文件名,它们应该使用Unix样式的斜杠,即使在Windows上也是如此。 /匹配挂载点根目录,**可以用作超级星号以递归匹配所有目录,例如/posts/**.jpg

​ 搜索时忽略大小写。

excludeFiles (字符串或切片)

​ 一个或多个用于匹配要排除的文件的通配符。

示例

config.

=== “yaml”

```yaml
module:
  mounts:
  - excludeFiles: docs/*
    source: content
    target: content
```

=== “toml”

```toml
[module]
[[module.mounts]]
  excludeFiles = 'docs/*'
  source = 'content'
  target = 'content'
```

=== “json”

```json
{
   "module": {
      "mounts": [
         {
            "excludeFiles": "docs/*",
            "source": "content",
            "target": "content"
         }
      ]
   }
}
```

参见

4.2 - 使用 Hugo 模块

Use Hugo Modules - 使用 Hugo 模块

https://gohugo.io/hugo-modules/use-modules/

​ 如何使用 Hugo 模块来构建和管理您的站点。

先决条件

​ 大多数 Hugo 模块的命令需要安装更新版本的 Go(请参阅 https://golang.org/dl/)和相关的 VCS 客户端(例如 Git,请参阅 https://git-scm.com/downloads/)。如果您在 Netlify 上运行的是"旧"站点,则可能需要在环境设置中将 GO_VERSION 设置为 1.12。

​ 有关 Go 模块的更多信息,请参见:

初始化新模块

​ 使用 hugo mod init 初始化一个新的 Hugo 模块。如果它无法猜测模块路径,您必须提供它作为参数,例如:

1
hugo mod init github.com/gohugoio/myShortcodes

​ 另请参阅 CLI 文档

为主题使用模块

​ 使用模块作为主题的最简单方法是在配置中导入它。

  1. 初始化 hugo 模块系统:hugo mod init github.com/<your_user>/<your_project>
  2. 导入主题:

config.

=== “yaml”

```yaml
module:
  imports:
  - path: github.com/spf13/hyde
```

=== “toml”

```toml
[module]
[[module.imports]]
  path = 'github.com/spf13/hyde'
```

=== “json”

```json
{
   "module": {
      "imports": [
         {
            "path": "github.com/spf13/hyde"
         }
      ]
   }
}
```

更新模块

​ 将模块作为导入项添加到您的配置文件时,模块将被下载并添加,详见模块导入

​ 要更新或管理版本,可以使用 hugo mod get 命令。

​ 以下是一些示例:

更新所有模块

1
hugo mod get -u

递归更新所有模块

1
hugo mod get -u ./...

更新一个模块

1
hugo mod get -u github.com/gohugoio/myShortcodes

获取特定版本

1
hugo mod get github.com/gohugoio/myShortcodes@v1.0.7

​ 另请参阅 CLI 文档

在模块中进行更改和测试

​ 在项目中导入模块并进行本地开发的一种方法是在 go.mod 中使用replace 指令将本地目录与源代码联系起来:

1
replace github.com/bep/hugotestmods/mypartials => /Users/bep/hugotestmods/mypartials

​ 如果 hugo server正在运行,则会重新加载配置,并将 /Users/bep/hugotestmods/mypartials 添加到监视列表中。

​ 除了修改 go.mod 文件之外,您还可以使用模块配置的replacements选项。

打印依赖项图

​ 从相关的模块目录使用 hugo mod graph 命令,它将打印依赖项图,包括 vendoring、模块替换或禁用状态。

E.g.:

1
2
3
4
5
6
7
8
9
hugo mod graph

github.com/bep/my-modular-site github.com/bep/hugotestmods/mymounts@v1.2.0
github.com/bep/my-modular-site github.com/bep/hugotestmods/mypartials@v1.0.7
github.com/bep/hugotestmods/mypartials@v1.0.7 github.com/bep/hugotestmods/myassets@v1.0.4
github.com/bep/hugotestmods/mypartials@v1.0.7 github.com/bep/hugotestmods/myv2@v1.0.0
DISABLED github.com/bep/my-modular-site github.com/spf13/hyde@v0.0.0-20190427180251-e36f5799b396
github.com/bep/my-modular-site github.com/bep/hugo-fresh@v1.0.1
github.com/bep/my-modular-site in-themesdir

​ 另请参阅 CLI 文档

Vendor Your Modules

​ 运行hugo mod vendor将所有模块依赖项写入_vendor文件夹,然后在所有后续构建中使用它们。

请注意:

  • 您可以在模块树的任何级别上运行 hugo mod vendor
  • 存储在themes文件夹中的模块不会被存储到Vendoring目录中。
  • 大多数命令接受--ignoreVendorPaths标志,然后不会对与给定Glob模式匹配的模块路径使用_vendor中的供应商模块。

​ 另请参阅CLI文档

整理go.mod、go.sum

​ 运行 hugo mod tidy 以删除 go.modgo.sum 中未使用的条目。

​ 另请参阅CLI文档

清除模块缓存

​ 运行 hugo mod clean 以删除整个模块缓存。

​ 请注意,您还可以通过 maxAge 配置模块缓存,请参阅文件缓存

​ 另请参阅CLI文档

模块工作区

New in v0.109.0

Go 1.18 版本中增加了工作区支持,而 Hugo 在 v0.109.0 版本中得到了稳定的支持。

​ 工作区的常见用途是简化带有其主题模块的站点的本地开发。

​ 可以在 *.work 文件中配置工作区,并通过 module.workspace 设置激活它,对于此用法下通常由 HUGO_MODULE_WORKSPACE 操作系统环境变量控制。

​ 在Hugo 文档库中查看hugo.work文件以获取示例:

go 1.19

use .
use ../gohugoioTheme

​ 使用 use 指令,列出您要处理的所有模块,指向其相对位置。如上例所示,建议始终在列表中包括主项目(".")。

​ 有了这个指令,您可以使用启用了该工作区的Hugo服务器:

HUGO_MODULE_WORKSPACE=hugo.work hugo server --ignoreVendorPaths "**"

​ 上面添加了 --ignoreVendorPaths 标志,以忽略 _vendor 中与给定 Glob 模式匹配的模块路径中的任何存储的依赖项。如果您不使用 vendoring,则不需要该标志。但现在,服务器设置为监视工作区中的文件和目录,您可以看到重新加载本地编辑。

另请参阅

4.3 - 主题组件

Theme Components - 主题组件

https://gohugo.io/hugo-modules/theme-components/

​ Hugo 提供了主题组件的高级主题支持。

​ 本部分包含的信息可能已过时,并正在重写过程中。

​ 从 Hugo 0.42 版本开始,项目可以将主题配置为所需的多个主题组件的组合:

config.

=== “yaml”

```yaml
theme:
- my-shortcodes
- base-theme
- hyde
```

=== “toml”

```toml
theme = ['my-shortcodes', 'base-theme', 'hyde']
```

=== “json”

```json
{
   "theme": [
      "my-shortcodes",
      "base-theme",
      "hyde"
   ]
}
```

​ 甚至可以嵌套使用,主题组件本身可以在其 own config.toml 中包含主题组件 (主题继承)。1

​ 上述 config.toml 中的主题定义示例创建了一个具有从左到右优先级的三个主题组件的主题。

​ 对于任何给定的文件、数据条目等,Hugo 将首先查找项目,然后查找 my-shortcodesbase-theme,最后是 hyde

​ Hugo 使用两种不同的算法来合并文件系统,具体取决于文件类型:

  • 对于 i18ndata文件,Hugo 使用文件内部的翻译 ID 和数据键进行深度合并。
  • 对于static文件、layouts (templates) 和archetypes文件,这些文件在文件级别上进行合并。所以最左边的文件将被选中。

​ 上面的theme定义中使用的名称必须与 /your-site/themes 中的一个文件夹相匹配,例如 /your-site/themes/my-shortcodes。计划改进此功能,并获取 URL 方案,以便可以自动解析。

​ 还要注意,作为主题的组件可以有自己的配置文件,例如 config.toml。目前,主题组件可以配置的内容存在一些限制:

  • params (global and per language)
  • menu (global and per language)
  • outputformats and mediatypes

​ 这里也适用相同的规则:具有相同 ID 的最左边的 param/menu 等将获胜。上述内容中还存在一些隐藏的实验性命名空间支持,我们将在未来努力改进,但鼓励主题作者创建自己的命名空间,以避免命名冲突。


  1. 对于托管在 Hugo Themes Showcase中的主题组件,需要将组件添加为 git 子模块,指向目录 exampleSite/themes。 ↩︎

另请参阅

5 - 内容管理

Content Management - 内容管理

https://gohugo.io/content-management/

​ 静态站点生成器需要扩展超越前置元数据和几个模板才能实现可伸缩性和可管理性。Hugo 设计时不仅考虑了开发人员,也考虑了内容管理人员和作者。

5.1 - 内容组织

Content Organization - 内容组织

https://gohugo.io/content-management/organization/

Hugo assumes that the same structure that works to organize your source content is used to organize the rendered site.【好复杂的从句】

​ Hugo 假设用于组织源内容的结构与用于组织渲染站点的结构相同。

Page Bundles

​ Hugo 0.32 引入了页面相关的图像和其他资源封装为Page Bundles的功能。

​ 这些术语是相关的,您还需要阅读页面资源(Page Resources)和图像处理(Image Processing)等相关文档才能获得全面的信息。

img

​ 示意图显示了三个bundle。请注意,主页bundle不能包含其他内容页面,虽然允许包含其他文件(如图像)。

bundle文档仍在完善中。我们会尽快发布更全面的文档。

Organization of Content Source

​ 在 Hugo 中,您的内容应该按照反映渲染站点的方式进行组织。

​ 虽然 Hugo 支持嵌套在任何级别的内容,但顶层(即 content/<DIRECTORIES>)在 Hugo 中是特殊的,并且被视为用于确定布局等内容类型。要了解更多有关部分的信息,包括如何嵌套它们,请参阅sections

​ 在没有任何额外配置的情况下,以下内容将自动工作:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.
└── content
    └── about
    |   └── index.md  // <- https://example.com/about/
    ├── posts
    |   ├── firstpost.md   // <- https://example.com/posts/firstpost/
    |   ├── happy
    |   |   └── ness.md  // <- https://example.com/posts/happy/ness/
    |   └── secondpost.md  // <- https://example.com/posts/secondpost/
    └── quote
        ├── first.md       // <- https://example.com/quote/first/
        └── second.md      // <- https://example.com/quote/second/

在 Hugo 中的路径分解

​ 以下示例演示了在 Hugo 渲染站点时,您的内容组织和输出 URL 结构之间的关系。这些示例假定您使用美化的 URL,这是 Hugo 的默认行为。这些示例假设您正在使用美化的 URL,这是 Hugo 的默认行为。这些示例还假设在您站点的配置文件中设置了 baseURL = "https://example.com"

索引页: _index.md

_index.md 在 Hugo 中有特殊的作用。它允许您在列表模板中添加 前置元数据和内容。这些模板包括section templatestaxonomy templatestaxonomy terms templateshomepage template

提示:您可以使用 .Site.GetPage 函数引用 _index.md 中的内容和元数据。

​ 您可以为主页和每个内容章节(content sections)、分类法(taxonomies)和分类法条目(taxonomy terms)中创建一个 _index.md。以下示例显示了在Hugo站点上包含用于posts章节列表页的内容和前置元数据的_index.md的典型放置方式:

1
2
3
4
5
6
7
.         url
.       ⊢--^-⊣
.        path    slug
.       ⊢--^-⊣⊢---^---⊣
.           filepath
.       ⊢------^------⊣
content/posts/_index.md

At build, this will output to the following destination with the associated values:(with该怎么翻译)

​ 在构建时,这将输出到以下目标并具有相关的值:

1
2
3
4
5
6
7
                     url ("/posts/")
                    ⊢-^-⊣
       baseurl      section ("posts")
⊢--------^---------⊣⊢-^-⊣
        permalink(永久链接)
⊢----------^-------------⊣
https://example.com/posts/index.html

sections可以嵌套得很深。要完全导航section树,最下面的section至少必须包含一个内容文件(即_index.md) 。

Single Pages in Sections

​ 在每个章节中的单个内容文件将渲染为单个页面模板。这是一个在 posts 中的单个post的例子:

1
2
3
4
5
                   path ("posts/my-first-hugo-post.md")
.       ⊢-----------^------------⊣
.      section        slug
.       ⊢-^-⊣⊢--------^----------⊣
content/posts/my-first-hugo-post.md

​ 当Hugo构建您的站点时,内容将输出到以下目标:

1
2
3
4
5
6
7
                               url ("/posts/my-first-hugo-post/")
                   ⊢------------^----------⊣
       baseurl     section     slug
⊢--------^--------⊣⊢-^--⊣⊢-------^---------⊣
                 permalink
⊢--------------------^---------------------⊣
https://example.com/posts/my-first-hugo-post/index.html

路径解释

​ 以下概念更深入地解释了项目组织与构建站点输出的默认Hugo行为之间的关系。

section

​ 默认内容类型由存储内容项的section确定。section是根据项目的content目录中的位置确定的。section无法在前置元数据中指定或覆盖。

slug

slug是URL路径的最后一段,由文件名定义,并在前置元数据中可选地被slug值覆盖。有关详细信息,请参阅URL管理

path

​ 内容的path由section到文件的路径确定。文件path

  • 是基于内容位置的路径,且
  • 不包括 slug (=>这里应该描述有问题,更据上面Single Pages in Sections 的图,这样不是矛盾了吗)

url

url是整个URL路径,由文件路径定义,并在前置元数据中可选地被url值覆盖。有关详细信息,请参阅URL管理

另请参阅

5.2 - 页面Bundle

Page Bundles - 页面Bundle

https://gohugo.io/content-management/page-bundles/

​ 使用页面 Bundle 进行内容组织

​ 页面 Bundle 是一种分组页面资源的方式。

​ 页面 Bundle 可以是以下之一:

  • 叶子Bundle (叶子表示它没有子级)
  • 分支Bundle (home page,section,taxonomy terms,taxonomy list)
叶子 Bundle分支 Bundle
用法单个页面内容和附件的集合用于section页面(home page,section,taxonomy terms,taxonomy list)的附件集合
索引文件名index.md 1_index.md 1
允许的资源页面和非页面类型(如图像、PDF 等)仅允许非页面类型(如图像、PDF 等)
资源可以存放在哪里?在叶子 Bundle 目录中的任何目录级别。仅在分支 Bundle 目录的目录级别中,即包含 _index.md 的目录(参考)。
布局类型singlelist
嵌套不允许在其下方嵌套更多的 Bundle允许在其下方嵌套叶子或分支 Bundle
示例content/posts/my-post/index.mdcontent/posts/_index.md
非索引页面文件中的内容…仅作为页面资源访问仅作为常规页面访问

叶子Bundles

​ 叶子 Bundle 是 content/ 目录中任何层次结构中包含 index.md 文件的目录。

叶子 Bundle 组织示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
content/
├── about
│   ├── index.md
├── posts
│   ├── my-post
│   │   ├── content1.md
│   │   ├── content2.md
│   │   ├── image1.jpg
│   │   ├── image2.png
│   │   └── index.md
│   └── my-other-post
│       └── index.md
└── another-section
    ├── ..
    └── not-a-leaf-bundle
        ├── ..
        └── another-leaf-bundle
            └── index.md

In the above example content/ directory, there are four leaf bundles:

​ 在上面的示例中,content/ 目录中有四个叶子 Bundle:

  • about

    这个叶子 Bundle 在根级别(直接在 content 目录下)并且只有 index.md

  • my-post

    这个叶子 Bundle 有 index.md、另外两个内容 Markdown 文件和两个图像文件。

    image1, image2:这些图像是 my-post 的页面资源,仅在 my-post/index.md 资源中可用。

    content1, content2: These content files are page resources of my-post and only available in my-post/index.md resources. They will not be rendered as individual pages. 这些内容文件是 my-post 的页面资源,仅在 my-post/index.md 资源中可用。它们不会被渲染为单独的页面。

  • my-other-post

    这个叶子 Bundle 只有 index.md

  • another-leaf-bundle

    这个叶子 Bundle 被嵌套在几个目录下。此 Bundle 也只有 index.md

​ 创建叶子 Bundle 的层次深度不重要,只要它不在另一个叶子 Bundle 中即可。

Headless Bundle

​ 无头Bundle是一种配置为不在任何地方发布的Bundle:

  • 它将没有永久链接(Permalink)和public/中的渲染HTML。
  • 它不会成为.Site.RegularPages等的一部分。

​ 但是,您可以通过.Site.GetPage获取它。以下是一个示例:

1
2
3
4
5
6
7
{{ $headless := .Site.GetPage "/some-headless-bundle" }}
{{ $reusablePages := $headless.Resources.Match "author*" }}
<h2>Authors</h2>
{{ range $reusablePages }}
    <h3>{{ .Title }}</h3>
    {{ .Content }}
{{ end }}

​ 在此示例中,我们假设some-headless-bundle是一个包含一个或多个页面资源的无头Bundle,其.Name"author*"匹配。

​ 上面示例的说明:

  1. 获取some-headless-bundle页面"object"。
  2. 使用.Resources.Match收集此页面Bundle中与"author*"匹配的资源片段。
  3. 循环遍历嵌套页面的切片,并输出它们的.Title.Content

​ 通过在index.md的前置元数据中添加以下内容,可以将一个叶子Bundle变为无头Bundle:

content/headless/index.md

=== “yaml”

```yaml
---
headless: true
---
```

=== “toml”

```toml
+++
headless = true
+++
```

=== “json”

```json
{
   "headless": true
}
```

​ 此类无头页面Bundle有许多用例:

  • 共享媒体库
  • 可重复使用的页面内容"snippets(片段)"

分支Bundle

​ 分支Bundle是位于content/目录中任何层次结构中的任何目录,其中至少包含一个_index.md文件。

​ 这个_index.md也可以直接在content/目录下。

​ 这里以md(markdown)仅作为示例。只要它是Hugo可识别的内容类型,您可以使用任何文件类型作为内容资源。

分支Bundle组织示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
content/
├── branch-bundle-1
│   ├── branch-content1.md
│   ├── branch-content2.md
│   ├── image1.jpg
│   ├── image2.png
│   └── _index.md
└── branch-bundle-2
    ├── _index.md
    └── a-leaf-bundle
        └── index.md

​ 在上面的content/目录示例中,有两个分支Bundle(和一个叶子Bundle):

  • branch-bundle-1

    该分支Bundle有_index.md,另外两个内容Markdown文件和两个图像文件。

  • branch-bundle-2

    该分支Bundle有_index.md和一个嵌套的叶子Bundle。

​ 创建分支Bundle的层次深度不重要。


  1. .md扩展名仅作为示例。扩展名可以是.html.json或任何有效的MIME类型。 ↩︎ ↩︎

另请参阅

5.3 - 内容格式

Content Formats - 内容格式

https://gohugo.io/content-management/formats/

​ Hugo支持HTML和Markdown这两种内容格式。

​ 您可以将任何文件类型放入您的 /content 目录下,但Hugo会使用 前置元数据 中的 markup 值(如果设置了)或文件扩展名(见下表中的 Markup identifiers)来确定是否需要处理标记语言,例如:

  • Markdown 转换为 HTML
  • 处理 Shortcodes
  • 应用布局

内容格式列表

​ Hugo当前支持的内容格式如下:

NameMarkup identifiers备注
Goldmarkmd, markdown, goldmark注意您可以将 mdmarkdown 的默认处理器设置为其他内容,请参见配置标记
Emacs Org-Modeorg参见 go-org.
AsciiDocasciidocext, adoc, ad需要安装 Asciidoctor
RSTrst需要安装 RST
Pandocpandoc, pdc需要安装 Pandoc
HTMLhtml, htm要将其视为内容文件(包括布局、shortcodes等),它必须有前置元数据。否则,它将被原样复制。

markup identifier可以从前置元数据中的markup变量或文件扩展名中获取。有关标记语言相关的配置,请参见配置标记

外部助手

​ 上表中的某些格式需要在您的计算机上安装外部助手。例如,对于 AsciiDoc 文件,Hugo 将尝试调用 asciidoctor 命令。这意味着您需要在您的计算机上安装相应的工具才能使用这些格式。

​ 默认情况下,Hugo会将合理的默认参数传递给这些外部助手:

  • asciidoctor: --no-header-footer -
  • rst2html: --leave-comments --initial-header-level=2
  • pandoc: --mathjax

​ 由于其他格式是外部命令,生成性能将严重依赖于您正在使用的外部工具的性能。由于此功能仍处于初期阶段,因此欢迎提供反馈。

AsciiDoc 外部助手

AsciiDoc实现于 2020 年 1 月结束生命周期并不再得到支持。AsciiDoc 的开发正在 Asciidoctor 下继续进行。当然,AsciiDoc 格式仍然存在。但请继续使用 Asciidoctor 实现。

Asciidoctor 外部助手

​ Asciidoctor 社区提供了一系列针对 AsciiDoc 格式的工具,可以额外安装到 Hugo 中。请参阅 Asciidoctor 文档以获取安装说明。如果需要,请确保还安装了所有可选扩展,例如 asciidoctor-diagramasciidoctor-html5s

​ 外部 asciidoctor 命令要求 Hugo 将渲染内容写入磁盘的特定目标目录。必须使用命令选项 --destination 运行 Hugo。

​ 一些 Asciidoctor参数可以在 Hugo 中自定义:

参数备注
backend除非您知道自己在做什么,否则不要更改此参数。
doctype目前,Hugo仅支持article类型的文档。
extensions可用的扩展包括 asciidoctor-html5s, asciidoctor-bibtex, asciidoctor-diagram, asciidoctor-interdoc-reftext, asciidoctor-katex, asciidoctor-latex, asciidoctor-mathematical, asciidoctor-question, asciidoctor-rouge.
attributes用于在AsciiDoc文件中引用的变量。这是一个变量名称/值映射列表。参见Asciidoctor的属性
noHeaderOrFooter输出一个可嵌入的文档,不包括标题、页脚和文档正文之外的内容。除非您知道自己在做什么,否则不要更改此参数。
safeMode安全模式级别unsafesafeserversecure。除非您知道自己在做什么,否则不要更改此参数。
sectionNumbers自动为章节标题编号。
verbose详细打印处理信息和配置文件检查到stderr。
trace在错误信息中包含回溯信息。
failureLevel触发非零退出码(失败)的最小日志记录级别。

​ Hugo提供了一些额外的设置,这些设置不能直接映射到Asciidoctor的CLI选项中:

  • workingFolderCurrent

    将工作目录设置为正在处理的AsciiDoc文件的目录,以便include可以使用相对路径。此设置使用asciidoctor cli参数--base-dir和attribute outdir=. 若要使用asciidoctor-diagram渲染图表,必须将workingFolderCurrent设置为true

  • preserveTOC

    默认情况下,Hugo会删除Asciidoctor生成的目录,并通过内置变量.TableOfContents提供它,以便进行进一步的自定义并更好地与各种Hugo主题集成。可以将此选项设置为true以保留Asciidoctor的目录。

​ 以下是所有与AsciiDoc相关的设置及其默认值:

config.

=== “yaml”

``` yaml
markup:
  asciidocExt:
    attributes: {}
    backend: html5
    extensions: []
    failureLevel: fatal
    noHeaderOrFooter: true
    preserveTOC: false
    safeMode: unsafe
    sectionNumbers: false
    trace: false
    verbose: false
    workingFolderCurrent: false
```

=== “toml”

``` toml
[markup]
  [markup.asciidocExt]
    backend = 'html5'
    extensions = []
    failureLevel = 'fatal'
    noHeaderOrFooter = true
    preserveTOC = false
    safeMode = 'unsafe'
    sectionNumbers = false
    trace = false
    verbose = false
    workingFolderCurrent = false
    [markup.asciidocExt.attributes]
```

=== “json”

``` json
{
   "markup": {
      "asciidocExt": {
         "attributes": {},
         "backend": "html5",
         "extensions": [],
         "failureLevel": "fatal",
         "noHeaderOrFooter": true,
         "preserveTOC": false,
         "safeMode": "unsafe",
         "sectionNumbers": false,
         "trace": false,
         "verbose": false,
         "workingFolderCurrent": false
      }
   }
}
```

​ 请注意,出于安全考虑,只允许没有路径分隔符(\/.)的扩展名。这意味着只有在Ruby的$LOAD_PATH中(即,扩展名很可能是由用户安装的),扩展名才能被调用。任何相对于站点路径声明的扩展名都将不被接受。

Example of how to set extensions and attributes:

​ 设置扩展名和属性的示例:

1
2
3
4
5
6
[markup.asciidocExt]
    extensions = ["asciidoctor-html5s", "asciidoctor-diagram"]
    workingFolderCurrent = true
    [markup.asciidocExt.attributes]
        my-base-url = "https://example.com/"
        my-attribute-name = "my value"

​ 在复杂的 Asciidoctor 环境中,有时候调试带有所有参数的外部助手的确切调用是很有帮助的。使用 -v 选项运行 Hugo。您将得到如下输出:

1
INFO 2019/12/22 09:08:48 Rendering book-as-pdf.adoc with C:\Ruby26-x64\bin\asciidoctor.bat using asciidoc args [--no-header-footer -r asciidoctor-html5s -b html5s -r asciidoctor-diagram --base-dir D:\prototypes\hugo_asciidoc_ddd\docs -a outdir=D:\prototypes\hugo_asciidoc_ddd\build -] ...

学习Markdown

​ Markdown 语法简单易学,只需花费一个短暂的时间就能掌握。以下资源是很好的起步指南:

另请参阅

5.4 - 图表

Diagrams

Use fenced code blocks and markdown render hooks to display diagrams.

New in v0.93.0

GoAT Diagrams (Ascii)

Hugo supports GoAT natively. This means that this code block:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
```goat
      .               .                .               .--- 1          .-- 1     / 1
     / \              |                |           .---+            .-+         +
    /   \         .---+---.         .--+--.        |   '--- 2      |   '-- 2   / \ 2
   +     +        |       |        |       |    ---+            ---+          +
  / \   / \     .-+-.   .-+-.     .+.     .+.      |   .--- 3      |   .-- 3   \ / 3
 /   \ /   \    |   |   |   |    |   |   |   |     '---+            '-+         +
 1   2 3   4    1   2   3   4    1   2   3   4         '--- 4          '-- 4     \ 4

```

Will be rendered as:

image-20230418212959281

Mermaid Diagrams

Hugo currently does not provide default templates for Mermaid diagrams. But you can easily add your own. One way to do it would be to create layouts/_default/_markup/render-codeblock-mermaid.html:

1
2
3
4
<div class="mermaid">
  {{- .Inner | safeHTML }}
</div>
{{ .Page.Store.Set "hasMermaid" true }}

And then include this snippet at the bottom of the content template (Note: below .Content as the render hook is not processed until .Content is executed):

1
2
3
4
5
6
{{ if .Page.Store.Get "hasMermaid" }}
  <script type="module">
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
    mermaid.initialize({ startOnLoad: true });
  </script>
{{ end }}

With that you can use the mermaid language in Markdown code blocks:

```mermaid
sequenceDiagram
    participant Alice
    participant Bob
    Alice->>John: Hello John, how are you?
    loop Healthcheck
        John->>John: Fight against hypochondria
    end
    Note right of John: Rational thoughts <br/>prevail!
    John-->>Alice: Great!
    John->>Bob: How about you?
    Bob-->>John: Jolly good!
```

Goat Ascii Diagram Examples

Graphics

image-20230418213039435

Complex

image-20230418213057019

Process

image-20230418213112054

File tree

Created from https://arthursonzogni.com/Diagon/#Tree

image-20230418213127200

Sequence Diagram

https://arthursonzogni.com/Diagon/#Sequence

image-20230418213140087

Flowchart

https://arthursonzogni.com/Diagon/#Flowchart

image-20230418213154601

Table

https://arthursonzogni.com/Diagon/#Table

image-20230418213220528

5.5 - 前置元数据

Front matter - 前置元数据

https://gohugo.io/content-management/front-matter/

​ Hugo 允许您在您的内容文件中添加 YAML、TOML 或 JSON 格式的前置元数据。

​ 前置元数据允许您将元数据附加到内容类型实例中,即嵌入在内容文件内部,这是 Hugo 赋予其强大功能的众多特点之一。

前置元数据格式

​ Hugo 支持四种前置元数据格式,每种格式都有其自己的标识符。

  • TOML

    由打开和关闭 +++ 标识。

  • YAML

    由打开和关闭 --- 标识。

  • JSON

    由 ‘{’ 和 ‘}’ 包围的单个 JSON 对象,后跟一个换行符

  • ORG

    ​ 由一组以’#+KEY: VALUE‘格式呈现的Org模式关键字组成。任何不以#+开头的行都会结束前置元数据部分。关键字值可以是字符串(#+KEY: VALUE)或空格分隔的字符串列表(#+KEY[]: VALUE_1 VALUE_2)。

示例

=== “yaml”

``` yaml
categories:
- Development
- VIM
date: "2012-04-06"
description: spf13-vim is a cross platform distribution of vim plugins and resources
  for Vim.
slug: spf13-vim-3-0-release-and-new-website
tags:
- .vimrc
- plugins
- spf13-vim
- vim
title: spf13-vim 3.0 release and new website
```

=== “toml”

``` toml
categories = ['Development', 'VIM']
date = '2012-04-06'
description = 'spf13-vim is a cross platform distribution of vim plugins and resources for Vim.'
slug = 'spf13-vim-3-0-release-and-new-website'
tags = ['.vimrc', 'plugins', 'spf13-vim', 'vim']
title = 'spf13-vim 3.0 release and new website'
```

=== “json”

``` json
{
   "categories": [
      "Development",
      "VIM"
   ],
   "date": "2012-04-06",
   "description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim.",
   "slug": "spf13-vim-3-0-release-and-new-website",
   "tags": [
      ".vimrc",
      "plugins",
      "spf13-vim",
      "vim"
   ],
   "title": "spf13-vim 3.0 release and new website"
}
```

前置元数据变量

预定义

​ 有一些预定义变量是 Hugo 能够识别的。请参阅页面变量以了解如何在模板中调用这些预定义变量。

  • aliases

    一个由一个或多个别名(例如,已更名的内容的旧发布路径)组成的数组,这些别名将在输出目录结构中创建。详见别名

  • audio

    一个路径数组,用于与页面相关的音频文件;用于填充 og:audioopengraph 内部模板

  • cascade

    一个前置元数据键值对映射,其值会传递给页面的子代,除非被自身或更近的祖先级别的 cascade 覆盖。详见前置元数据级联

  • date

    分配给此页面的日期时间。通常从前置元数据中的date字段获取,但此行为是可配置的。

  • description

    内容的描述。

  • draft

    如果为 true,则不会渲染该内容,除非在 hugo 命令中传递 --buildDrafts-D标志。

  • expiryDate

    内容应不再由 Hugo 发布的日期时间;除非在 hugo 命令中传递 --buildExpired-E标志,否则不会渲染已过期的内容。

  • headless

    如果为 true,则将叶子bundle设置为headless

  • images

    一个路径数组,用于与该页面相关的图像;用于内部模板,例如 _internal/twitter_cards.html

  • isCJKLanguage

    如果为 true,则 Hugo 将明确地将内容视为 CJK 语言;.Summary.WordCount 在 CJK 语言中均能正常工作。

  • keywords

    该内容的元关键字。

  • layout

    在渲染内容时 Hugo 应从查找顺序中选择的布局。如果在前置元数据中未指定type,则 Hugo 将在与内容所属章节对应的布局目录中查找同名的布局。请参阅内容类型

  • lastmod

    该内容上次修改的日期时间。

  • linkTitle

    用于创建链接到内容;如果设置,则 Hugo 默认使用title之前的linktitle。Hugo 还可以按照linktitle内容列表进行排序

  • markup

    实验性功能;指定"rst"表示使用reStructuredText(需要rst2html)或"md"(默认)表示使用Markdown。

  • outputs

    允许您指定特定于该内容的输出格式。请参见输出格式

  • publishDate

    如果在将来,则不会呈现内容,除非传递--buildFuture-F标志给hugo命令。

  • resources

    用于配置页面捆绑资源。请参见页面资源

  • series

    该页面属于的系列数组,作为series分类法的子集;被内部模板opengraph用于填充og:see_also

  • slug

    覆盖URL路径的最后一段。不适用于章节页面。有关详细信息,请参见URL管理

  • summary

    .Summary页面变量中提供文章摘要时使用的文本;有关详细信息,请参见内容摘要部分。

  • title

    该内容的标题。

  • type

    该内容的类型;如果在前置元数据中未指定,则该值将自动从目录(即章节)派生。

  • url

    覆盖整个URL路径。适用于常规页面和章节页面。有关详细信息,请参见URL管理

  • videos

    页面相关视频路径的数组;被内部模板opengraph用于填充og:video

  • weight

    用于在列表中排序内容较低的权重具有更高的优先级。因此,具有较低权重的内容将首先出现。如果设置了权重,则权重应为非零,因为0会被解释为未设置权重。

  • <taxonomies>

    索引的复数形式的字段名称。请参见上面的前置元数据示例中的tagscategories。请注意,用户定义的分类法(taxonomies)的复数形式不能与任何预定义的前置元数据变量相同。

​ 如果 slugurl 都不存在,并且在您的站点配置文件中未配置永久链接,Hugo 将使用您的内容文件名来创建输出 URL。请参见 Hugo 中的内容组织以了解 Hugo 中路径的说明,以及 URL 管理以了解自定义 Hugo 的默认行为的方式。

用户自定义

​ 您可以任意添加字段到您的前置元数据中以满足您的需求。这些用户自定义的键值被放入一个.Params变量中,以供在您的模板中使用。

​ 以下字段可以通过.Params.include_toc.Params.show_comments进行访问。变量章节提供有关在模板中使用Hugo的页面级别和站点级别变量的更多信息。

=== “yaml”

``` yaml
include_toc: true
show_comments: false
```

=== “toml”

``` toml
include_toc = true
show_comments = false
```

=== “json”

``` json
{
   "include_toc": true,
   "show_comments": false
}
```

前置元数据级联

​ 只要在保留的cascade前置元数据键下定义,任何节点或章节都可以向后代传递一组前置元数据值。

目标特定页面

The cascade block can be a slice with a optional _target keyword, allowing for multiple cascade values targeting different page sets.

cascade块可以是一个切片,其中包含一个可选的_target关键字,允许多个cascade值针对不同的页面集。

=== “yaml”

``` yaml
cascade:
- _target:
    kind: page
    lang: en
    path: /blog/**
  background: yosemite.jpg
- _target:
    kind: section
  background: goldenbridge.jpg
title: Blog
```

=== “toml”

``` toml
title = 'Blog'
[[cascade]]
background = 'yosemite.jpg'
[cascade._target]
  kind = 'page'
  lang = 'en'
  path = '/blog/**'
[[cascade]]
background = 'goldenbridge.jpg'
[cascade._target]
  kind = 'section'
```

=== “json”

``` json
{
   "cascade": [
      {
         "_target": {
            "kind": "page",
            "lang": "en",
            "path": "/blog/**"
         },
         "background": "yosemite.jpg"
      },
      {
         "_target": {
            "kind": "section"
         },
         "background": "goldenbridge.jpg"
      }
   ],
   "title": "Blog"
}
```

​ 可用于_target的关键字:

  • path

    匹配/content下的内容路径的通配符模式。期望是Unix风格的斜杠。注意,这是虚拟路径,因此它从挂载根开始。匹配支持双星号,因此您可以匹配模式如/blog/*/**,以匹配从第三层及以下的任何内容。

  • kind

    匹配该页面种类的通配符模式,例如"{home, section}"。

  • lang

    匹配该页面语言的通配符模式,例如"{en, sv}"。

  • environment

    匹配构建环境的通配符模式,例如"{production, development}"

​ 以上任何一个都可以省略。

示例

content/blog/_index.md

=== “yaml”

``` yaml
cascade:
  banner: images/typewriter.jpg
title: Blog
```

=== “toml”

``` toml
title = 'Blog'
[cascade]
  banner = 'images/typewriter.jpg'
```

=== “json”

``` json
{
   "cascade": {
      "banner": "images/typewriter.jpg"
   },
   "title": "Blog"
}
```

在上面的示例中,除非:

  • 该子页面已经设置了自己的banner
  • 或更近的祖先节点已经设置了自己的cascade.banner

否则博客章节页面和其后代页面将在调用.Params.banner时将返回images/typewriter.jpg

通过前置元数据对内容进行排序

​ 您可以在内容的前置元数据中分配特定于内容的weight。这些值对于列表视图中的排序非常有用。您可以使用weight对内容进行排序,使用_weight的约定对分类法(taxonomy)内的内容进行排序。请参阅对有序列表进行排序和分组,以了解如何使用weight在列表视图中组织您的内容。

覆盖全局 Markdown 配置

​ 可以在内容的前置元数据中设置某些Markdown渲染选项,作为对项目配置中设置的Rendering选项的覆盖。

前置元数据格式规范

另请参阅

5.6 - 构建选项

Build Options - 构建选项

https://gohugo.io/content-management/build-options/

​ 构建选项有助于定义 Hugo 在构建站点时如何处理给定页面。

​ 它们存储在名为 _build 的保留前置元数据对象中,具有以下默认值:

=== “yaml”

``` yaml
_build:
  list: always
  publishResources: true
  render: always
```

=== “toml”

``` toml
[_build]
  list = 'always'
  publishResources = true
  render = 'always'
```

=== “json”

``` json
{
   "_build": {
      "list": "always",
      "publishResources": true,
      "render": "always"
   }
}
```

render

​ 如果设置为 always,该页面将被视为已发布页面,并保留其专用输出文件(index.html 等)和永久链接。

​ 我们从布尔值将此属性扩展为枚举,从 Hugo 0.76.0 开始,有效值包括:

  • never

    该页面不会包含在任何页面集合中。

  • always (default)

    该页面将被渲染到磁盘并获得 RelPermalink 等。

  • link

    该页面不会被渲染到磁盘,但会获得 RelPermalink

list

​ 请注意,我们从布尔值将此属性扩展为枚举,从 Hugo 0.68.0 开始,有效值包括:

  • never

    该页面不会包含在任何页面集合中。

  • always (default)

    该页面将包含在所有页面集合中,例如 site.RegularPages$page.Pages

  • local

    该页面将包含在任何本地页面集合中,例如 $page.RegularPages$page.Pages。其一个用例是创建完全可导航但无头内容章节。

​ 如果为 true,则该页面将被视为项目集合的一部分,并在适当时通过 Hugo 的列表方法(.Pages.RegularPages 等)返回。

publishResources

​ 如果设置为 true,则 Bundle 的资源将被发布。将其设置为 false 将仍会按需发布资源(当从模板调用资源的 .Permalink.RelPermalink 时),但会跳过其他资源。

​ 无论其构建选项如何,任何页面都始终可以使用 .GetPage 方法访问。

说明性用例

不发布某个页面

​ 项目需要一个"Who We Are"内容文件,其中包括前置元数据和正文,用于主页但不用于其他任何地方。

content/who-we-are.md

=== “yaml”

``` yaml
---
_build:
  list: false
  render: false
title: Who we are
---
```

=== “toml”

``` toml
+++
title = 'Who we are'
[_build]
  list = false
  render = false
+++
```

=== “json”

``` json
{
   "_build": {
      "list": false,
      "render": false
   },
   "title": "Who we are"
}
```

layouts/index.html

1
2
3
4
5
<section id="who-we-are">
  {{ with site.GetPage "who-we-are" }}
    {{ .Content }}
  {{ end }}
</section>

列出未发布的页面

​ 站点需要展示一些可用的百余个"推荐(testimonials)“内容文件,而不发布其中任何一个。

​ 为了避免在每个推荐中设置构建选项,可以在推荐章节的内容文件上使用cascade

=== “yaml”

``` yaml
_build:
  render: true
cascade:
  _build:
    list: true
    render: false
title: Testimonials
```

=== “toml”

``` toml
title = 'Testimonials'
[_build]
  render = true
[cascade]
  [cascade._build]
    list = true
    render = false
```

=== “json”

``` json
{
   "_build": {
      "render": true
   },
   "cascade": {
      "_build": {
         "list": true,
         "render": false
      }
   },
   "title": "Testimonials"
}
```

layouts/_defaults/testimonials.html

1
2
3
4
5
6
7
<section id="testimonials">
  {{ range first 5 .Pages }}
    <blockquote cite="{{ .Params.cite }}">
      {{ .Content }}
    </blockquote>
  {{ end }}
</section>

另请参阅

5.7 - ContentTypes

Content Types - 内容类型

https://gohugo.io/content-management/types/

Hugo is built around content organized in sections.

​ Hugo 建立在按章节组织内容的基础上。

​ 内容类型是组织内容的一种方式。Hugo 会根据正文中的类型或者文件路径中的第一个目录(如果没有设置类型)来确定内容类型。例如,如果没有设置类型,则 content/blog/my-first-event.md 将被认为是类型为blog的内容。

​ 内容类型用于:

另请参阅

5.8 - 页面资源

Page Resources - 页面资源

https://gohugo.io/content-management/page-resources/

​ 页面资源(如图片、其他页面、文档等)具有相对于页面的 URL 和它们自己的元数据。

​ 页面资源只能从page bundles中访问,这些目录在其根目录中具有index.md或_index.md文件。页面资源仅可用于与其捆绑的页面。

​ 在此示例中,first-post是具有10个页面资源(包括音频,数据,文档,图像和视频)访问权限的page bundle。尽管second-post也是一个page bundle,但它没有页面资源,并且无法直接访问与first-post关联的页面资源。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
content
└── post
    ├── first-post
    │   ├── images
    │   │   ├── a.jpg
    │   │   ├── b.jpg
    │   │   └── c.jpg
    │   ├── index.md (root of page bundle)
    │   ├── latest.html
    │   ├── manual.json
    │   ├── notice.md
    │   ├── office.mp3
    │   ├── pocket.mp4
    │   ├── rating.pdf
    │   └── safety.txt
    └── second-post
        └── index.md (root of page bundle)

属性

  • ResourceType

    ​ 该资源媒体类型的主类型。例如,MIME类型为image/jpeg的文件的ResourceTypeimage。页面的ResourceType值为page

  • Name

    默认值为文件名(相对于所属页面)。可以在前置元数据中设置。

  • Title

    默认值与 .Name 相同。可以在前置元数据中设置。

  • Permalink

    该资源的绝对URL。类型为page的资源将没有值。

  • RelPermalink

    该资源的相对URL。类型为page的资源将没有值。

  • Content

    该资源本身的内容。对于大多数资源,这将返回一个字符串,其中包含文件的内容。使用它来创建内联资源。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{{ with .Resources.GetMatch "script.js" }}
  <script>{{ .Content | safeJS }}</script>
{{ end }}

{{ with .Resources.GetMatch "style.css" }}
  <style>{{ .Content | safeCSS }}</style>
{{ end }}

{{ with .Resources.GetMatch "img.png" }}
  <img src="data:{{ .MediaType }};base64,{{ .Content | base64Encode }}">
{{ end }}
  • MediaType

    该资源的MIME类型,例如image/jpeg

  • MediaType.MainType

    该资源MIME类型的主类型。例如,MIME类型为application/pdf的文件的主类型为application

  • MediaType.SubType

    该资源MIME类型的子类型。例如,MIME类型为application/pdf的文件的子类型为pdf。请注意,这与文件扩展名不同 —— PowerPoint文件的子类型为vnd.mspowerpoint

  • MediaType.Suffixes

    该资源MIME类型的可能后缀切片。

方法

  • ByType

    返回给定类型的页面资源。

1
{{ .Resources.ByType "image" }}
  • Match

    返回所有Name与给定通配符模式(examples)匹配的页面资源(作为切片)。匹配不区分大小写。

1
{{ .Resources.Match "images/*" }}
  • GetMatch

    Match相同,但将返回第一个匹配项。

模式匹配

1
2
3
4
5
6
7
8
// 使用 Match/GetMatch 来寻找这个 images/sunset.jpg ?
.Resources.Match "images/sun*".Resources.Match "**/sunset.jpg".Resources.Match "images/*.jpg".Resources.Match "**.jpg".Resources.Match "*" 🚫
.Resources.Match "sunset.jpg" 🚫
.Resources.Match "*sunset.jpg" 🚫

页面资源元数据

​ 页面资源的元数据由相应页面的前置元数据中的resources数组/表(array/table)参数进行管理。您可以使用通配符进行批量分配值。

​ 类型为page的资源从其自己的前置元数据中获取Title等。

  • name

    设置Name中返回的值

MatchGetGetMatch方法使用Name来匹配资源。

  • title

    设置Title中返回的值。

  • params

    一个自定义键/值的映射。

资源元数据示例

=== “yaml”

``` yaml
date: "2018-01-25"
resources:
- name: header
  src: images/sunset.jpg
- params:
    icon: photo
  src: documents/photo_specs.pdf
  title: Photo Specifications
- src: documents/guide.pdf
  title: Instruction Guide
- src: documents/checklist.pdf
  title: Document Checklist
- src: documents/payment.docx
  title: Proof of Payment
- name: pdf-file-:counter
  params:
    icon: pdf
  src: '**.pdf'
- params:
    icon: word
  src: '**.docx'
title: Application
```

=== “toml”

``` toml
date = '2018-01-25'
title = 'Application'
[[resources]]
name = 'header'
src = 'images/sunset.jpg'
[[resources]]
src = 'documents/photo_specs.pdf'
title = 'Photo Specifications'
[resources.params]
  icon = 'photo'
[[resources]]
src = 'documents/guide.pdf'
title = 'Instruction Guide'
[[resources]]
src = 'documents/checklist.pdf'
title = 'Document Checklist'
[[resources]]
src = 'documents/payment.docx'
title = 'Proof of Payment'
[[resources]]
name = 'pdf-file-:counter'
src = '**.pdf'
[resources.params]
  icon = 'pdf'
[[resources]]
src = '**.docx'
[resources.params]
  icon = 'word'
```

=== “json”

``` json
{
   "date": "2018-01-25",
   "resources": [
      {
         "name": "header",
         "src": "images/sunset.jpg"
      },
      {
         "params": {
            "icon": "photo"
         },
         "src": "documents/photo_specs.pdf",
         "title": "Photo Specifications"
      },
      {
         "src": "documents/guide.pdf",
         "title": "Instruction Guide"
      },
      {
         "src": "documents/checklist.pdf",
         "title": "Document Checklist"
      },
      {
         "src": "documents/payment.docx",
         "title": "Proof of Payment"
      },
      {
         "name": "pdf-file-:counter",
         "params": {
            "icon": "pdf"
         },
         "src": "**.pdf"
      },
      {
         "params": {
            "icon": "word"
         },
         "src": "**.docx"
      }
   ],
   "title": "Application"
}
```

从上面的示例中:

  • sunset.jpg将获得一个新的Name,并且现在可以使用.GetMatch "header"找到它。
  • documents/photo_specs.pdf将获得photo图标。
  • documents/checklist.pdfdocuments/guide.pdfdocuments/payment.docx将得到Title,如Title中所设置。
  • 包中除documents/photo_specs.pdf外的每个PDF都将获得pdf图标。
  • 所有PDF文件都将获得新的Namename参数包含一个特殊占位符:counter,因此名称将是pdf-file-1pdf-file-2pdf-file-3
  • 包中的每个docx都将获得word图标。

​ 顺序很重要 —— 只有titlenameparams-keys的第一个设置值将被使用。连续的参数仅设置未设置的参数。在上面的示例中,.Params.icon首先在src = "documents/photo_specs.pdf"中设置为"photo"。因此,后来设置的src = "**.pdf"规则不会将其覆盖为"pdf"

nametitle 中的 :counter 占位符

:counter是在资源的nametitle参数中识别的特殊占位符。

​ 该计数器从第一次在nametitle中使用时开始计数。

​ 例如,如果一个包中有资源photo_specs.pdfother_specs.pdfguide.pdfchecklist.pdf,并且前置元数据已将resources指定为:

=== “yaml”

``` yaml
resources:
- src: '*specs.pdf'
  title: 'Specification #:counter'
- name: pdf-file-:counter
  src: '**.pdf'
```

=== “toml”

``` toml
[[resources]]
src = '*specs.pdf'
title = 'Specification #:counter'
[[resources]]
name = 'pdf-file-:counter'
src = '**.pdf'
```

=== “json”

``` json
{
   "resources": [
      {
         "src": "*specs.pdf",
         "title": "Specification #:counter"
      },
      {
         "name": "pdf-file-:counter",
         "src": "**.pdf"
      }
   ]
}
```

NameTitle将按如下分配给资源文件:

Resource fileNameTitle
checklist.pdf"pdf-file-1.pdf"checklist.pdf"
guide.pdf"pdf-file-2.pdf"guide.pdf"
other_specs.pdf"pdf-file-3.pdf"Specification #1"
photo_specs.pdf"pdf-file-4.pdf"Specification #2"

另请参阅

5.9 - 图像处理

Image Processing - 图像处理

https://gohugo.io/content-management/image-processing/

​ 调整大小、裁剪、旋转、滤镜和转换图像。

图像资源

​ 要处理图像,必须将其作为页面资源或全局资源访问。

页面资源

​ 页面资源是page bundle中的文件。page bundle是一个在其根目录下具有index.md_index.md文件的目录。

1
2
3
4
5
content/
└── posts/
    └── post-1/           <-- page bundle
        ├── index.md
        └── sunset.jpg    <-- page resource

全局资源

​ 全局资源是一个文件:

  • assets目录中,或
  • 在任何已挂载assets目录的目录中,或
  • 位于通过httphttps可访问的远程服务器上
1
2
3
assets/
└── images/
    └── sunset.jpg    <-- global resource

​ 要访问本地图像作为全局资源:

1
{{ $image := resources.Get "images/sunset.jpg" }}

​ 要将远程图像作为全局资源访问:

1
{{ $image := resources.GetRemote "https://gohugo.io/img/hugo-logo.png" }}

图像渲染

​ 一旦您已经将图像作为页面资源或全局资源之一访问,可以使用PermalinkRelPermalinkWidthHeight属性在模板中呈现它。

示例1:如果未找到资源,则会引发错误。

1
2
{{ $image := .Resources.GetMatch "sunset.jpg" }}
<img src="{{ $image.RelPermalink }}" width="{{ $image.Width }}" height="{{ $image.Height }}">

示例2:如果未找到资源,则跳过图像渲染。

1
2
3
4
{{ $image := .Resources.GetMatch "sunset.jpg" }}
{{ with $image }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
{{ end }}

示例3:如果未找到资源,则跳过图像渲染的更简洁的方法。

1
2
3
{{ with .Resources.GetMatch "sunset.jpg" }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
{{ end }}

图像处理方法

image资源实现了ResizeFitFillCropFilterColorsExif方法。

Metadata (Exif, IPTC, XMP, etc.) is not preserved during image transformation. Use the [Exif] method with the original image to extract Exif metadata from JPEG or TIFF images.

​ 在图像转换期间,元数据(Exif,IPTC,XMP等)不会被保留。请使用[Exif]方法和原始图像从JPEG或TIFF图像中提取Exif元数据。

Resize

​ 将图像调整为指定的宽度和/或高度。

​ 如果同时指定宽度和高度,则结果图像将不成比例缩放,除非原始图像具有相同的宽高比。

1
2
3
4
5
6
7
8
{{/* Resize to a width of 600px and preserve aspect ratio */}}
{{ $image := $image.Resize "600x" }}

{{/* Resize to a height of 400px and preserve aspect ratio */}}
{{ $image := $image.Resize "x400" }}

{{/* Resize to a width of 600px and a height of 400px */}}
{{ $image := $image.Resize "600x400" }}

Fit

​ 按比例缩小图像以适应给定的尺寸。您必须同时提供宽度和高度。

1
{{ $image := $image.Fit "600x400" }}

Fill

​ 裁剪并调整图像以匹配给定的尺寸。您必须同时提供宽度和高度。使用 anchor 选项可以更改裁剪框锚点。

1
{{ $image := $image.Fill "600x400" }}

Crop

​ 裁剪图像以匹配给定的尺寸而不调整大小。您必须同时提供宽度和高度。使用 anchor 选项可以更改裁剪框锚点。

1
{{ $image := $image.Crop "600x400" }}

Filter

​ 对图像应用一个或多个滤镜

1
{{ $image := $image.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}

​ 使用管道以更函数式的风格编写此内容。 Hugo按照给定的顺序应用过滤器。

1
{{ $image := $image | images.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}

​ 有时候创建一个过滤器链并重复使用它是很有用的。

1
2
3
{{ $filters := slice  (images.GaussianBlur 6) (images.Pixelate 8) }}
{{ $image1 := $image1.Filter $filters }}
{{ $image2 := $image2.Filter $filters }}

Colors

New in v0.104.0

.Colors 方法使用简单的直方图方法返回图像中的主要颜色的十六进制字符串切片。

1
{{ $colors := $image.Colors }}

​ 此方法速度很快,但如果您还缩小图像,从缩小的图像提取颜色可提高性能。

Exif

​ 提供一个包含图像元数据的 Exif 对象。

​ 您可以访问 JPEG 和 TIFF 图像中的 Exif 数据。为避免处理没有 Exif 数据的图像时出现错误,请将访问包装在 with 语句中。

1
2
3
4
5
6
7
8
{{ with $image.Exif }}
  Date: {{ .Date }}
  Lat/Long: {{ .Lat }}/{{ .Long }}
  Tags:
  {{ range $k, $v := .Tags }}
    TAG: {{ $k }}: {{ $v }}
  {{ end }}
{{ end }}

​ 您还可以使用lang.FormatNumber函数单独访问Exif字段,根据需要格式化字段。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ with $image.Exif }}
  <ul>
    {{ with .Date }}<li>Date: {{ .Format "January 02, 2006" }}</li>{{ end }}
    {{ with .Tags.ApertureValue }}<li>Aperture: {{ lang.FormatNumber 2 . }}</li>{{ end }}
    {{ with .Tags.BrightnessValue }}<li>Brightness: {{ lang.FormatNumber 2 . }}</li>{{ end }}
    {{ with .Tags.ExposureTime }}<li>Exposure Time: {{ . }}</li>{{ end }}
    {{ with .Tags.FNumber }}<li>F Number: {{ . }}</li>{{ end }}
    {{ with .Tags.FocalLength }}<li>Focal Length: {{ . }}</li>{{ end }}
    {{ with .Tags.ISOSpeedRatings }}<li>ISO Speed Ratings: {{ . }}</li>{{ end }}
    {{ with .Tags.LensModel }}<li>Lens Model: {{ . }}</li>{{ end }}
  </ul>
{{ end }}

Exif变量

  • .Date

    图像创建日期/时间。使用time.Format函数格式化。

  • .Lat

    GPS纬度(latitude 以度为单位)。

  • .Long

    GPS经度(longitude 以度为单位)。

  • .Tags

    此图像可用的Exif标签集合。您可以在站点配置中包含或排除特定标签。

图像处理选项

ResizeFitFillCrop方法接受一个以空格分隔、大小写不敏感的选项列表。列表中的选项顺序无关紧要。

尺寸

​ 使用Resize方法,必须指定宽度、高度或两者。FitFillCrop方法需要宽度和高度。所有尺寸以像素为单位。

1
2
3
4
5
6
{{ $image := $image.Resize "600x" }}
{{ $image := $image.Resize "x400" }}
{{ $image := $image.Resize "600x400" }}
{{ $image := $image.Fit "600x400" }}
{{ $image := $image.Fill "600x400" }}
{{ $image := $image.Crop "600x400" }}

旋转

​ 将图像逆时针旋转给定角度。 Hugo在缩放之前执行旋转。例如,如果原始图像为600x400,并且您希望将图像逆时针旋转90度,并将其缩小50%:

1
{{ $image = $image.Resize "200x r90" }}

​ 在上面的示例中,宽度表示旋转后的期望宽度。

​ 要在不缩放的情况下旋转图像,请使用原始图像的尺寸:

1
2
3
4
5
{{ with .Resources.GetMatch "sunset.jpg" }}
  {{ with .Resize (printf "%dx%d r90" .Height .Width) }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
  {{ end }}
{{ end }}

​ 在上面的示例中,第二行我们反转了宽度和高度,以反映旋转后期望尺寸。

锚点

​ 使用CropFill方法时,锚点确定裁剪框的放置位置。您可以指定TopLeftTopTopRightLeftCenterRightBottomLeftBottomBottomRightSmart

​ 默认值为Smart,它使用Smartcrop图像分析来确定裁剪框的最佳放置位置。您可以在站点配置中覆盖默认值。

​ 例如,如果您有一个400x200像素的图像,其中鸟位于左上象限,您可以创建一个包含鸟的200x100缩略图:

1
{{ $image.Crop "200x100 TopLeft" }}

​ 如果在使用CropFill方法时应用旋转,则相对于旋转后的图像指定锚点。

目标格式

​ 默认情况下,Hugo将图像编码为源格式。您可以通过指定bmpgifjpegjpgpngtiftiffwebp将图像转换为另一种格式。

1
{{ $image.Resize "600x webp" }}

​ 使用原始图像的尺寸而不缩放来转换图像:

1
2
3
4
5
{{ with .Resources.GetMatch "sunset.jpg" }}
  {{ with .Resize (printf "%dx%d webp" .Width .Height) }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
  {{ end }}
{{ end }}

质量

​ 适用于JPEG和WebP图像,q值确定转换图像的质量。更高的值会产生更好的质量图像,而更低的值会产生更小的文件。将此值设置为介于1和100之间(包括1和100)的整数。

​ 默认值为75。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x webp q50" }}

提示

​ 适用于WebP图像,此选项对应于一组预定义的编码参数。

ValueExample
drawing高对比度手绘或线描图像
icon小型彩色图像
photo自然光照的户外照片
picture室内照片,例如肖像
text主要是文本的图像

​ 默认值为photo。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x webp picture" }}

背景色

​ 当将支持透明度的图像(例如PNG)转换为不支持透明度的图像(例如JPEG)时,可以指定结果图像的背景颜色。

​ 使用3位或6位十六进制颜色代码(例如#00f#0000ff)。

​ 默认值为#ffffff(白色)。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x jpg #b31280" }}

重采样滤镜

You may specify the resampling filter used when resizing an image. Commonly used resampling filters include:

您可以在调整图像大小时指定使用的重采样滤镜。常用的重采样滤镜包括:

调整图像大小时,可以指定所使用的重采样滤镜。常用的重采样滤镜包括:

FilterDescription
Box适合缩小的简单快速平均滤镜
Lanczos用于摄影图像的高质量重采样滤镜,产生锐利的结果
CatmullRom尖锐的立方滤镜,比Lanczos滤镜快,提供类似的结果
MitchellNetravali立方体滤镜,产生比 CatmullRom 更平滑的结果,减少了环状伪影
Linear双线性重采样滤镜,产生平滑的输出,比立方体滤镜更快
NearestNeighbor最快的重采样滤镜,无抗锯齿

​ 默认值为 Box。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x400 Lanczos" }}

​ 请参见github.com/disintegration/imaging以获取完整的重采样滤镜列表。如果您希望以性能为代价改善图像质量,可以尝试使用替代滤镜。

图像处理示例

​ 以下示例中使用的日落照片版权归Bjørn Erik Pedersen所有(Creative Commons Attribution-Share Alike 4.0 International license)。

image-20230423173937490

​ 这是用于生成上述示例的shortcode :

layouts/shortcodes/imgproc.html

 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
{{ $img := .Page.Resources.GetMatch (printf "*%s*" (.Get 0)) }}
{{ $command := .Get 1 }}
{{ $options := .Get 2 }}
{{ if eq $command "Fit"}}
  {{ $img = $img.Fit $options }}
{{ else if eq $command "Resize"}}
  {{ $img = $img.Resize $options }}
{{ else if eq $command "Fill"}}
  {{ $img = $img.Fill $options }}
{{ else if eq $command "Crop"}}
  {{ $img = $img.Crop $options }}
{{ else }}
  {{ errorf "Invalid image processing command: Must be one of Crop, Fit, Fill or Resize."}}
{{ end }}
<figure style="padding: 0.25rem; margin: 2rem 0; background-color: #cccc">
  <img style="max-width: 100%; width: auto; height: auto;" src="{{ $img.RelPermalink }}" width="{{ $img.Width }}" height="{{ $img.Height }}">
  <figcaption>
  <small>
    {{ with .Inner }}
      {{ . }}
    {{ else }}
      .{{ $command }} "{{ $options }}"
    {{ end }}
  </small>
  </figcaption>
</figure>

​ 在您的Markdown中像这样调用shortcode :

1
\{\{\< imgproc sunset Resize "300x" /\>\}\}

​ 注意上面自我封闭的shortcode语法。您可以使用或不使用内部内容来调用imgproc shortcode 。

图像处理配置

处理选项

​ 在您的站点配置中定义一个imaging处理部分,以设置默认的图像处理选项

config.

=== “yaml”

``` yaml
imaging:
  anchor: Smart
  bgColor: '#ffffff'
  hint: photo
  quality: 75
  resampleFilter: Box
```

=== “toml”

``` toml
[imaging]
  anchor = 'Smart'
  bgColor = '#ffffff'
  hint = 'photo'
  quality = 75
  resampleFilter = 'Box'
```

=== “json”

``` json
{
   "imaging": {
      "anchor": "Smart",
      "bgColor": "#ffffff",
      "hint": "photo",
      "quality": 75,
      "resampleFilter": "Box"
   }
}
```

Exif 数据

在您的站点配置中定义一个 imaging.exif 部分,以控制 Exif 数据的可用性。

config.

=== “yaml”

``` yaml
imaging:
  exif:
    disableDate: false
    disableLatLong: false
    excludeFields: ""
    includeFields: ""
```

=== “toml”

``` toml
[imaging]
  [imaging.exif]
    disableDate = false
    disableLatLong = false
    excludeFields = ''
    includeFields = ''
```

=== “json”

``` json
{
   "imaging": {
      "exif": {
         "disableDate": false,
         "disableLatLong": false,
         "excludeFields": "",
         "includeFields": ""
      }
   }
}
```
  • disableDate

    Hugo 将图像创建日期/时间提取到 .Date 中。将此设置为 true 以禁用。默认值为 false

  • disableLatLong

    Hugo 将 GPS 纬度和经度提取到 .Lat.Long 中。将此设置为 true 以禁用。默认值为 false

  • excludeFields

    正则表达式匹配要从 .Tags 集合中排除的 Exif 标记。默认值为 ""

  • includeFields

    正则表达式匹配要在 .Tags 集合中包含的 Exif 标记。默认值为 ""。要包括所有可用的标记,请将此值设置为 ".*"

​ 为了提高性能并减小缓存大小,如果您既不设置 excludeFields 也不设置 includeFields,则 Hugo 将排除以下标记:ColorSpaceContrastExifExposure[M|P|B]FlashGPSJPEGMeteringResolutionSaturationSensingSharpWhiteBalance

智能裁剪图像

​ 默认情况下,Hugo在使用CropFill方法裁剪图像时会使用Smartcrop库。您可以手动设置锚点,但在大多数情况下,Smart选项会做出很好的选择。

​ 以下是使用上面的日落图片的示例:

image-20230423174039092

图像处理性能考虑

​ Hugo在resources目录中缓存处理过的图像。如果您将此目录包含在源代码控制中,Hugo将不必在CI / CD工作流程(例如,GitHub Pages,GitLab Pages,Netlify等)中重新生成图像。这将加快构建速度。

​ 如果您更改图像处理方法或选项,或者重命名或删除图像,则resources目录将包含未使用的图像。要删除未使用的图像,请执行垃圾回收:

1
hugo --gc

另请参阅

5.10 - 简码

Shortcodes - 简码

https://gohugo.io/content-management/shortcodes/

​ 简码是在您的内容文件中调用内置或自定义模板的简单代码片段。

什么是简码

​ Hugo喜欢Markdown,因为它的简单内容格式,但有时Markdown存在局限性。通常,内容作者被迫将原始HTML(例如视频<iframe>)添加到Markdown内容中。我们认为这与Markdown语法的美丽简洁相矛盾。

​ Hugo创建了简码来规避这些限制。

​ 简码是内容文件中的简单代码片段,Hugo将使用预定义的模板进行渲染。请注意,简码在模板文件中不起作用。如果您需要简码提供的此类插入(drop-in)功能,但在模板中,则很可能需要局部模板

​ 除了更干净的Markdown外,简码可以随时更新以反映新的类、技术或标准。在站点生成的时候,Hugo简码将轻松合并您的更改。您避免了可能复杂的搜索和替换操作。

使用简码

​ 在您的内容文件中,可以通过调用\{\{\% shortcodename parameters \%\}\}来调用简码。简码参数由空格分隔,具有内部空格的参数可以用引号引起来。

​ 简码声明中的第一个单词始终是简码的名称。参数跟在名称后面。根据简码的定义方式,参数可以是命名的、位置的或两者兼有,但不能在单个调用中混合使用参数类型。命名参数的格式与HTML的格式name="value"相似。

​ 一些简码使用或需要闭合简码。与HTML一样,开放和关闭简码匹配(仅名称),关闭声明前缀有一个斜杠。

​ 以下是成对的简码的两个示例:

1
2
\{\{\% mdshortcode \%\}\}Stuff to `process` in the *center*.\{\{\% /mdshortcode \%\}\}
\{\{\< highlight go \>\}\} A bunch of code here \{\{\< /highlight \>\}\}

​ 上面的例子使用两个不同的定界符,不同之处在于第一个中有%字符,第二个中有<>字符。

使用原始字符串参数的简码

​ 您可以使用原始字符串字面值将占据多行的参数传递给简码:

1
2
\{\{\<  myshortcode `This is some <b>HTML</b>,
and a new line with a "quoted string".` \>\}\}

具有 Markdown 的简码

​ 在Hugo 0.55中,我们改变了%定界符的工作方式。使用 % 作为最外层定界符的简码现在将在发送到内容渲染器时完全渲染。它们可以成为生成的目录(table of contents)、脚注(footnotes)等的一部分。

​ 如果您想要旧的行为,可以在简码模板的开头放置以下行:

1
\{\{ $_hugo_config := `{ "version": 1 }` \}\}

没有 Markdown 的简码

<字符表示简码的内部内容不需要进一步渲染。通常,不带Markdown的简码包括内部HTML:

1
\{\{\< myshortcode \>\}\}<p>Hello <strong>World!</strong></p>\{\{\< /myshortcode \>\}\}

嵌套的简码

​ 您可以通过创建自己的模板来利用.Parent变量在其他简码中调用简码。 .Parent允许您检查简码被调用的上下文。请参见简码模板

使用 Hugo 的内置简码

​ Hugo附带了一组预定义的简码,代表非常常见的用法。这些简码提供给作者方便,并使您的Markdown内容保持干净。

figure

figure 是 Markdown 中图像语法的扩展,它不提供更语义化的 HTML5

元素的简写形式。

figure简码可以使用以下命名参数:

  • src

    要显示的图像的URL。

  • link

    如果图像需要超链接,目标的URL。

  • target

    如果设置了link参数,则为URL的可选target属性。

  • rel

    如果设置了link参数,则为URL的可选rel属性。

  • alt

    如果无法显示图像,则为图像的替代文本。

  • title

    图像标题。

  • caption

    图像标题。在caption的值中的Markdown将被渲染。

  • class

    HTML figure标记的class属性。

  • height

    图像的height属性。

  • width

    图像的width属性。

  • attr

    图像归属文本。在attr的值中的Markdown将被渲染。

  • attrlink

    如果需要将归属文本超链接,则为目标的URL。

示例figure输入

figure-input-example.md

1
\{\{\< figure src="elephant.jpg" title=">An elephant at sunset" \>\}\}

示例figure输出

1
2
3
4
<figure>
  <img src="elephant.jpg">
  <figcaption>An elephant at sunset</figcaption>
</figure>

gist

​ 要显示此URL的GitHub代码片段(gist):

1
https://gist.github.com/user/50a7482715eac222e230d1e64dd9a89b

​ 在您的Markdown中包含以下内容:

1
\{\{\< gist user 50a7482715eac222e230d1e64dd9a89b \>\}\}

​ 这将按文件名按字母顺序显示gist中的所有文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ with .GetTerms "tags" }}
  <ul>
    {{ range . }}
      <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
    {{ end }}
  </ul>
{{ end }}
<ul>
  <li><a href="/tags/tag-a/">Tag A</a></li>
  <li><a href="/tags/tab-b/">Tab B</a></li>
  <li><a href="/tags/tab-c/">Tab C</a></li>
</ul>

​ 要显示gist中的特定文件:

1
\{\{\< gist user 50a7482715eac222e230d1e64dd9a89b 1-template.html \>\}\}

​ 渲染结果:

1
2
3
4
5
6
7
{{ with .GetTerms "tags" }}
  <ul>
    {{ range . }}
      <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
    {{ end }}
  </ul>
{{ end }}

highlight

​ 用于展示高亮代码示例:

1
2
3
4
5
\{\{\< highlight go-html-template \>\}\}
{{ range .Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}
\{\{\< /highlight \>\}\}

​ 渲染结果:

1
2
3
{{ range .Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}

​ 若要指定一个或多个高亮选项,请使用引号包围、逗号分隔的列表:

1
2
3
4
5
\{\{\< highlight go-html-template "lineNos=inline, lineNoStart=42" \>\}\}
{{ range .Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}
\{\{\< /highlight \>\}\}

​ 渲染结果:

1
2
3
42{{ range .Pages }}
43  <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
44{{ end }}

instagram

instagram简码使用Facebook的oEmbed Read功能。Facebook开发者文档说明:

  • 这个权限或特性需要App Review流程成功完成,然后您的应用才能访问实时数据。了解更多
  • 此权限或功能仅在业务验证后才可用。在应用访问数据之前,您可能还需要签署其他合同。在此处了解更多

​ 您必须获得Access Token才能使用instagram 简码。

​ 如果您的站点配置是私有的:

config.

=== “yaml”

``` yaml
services:
  instagram:
    accessToken: xxx
```

=== “toml”

``` toml
[services]
  [services.instagram]
    accessToken = 'xxx'
```

=== “json”

``` json
{
   "services": {
      "instagram": {
         "accessToken": "xxx"
      }
   }
}
```

​ 如果您的站点配置不是私有的,请使用环境变量设置 Access Token:

1
HUGO_SERVICES_INSTAGRAM_ACCESSTOKEN=xxx hugo --gc --minify

​ 如果您正在使用Client Access Token,您必须使用管道符(APPID|ACCESSTOKEN)将Access Token与您的App ID 结合起来。

​ 要显示具有此 URL 的 Instagram 帖子:

1
https://www.instagram.com/p/BWNjjyYFxVx/

​ 在您的 Markdown 中包含以下内容:

1
\{\{\< instagram BWNjjyYFxVx \>\}\}

param

​ 从当前页面的前置元数据中的 params 集合获取一个值,并回退到站点参数值。如果在其中都找不到具有给定键的参数,则会记录一个 ERROR

1
\{\{\< param testparam \>\}\}

​ 由于 testparam 是此页面前置元数据中定义的参数,其值为 Hugo Rocks!,因此以上内容将打印出:

Hugo Rocks!

​ 要访问深层嵌套的参数,请使用"点语法",例如:

1
\{\{\< param "my.nested.param" \>\}\}

refrelref

​ 这些简码将通过相对路径(例如blog/post.md)或逻辑名称(post.md)查找页面,并返回找到的页面的永久链接(ref 即 permalink )或相对永久链接(relref 即 relative permalink)。

refrelref还使得可以为Hugo生成的标题链接创建片段链接(fragmentary link)。

​ 在交叉引用文档中阅读有关 refrelref 的更详细描述。

refrelref 接受恰好一个必需的引用参数,引用参数必须在位置 0 上引用并使用引号引起来。

示例refrelref输入

1
2
[Neat](\{\{\< ref "blog/neat.md" \>\}\})
[Who](\{\{\< relref "about.md#who" \>\}\})

示例refrelref输出

​ 假设标准的 Hugo 美化 URL 已经开启。

1
2
<a href="https://example.com/blog/neat">Neat</a>
<a href="/about/#who">Who</a>

tweet

​ 要显示此URL的Twitter帖子:

1
https://twitter.com/SanDiegoZoo/status/1453110110599868418

​ 请在您的Markdown 中包含以下内容:

1
\{\{\< tweet user="SanDiegoZoo" id="1453110110599868418" \>\}\}

​ 渲染结果:

image-20230423202625065

vimeo

​ 要显示此 URL 的 Vimeo 视频:

1
https://vimeo.com/channels/staffpicks/55073825

​ 请在您的Markdown 中包含以下内容:

1
\{\{\< vimeo 55073825 \>\}\}

​ 渲染结果:

​ 如果您想进一步自定义 YouTube 或 Vimeo 输出的视觉样式,请在调用简码时添加一个名为 class 的参数。新的class将添加到包裹 <iframe><div> 中,并删除其内联样式。请注意,您还需要将id作为命名参数调用。您还可以使用 title 为 Vimeo 视频添加描述性标题。

1
\{\{\< vimeo id="146022717" class="my-vimeo-wrapper-class" title="My vimeo video" \>\}\}

youtube

youtube 简码为 YouTube 视频嵌入一个响应式视频播放器。仅需要视频的 ID,例如:

1
https://www.youtube.com/watch?v=w7Ft2ymGmfc

示例 youtube 输入

​ 复制视频 URL 中 v= 后面的 YouTube 视频 ID 并将其传递给 youtube 简码:

example-youtube-input.md

1
\{\{\< youtube w7Ft2ymGmfc \>\}\}

​ 此外,您可以将嵌入视频的autoplay 参数设置为 true,以自动开始播放。请记住,您不能混合使用命名和未命名参数,因此您需要将未命名的视频 ID 分配给 id 参数:

example-youtube-input-with-autoplay.md

1
\{\{\< youtube id="w7Ft2ymGmfc" autoplay="true" \>\}\}

​ 出于辅助功能的原因,最好为您的 YouTube 视频提供一个标题。您可以使用 title 参数为简码提供标题。如果没有提供标题,将使用默认标题"YouTube Video"。

example-youtube-input-with-title.md

1
\{\{\< youtube id="w7Ft2ymGmfc" title="A New Hugo Site in Under Two Minutes" \>\}\}

示例 youtube 输出

​ 使用上述 youtube 示例,将添加以下 HTML 到您的站点的标记中:

example-youtube-output.html

1
2
3
<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
  <iframe src="https://www.youtube.com/embed/w7Ft2ymGmfc?autoplay=1" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video"></iframe>
</div>

示例 youtube 显示

** 使用上述 youtube 示例(不带 autoplay="true"),以下是访问者在您的站点上看到的内容。当然,最终的显示将取决于您的样式表和周围的标记。该视频也包含在 Hugo 文档的快速入门中。

隐私配置

​ 要了解如何配置您的Hugo站点以满足新的欧盟隐私法规,请参阅Hugo和GDPR

创建自定义简码

​ 要了解更多有关创建自定义简码的信息,请参阅简码模板文档

另请参阅

5.11 - 相关内容

Related Content - 相关内容

https://gohugo.io/content-management/related/

​ 在"另请参阅"章节中列出相关内容。

​ Hugo 使用一组因素来基于前置元数据参数识别页面的相关内容。这可以调整为所需的索引和参数集,或者留给Hugo的默认相关内容配置

列出相关内容

​ 要列出最多 5 个相关页面(共享相同的datekeyword参数),只需在您的单个页面模板中包含类似以下内容的partial:

layouts/partials/related.html

1
2
3
4
5
6
7
8
9
{{ $related := .Site.RegularPages.Related . | first 5 }}
{{ with $related }}
<h3>See Also</h3>
<ul>
 {{ range . }}
 <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
 {{ end }}
</ul>
{{ end }}

Related方法接受一个参数,可以是Page或选项映射。这些选项映射具有以下选项:

  • indices

    要搜索的索引。

  • document

    要搜索相关内容的文档。

  • namedSlices

    要搜索的关键字。

  • fragments

    片段(fragments )包含一个用于配置为"fragments"类型的索引的特殊关键字列表。这将匹配文档的片段(fragment )标识符。

​ 使用以上所有选项的虚构示例:

1
2
3
4
5
6
7
{{ $page := . }}
{{ $opts := 
  "indices" (slice "tags" "keywords")
  "document" $page
  "namedSlices" (slice (keyVals "tags" "hugo" "rocks") (keyVals "date" $page.Date))
  "fragments" (slice "heading-1" "heading-2")
}}

​ 我们在Hugo 0.111.0中改进和简化了这个功能。在此之前,我们有3种不同的方法:RelatedRelatedToRelatedIndicies。现在我们只有一个方法:Related。旧的方法仍然可用但已弃用。另请参阅此博客文章,以获得更高级用法的详细解释。

在相关内容中索引内容标题

New in v0.111.0

​ Hugo可以索引您内容中的标题,并使用此功能查找相关内容。您可以通过将类型为fragments的索引添加到related配置中来启用此功能:

config.

=== “yaml”

``` yaml
related:
  includeNewer: true
  indices:
  - applyFilter: false
    name: fragmentrefs
    type: fragments
    weight: 80
  threshold: 20
  toLower: false
```

=== “toml”

``` toml
[related]
  includeNewer = true
  threshold = 20
  toLower = false
[[related.indices]]
  applyFilter = false
  name = 'fragmentrefs'
  type = 'fragments'
  weight = 80
```

=== “json”

``` json
{
   "related": {
      "includeNewer": true,
      "indices": [
         {
            "applyFilter": false,
            "name": "fragmentrefs",
            "type": "fragments",
            "weight": 80
         }
      ],
      "threshold": 20,
      "toLower": false
   }
}
```
  • name映射到可选的前置元数据切片属性,可用于从页面级别链接到片段/标题(fragment/heading)级别。
  • 如果启用applyFilter,则结果中每个页面上的.HeadingsFiltered将反映筛选后的标题。如果您想在相关内容列表中显示标题,则这很有用:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{{ $related := .Site.RegularPages.Related . | first 5 }}
{{ with $related }}
  <h2>See Also</h2>
  <ul>
    {{ range $i, $p := . }}
      <li>
        <a href="{{ .RelPermalink }}">{{ .Title }}</a>
        {{ with .HeadingsFiltered }}
          <ul>
            {{ range . }}
              {{ $link := printf "%s#%s" $p.RelPermalink .ID | safeURL }}
              <li>
                <a href="{{ $link }}">{{ .Title }}</a>
              </li>
            {{ end }}
          </ul>
        {{ end }}
      </li>
    {{ end }}
  </ul>
{{ end }}

配置相关内容

​ Hugo提供了相关内容的合理默认配置,但是如果需要,您可以在全局或语言级别上对其进行微调。

默认配置

​ 如果项目上没有设置任何related配置,则Hugo的相关内容方法将使用以下内容。

config.

=== “yaml”

``` yaml
related:
  includeNewer: false
  indices:
  - name: keywords
    weight: 100
  - name: date
    weight: 10
  threshold: 80
  toLower: false
```

=== “toml”

``` toml
[related]
  includeNewer = false
  threshold = 80
  toLower = false
[[related.indices]]
  name = 'keywords'
  weight = 100
[[related.indices]]
  name = 'date'
  weight = 10
```

=== “json”

``` json
{
   "related": {
      "includeNewer": false,
      "indices": [
         {
            "name": "keywords",
            "weight": 100
         },
         {
            "name": "date",
            "weight": 10
         }
      ],
      "threshold": 80,
      "toLower": false
   }
}
```

​ 请注意,如果您将tags配置为分类(taxonomy),那么tags将与上述默认配置一起添加,并且权重为80

​ 应该使用相同的语法设置自定义配置。

如果添加了一个related 配置部分,则需要添加完整配置。不能只设置例如 includeNewer,并使用 Hugo 默认值中的其他部分。

顶级配置选项

  • threshold

    0-100之间的值。较低的值将提供更多但可能不是很相关的匹配项。

  • includeNewer

    设置为true以在相关内容列表中包含新于当前页面的页面。这意味着旧帖子的输出可能会随着添加新的相关内容而发生变化。

  • toLower

    将索引和查询中的关键字转换为小写。这可能会以轻微的性能损失为代价提供更准确的结果。请注意,这也可以针对每个索引进行设置。

每个索引的配置选项

  • name

    索引名称。此值直接映射到页面参数。 Hugo支持字符串值(例如示例中的author)和列表(tagskeywords等)以及时间和日期对象。

  • type

    v0.111.0 中的新功能。basic(默认)或fragments之一。

  • applyFilter

    v0.111.0 中的新功能。将type特定的过滤器应用于搜索结果。目前仅用于fragments类型。

  • weight

    表示该参数相对于其他参数的重要性的整数权重。它可以是0,这将关闭此索引的效果,甚至可以是负数。使用不同的值进行测试,以确定最适合您内容的值。

  • cardinalityThreshold (default 0)

    v0.111.0 中的新功能。用于从索引中删除常见关键字的百分比(0-100)。例如,将此设置为50将删除在索引中使用超过50%的文档中使用的所有关键字。

  • pattern

    目前仅对日期相关。在列出相关内容时,我们可能希望列出时间上也接近的内容。将"2006"(日期索引的默认值)设置为日期索引的模式将增加发布于同一年的页面的权重。对于访问频繁的博客,“200601”(年份和月份)可能是更好的默认值。

  • toLower

    见上文。

性能考虑

​ 快是Hugo的中间名,如果它不是非常快,我们不会发布此功能。

​ 这个功能已经在后台计划中,并被很多人长期要求。这个开发最近受到这个Twitter帖子的推动:

​ Scott S. Lowe 移除了使用标签上的intersect模板函数构建的"相关内容"部分,结果在其拥有 1700 篇文章的博客上,构建时间从 30 秒减少到不到 2 秒。

​ 他现在应该能够添加一个改进版的"相关内容"部分,而不会影响快速的实时重新加载。但需要注意的是:

​ 他现在应该能够添加改进版的"相关内容"部分,而不放弃快速的实时重载。但值得注意的是:

  • 如果您不使用任何Related方法,您将不会使用相关内容功能,性能将与之前相同。
  • 调用.RegularPages.Related等将创建一个倒排索引(有时也称为posting list),它将被重用于同一页面集合中的任何查找。在另外调用.Pages.Related之类的方法时,它会按预期工作,但会创建一个额外的倒排索引。这仍然非常快,但值得注意,特别是对于较大的站点。

​ 我们目前不对页面内容进行索引。我们认为在解决 Sherlock 的最后一个案件之前,发布一些能让大多数人满意的东西是值得的。

另请参阅

5.12 - 内容章节

Content Sections - 内容章节

https://gohugo.io/content-management/sections/

​ Hugo 生成与您的内容匹配的章节树。

​ 章节是根据 content/ 目录下的组织结构定义的页面集合。

​ 默认情况下,content/ 下的所有一级目录都形成自己的章节(根章节),前提是它们构成分支 Bundles。即使是一级目录,如果它们只是叶子 Bundles,也不会形成自己的章节。

​ 如果用户需要在更深的层次上定义一个名为 foo 的章节,则需要创建一个名为 foo 的目录,并包含一个 _index.md 文件(有关更多信息,请参见分支 Bundles)。

​ 章节不能通过前置元数据参数进行定义或覆盖——它严格基于内容组织结构派生。

嵌套章节

​ 章节可以嵌套到任意深度。

1
2
3
4
5
6
7
8
content
└── blog        <-- Section, 因为是content/目录下的一级目录
    ├── funny-cats
    │   ├── mypost.md
    │   └── kittens         <-- Section, 因为包含 _index.md
    │       └── _index.md
    └── tech                <-- Section, 因为包含 _index.md
        └── _index.md

​ 理解的重要部分是,为了使章节树完全可导航,至少需要一个内容文件作为最低层的章节(例如 _index.md)。

​ 当我们谈论与模板选择相关的章节时,目前仅涉及根章节(/blog/funny-cats/mypost/ => blog)。

​ 如果您需要一个子章节的特定模板,则需要在前置元数据参数中调整typelayout

示例:面包屑导航

​ 通过可用的章节变量和方法,您可以构建强大的导航。其中一个常见的示例是使用部分(partial )来显示面包屑导航:

layouts/partials/breadcrumb.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<nav aria-label="breadcrumb">
  <ol>
    {{ range .Ancestors.Reverse }}
      <li>
        <a href="{{ .Permalink }}">{{ .LinkTitle }}</a>
      </li>
    {{ end }}
    <li class="active">
      <a aria-current="page" href="{{ .Permalink }}">{{ .LinkTitle }}</a>
    </li>
  </ol>
</nav>

章节页面变量和方法

​ 另请参见页面变量

  • .CurrentSection

    该页面所属的当前章节。如果该页面本身就是章节或主页,则该值可以是该页面本身。

  • .FirstSection

    根目录下该页面的第一级章节,例如/docs/blog 等。

  • .InSection $anotherPage

    给定页面是否在当前章节中。

  • .IsAncestor $anotherPage

    当前页面是否是给定页面的祖先。

  • .IsDescendant $anotherPage

    当前页面是否是给定页面的后代。

  • .Parent

    一个章节的父章节或一个页面所属的章节。

  • .Section

    该内容所属的章节。注意:对于被嵌套章节,这是目录中的第一个路径元素,例如 /blog/funny/mypost/ => blog

  • .Sections

    此内容下面的章节。

内容章节列表

​ Hugo 将为每个根章节自动创建一个页面,列出该章节中的所有内容。有关自定义这些页面的渲染方式的详细信息,请参见章节模板文档。

内容章节与内容类型

​ 默认情况下,创建在章节中的所有内容都将使用与根章节名称相匹配的内容type。例如,Hugo 将假定 posts/post-1.md 具有 posts 内容type。如果您正在使用 post 章节的原型,Hugo 将根据在 archetypes/posts.md 中找到的内容生成前置元数据。

另请参阅

5.13 - 原型

Archetypes - 原型

https://gohugo.io/content-management/archetypes/

​ Archetypes是在创建新内容时使用的模板。

什么是Archetypes?

​ Archetypes是位于项目的archetypes目录中的内容模板文件,其中包含为您的站点内容类型(content types)预配置的前置元数据(前置元数据)和可能的内容排列方式。当您运行hugo new时,将使用这些模板。

hugo new使用content-section来查找项目中最合适的原型模板。如果您的项目不包含任何原型文件,它也会在主题中查找。

archetype-example.sh

1
hugo new posts/my-first-post.md

​ 以上将创建一个新的内容文件content/posts/my-first-post.md,使用找到的第一个原型文件:

  1. archetypes/posts.md
  2. archetypes/default.md
  3. themes/my-theme/archetypes/posts.md
  4. themes/my-theme/archetypes/default.md

​ 最后两个列表项仅适用于您使用主题并且它使用my-theme主题名称作为示例。

创建新的Archetype模板

​ 以下是一个虚构的newsletter section 的示例,以及原型文件archetypes/newsletter.md。在archetypes/中创建一个新文件newsletter.md并在文本编辑器中打开它。

archetypes/newsletter.md

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---

**Insert Lead paragraph here.**

## New Cool Posts

{{ range first 10 ( where .Site.RegularPages "Type" "cool" ) }}
* {{ .Title }}
{{ end }}

​ 当您使用以下命令创建新的newsletter:

1
hugo new newsletter/the-latest-cool.stuff.md

​ 它将基于原型模板创建一个新的newsletter类型的内容文件。

!!! warning “注意” 注意:如果在原型文件中使用了 .Site,那么只有在构建站点时才会构建。这对于大型站点可能需要很长时间。

​ 上述newsletter类型的原型展示了可能性:完整的Hugo .Site和所有Hugo模板函数都可以在原型文件中使用。

基于目录的archetypes

​ 从Hugo 0.49开始,您可以使用完整的目录作为原型模板。假设有以下原型目录:

1
2
3
4
5
6
7
archetypes
├── default.md
└── post-bundle
    ├── bio.md
    ├── images
    │   └── featured.jpg
    └── index.md
1
hugo new --kind post-bundle posts/my-post

​ 该命令将创建一个新的文件夹/content/posts/my-post,并且它包含与post-bundle原型文件夹中相同的一组文件。所有内容文件(例如index.md)都可以包含模板逻辑,并将为内容的语言接收正确的.Site

另请参阅

5.14 - 分类法

Taxonomies - 分类法

https://gohugo.io/content-management/taxonomies/

​ Hugo支持用户定义的分类法。

什么是分类法?

​ Hugo支持用户定义的内容分组,称为分类法(taxonomies)。分类法是内容之间逻辑关系的分类。

定义

  • Taxonomy

    可用于对内容进行分类的分类方式

  • Term

    分类法中的一个键

  • Value

    分配给项(term)的内容

示例分类法:电影站点

​ 假设您正在制作一个关于电影的站点。您可能想包括以下分类法:

  • Actors 演员
  • Directors 导演
  • Studios 制片厂
  • Genre 流派
  • Year 年份
  • Awards 奖项

​ 然后,在每部电影中,您都需要为这些分类法指定项(即,在每部电影的内容文件的前置元数据中)。根据这些项(terms),Hugo会自动创建每个Actor、Director、Studio、Genre、Year和Award的页面,每个页面都会列出与特定Actor、Director、Studio、Genre、Year和Award匹配的所有电影。

电影分类法组织

​ 继续使用电影站点的示例,以下演示了从分类法的角度看内容关系:

1
2
3
4
5
6
7
8
9
Actor                    <- Taxonomy
    Bruce Willis         <- Term
        The Sixth Sense  <- Value
        Unbreakable      <- Value
        Moonrise Kingdom <- Value
    Samuel L. Jackson    <- Term
        Unbreakable      <- Value
        The Avengers     <- Value
        xXx              <- Value

​ 从内容的角度看,关系看起来不同,尽管使用的数据和标签是相同的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Unbreakable                 <- Value
    Actors                  <- Taxonomy
        Bruce Willis        <- Term
        Samuel L. Jackson   <- Term
    Director                <- Taxonomy
        M. Night Shyamalan  <- Term
    ...
Moonrise Kingdom            <- Value
    Actors                  <- Taxonomy
        Bruce Willis        <- Term
        Bill Murray         <- Term
    Director                <- Taxonomy
        Wes Anderson        <- Term
    ...

Hugo分类法默认设置

​ Hugo本身支持分类法。

​ 不需要在您的站点配置文件中添加任何行,Hugo将自动为tagscategories创建分类法。这与手动配置您的分类法相同,如下所示:

config.

=== “yaml”

``` yaml
taxonomies:
  category: categories
  tag: tags
```

=== “toml”

``` toml
[taxonomies]
  category = 'categories'
  tag = 'tags'
```

=== “json”

``` json
{
   "taxonomies": {
      "category": "categories",
      "tag": "tags"
   }
}
```

​ 如果您不想让Hugo创建任何分类法,请将站点配置中的disableKinds设置为以下内容:

config.

=== “yaml”

``` yaml
disableKinds:
- taxonomy
- term
```

=== “toml”

``` toml
disableKinds = ['taxonomy', 'term']

```

=== “json”

``` json
{
   "disableKinds": [
      "taxonomy",
      "term"
   ]
}

```
KindDescriptionExample
home主页的着陆页/index.html
page给定页面的着陆页my-post page (/posts/my-post/index.html)
section给定章节的着陆页posts section (/posts/index.html)
taxonomy分类法的着陆页tags taxonomy (/tags/index.html)
term一个分类法项的着陆页term awesome in tags taxonomy (/tags/awesome/index.html)

默认目标

​ 当使用分类法并提供分类法模板时,Hugo将自动创建列出所有分类法项的页面以及列出与每个项关联的内容的个别页面。例如,在您的配置中声明并在内容前置元数据中使用的categories分类法将创建以下页面:

配置分类法

​ 除了默认之外的自定义分类法在整个站点中使用之前必须在站点配置中定义。您需要为每个分类法提供复数和单数标签。例如,对于TOML,singular key = "plural value",而对于YAML,singular key: "plural value"

示例:添加名为"series"的自定义分类法

在添加自定义分类法时,如果您想保留它们,您需要同时添加默认分类法。

config.

=== “yaml”

``` yaml
taxonomies:
  category: categories
  series: series
  tag: tags
```

=== “toml”

``` toml
[taxonomies]
  category = 'categories'
  series = 'series'
  tag = 'tags'
```

=== “json”

``` json
{
   "taxonomies": {
      "category": "categories",
      "series": "series",
      "tag": "tags"
   }
}
```

示例:删除默认分类法

​ 如果您只想要默认tags分类法,并删除您站点的categories分类法,可以通过修改站点配置文件中的taxonomies值来实现。

config.

=== “yaml”

``` yaml
taxonomies:
  tag: tags
```

=== “toml”

``` toml
[taxonomies]
  tag = 'tags'
```

=== “json”

``` json
{
   "taxonomies": {
      "tag": "tags"
   }
}
```

​ 如果您想要完全禁用所有分类法,请参阅 Hugo 分类法默认设置disableKinds 的用法。

​ 您可以向您的分类法列表和分类法项页面添加内容和前置元数据。有关如何为此目的添加 _index.md 的更多信息,请参见内容组织

​ 与常规页面类似,分类法列表永久链接是可配置的,但分类法项页面永久链接是不可配置的。

​ Hugo 0.55 版中删除了配置选项 preserveTaxonomyNames

​ 现在,您可以在相关分类法节点(taxonomy node)上使用 .Page.Title 来获取原始值。

将分类法添加到内容中

​ 一旦在站点级别定义了分类法,任何内容都可以被分配给它,而不管内容类型内容章节

​ 将内容分配给分类法是在前置元数据中完成的。只需创建一个变量,其名称为taxonomy 的复数形式,并分配所有要应用于内容类型实例的项。

​ 如果您希望能够快速生成具有预配置分类法或项的内容文件,请阅读有关 Hugo 原型的文档。

示例:带有taxonomies 的前置元数据

content/example.md

=== “yaml”

``` yaml
---
categories:
- Development
project_url: https://github.com/gohugoio/hugo
series:
- Go Web Dev
slug: hugo
tags:
- Development
- Go
- fast
- Blogging
title: 'Hugo: A fast and flexible static site generator'
---
```

=== “toml”

``` toml
+++
categories = ['Development']
project_url = 'https://github.com/gohugoio/hugo'
series = ['Go Web Dev']
slug = 'hugo'
tags = ['Development', 'Go', 'fast', 'Blogging']
title = 'Hugo: A fast and flexible static site generator'
+++
```

=== “json”

``` json
{
   "categories": [
      "Development"
   ],
   "project_url": "https://github.com/gohugoio/hugo",
   "series": [
      "Go Web Dev"
   ],
   "slug": "hugo",
   "tags": [
      "Development",
      "Go",
      "fast",
      "Blogging"
   ],
   "title": "Hugo: A fast and flexible static site generator"
}
```

排序分类法

​ 内容文件可以为其关联的每个分类法分配权重。分类法权重可用于在分类法列表模板中排序或排序内容,并在内容文件的前置元数据中声明。声明分类法权重的约定是taxonomyname_weight

​ 以下显示一个具有权重为22的内容,可在渲染分配给tags分类法的"a"、“b"和"c"值的页面时用于排序目的。在渲染"d"类别页面时,它也被分配了权重44。

示例:分类法weight

=== “yaml”

``` yaml
categories:
- d
categories_weight: 44
tags:
- a
- b
- c
tags_weight: 22
title: foo
```

=== “toml”

``` toml
categories = ['d']
categories_weight = 44
tags = ['a', 'b', 'c']
tags_weight = 22
title = 'foo'
```

=== “json”

``` json
{
   "categories": [
      "d"
   ],
   "categories_weight": 44,
   "tags": [
      "a",
      "b",
      "c"
   ],
   "tags_weight": 22,
   "title": "foo"
}
```

​ 通过使用分类法权重,同一篇内容可以在不同的分类法中出现在不同的位置。

​ 目前,分类法仅支持默认weight => date排序列表内容。有关更多信息,请参见分类法模板的文档。

向分类法或项添加自定义元数据

​ 如果您需要向分类法项添加自定义元数据,则需要在 /content/<TAXONOMY>/<TERM>/_index.md 中创建该项的页面,并在其前置元数据中添加您的元数据。继续以’Actors’为例,假设您想为每个演员添加维基百科页面链接。您的分类项页面将如下所示:

content/actors/bruce-willis/_index.md

=== “yaml”

``` yaml
---
title: Bruce Willis
wikipedia: https://en.wikipedia.org/wiki/Bruce_Willis
---
```

=== “toml”

``` toml
+++
title = 'Bruce Willis'
wikipedia = 'https://en.wikipedia.org/wiki/Bruce_Willis'
+++
```

=== “json”

``` json
{
   "title": "Bruce Willis",
   "wikipedia": "https://en.wikipedia.org/wiki/Bruce_Willis"
}
```

另请参阅

5.15 - 内容摘要

Content Summaries - 内容摘要

https://gohugo.io/content-management/summaries/

​ Hugo 可以生成内容的摘要。

​ 通过使用.Summary页面变量,Hugo会生成内容摘要以在摘要视图中用作简短版本。

摘要拆分选项

  • 自动摘要拆分
  • 手动摘要拆分
  • 前置元数据摘要

​ 在摘要中附带指向原始内容的链接是很自然的,常见的设计模式是以"Read More …“按钮的形式渲染。参见 .RelPermalink.Permalink.Truncated 页面变量

自动摘要拆分

​ 默认情况下,Hugo 会自动将内容的前 70 个字作为摘要,并将其存储在 .Summary 页面变量中供模板使用。您可以通过在站点配置中设置 summaryLength 来自定义摘要长度。

​ 您可以使用 plainifysafeHTML 等函数自定义摘要中加载的 HTML 标记的方式。

​ Hugo 定义的摘要使用的是通过将文本按一个或多个连续空格字符拆分计算的字数。如果您使用 CJK 语言创建内容,并希望使用 Hugo 的自动摘要拆分,请在站点配置中将 hasCJKLanguage 设置为 true

手动摘要拆分

​ 或者,您可以在想要拆分文章的地方添加 `

` 摘要分隔符。

​ 对于 Org 模式内容,请在想要拆分文章的地方使用 # more

​ 摘要分隔符之前的内容将用作该内容的摘要,并以完整的 HTML 格式存储在 .Summary 页面变量中。

​ 摘要分隔符的概念不仅仅适用于 Hugo。在其他文献中,它也被称为"more tag"或"excerpt separator”。

  • Pros(优点)

    自由、精度和提高渲染质量。所有 HTML 标记和格式都会被保留。

  • Cons(缺点)

    需要内容作者额外的工作,因为他们需要记得在每个内容文件中输入 <!--more-->(或 org 内容# more)。可以通过在原型的前置元数据下方添加摘要分隔符来自动化这一过程。

​ 请确保精确输入 <!--more-->;即全部小写且没有空格。

前置元数据摘要

​ 您可能希望文章摘要不是从文章开头开始的文本。在这种情况下,您可以在文章前置元数据的summary变量中提供一个单独的摘要。

  • Pros(优点)

    完全自由的文本,与文章内容无关。可以在摘要中使用标记。

  • Cons(缺点)

    对于内容作者来说,需要编写一个完全独立的文本作为文章的摘要,这会增加额外的工作量。

摘要选择顺序

​ 因为有多种方法可以指定摘要,了解 Hugo 在决定返回 .Summary 的文本时遵循的选择顺序是有用的。它如下所示:

  1. 如果文章中存在 <!--more--> 摘要分隔符,则提供分隔符之前的文本,按照手动摘要拆分方法。
  2. 如果文章前置元数据中有一个summary变量,则按照前置元数据摘要方法提供变量的值。
  3. 按照自动摘要拆分方法,提供文章开头的文本。

​ Hugo 使用上述步骤中返回的第一个文本。因此,例如,如果您的文章在其前言中具有summary变量和一个 <!--more--> 摘要分隔符,Hugo 将使用手动摘要拆分方法。

示例:前 10 篇带摘要的文章

​ 您可以使用以下代码显示内容摘要。例如,您可以在一个章节模板中使用以下代码片段。

page-list-with-summaries.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{{ range first 10 .Pages }}
    <article>
      <!-- this <div> includes the title summary -->
      <div>
        <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
        {{ .Summary }}
      </div>
      {{ if .Truncated }}
      <!-- This <div> includes a read more link, but only if the summary is truncated... -->
      <div>
        <a href="{{ .RelPermalink }}">Read More…</a>
      </div>
      {{ end }}
    </article>
{{ end }}

注意,当内容未被截断时,即摘要包含整篇文章时,.Truncated 布尔变量值可以用于隐藏"Read More…“链接。

5.16 - 链接和交叉引用

Links and Cross References - 链接和交叉引用

https://gohugo.io/content-management/cross-references/

​ 用于创建指向文档的简码链接。

refrelref简码分别显示文档的绝对和相对永久链接。

使用refrelref

refrelref简码需要一个参数:指向内容文档的路径,带有或不带有文件扩展名,带有或不带有锚点。没有前导 / 的路径首先相对于当前页面解析,然后相对于站点的其余部分解析。

.
└── content
    ├── about
    |   ├── _index.md
    |   └── credits.md
    ├── pages
    |   ├── document1.md
    |   └── document2.md    // has anchor #anchor
    ├── products
    |   └── index.md
    └── blog
        └── my-post.md

​ 这些页面可以按以下方式被引用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
\{\{\< ref "document2" \>\}\}             // <- From pages/document1.md, relative path
\{\{\< ref "document2#anchor" \>\}\}      
\{\{\< ref "document2.md" \>\}\}          
\{\{\< ref "document2.md#anchor" \>\}\}   
\{\{\< ref "#anchor" \>\}\}               // <- From pages/document2.md
\{\{\< ref "/blog/my-post" \>\}\}         // <- From anywhere, absolute path
\{\{\< ref "/blog/my-post.md" \>\}\}
\{\{\< relref "document" \>\}\}
\{\{\< relref "document.md" \>\}\}
\{\{\< relref "#anchor" \>\}\}
\{\{\< relref "/blog/my-post.md" \>\}\}

index.md可以被其路径或其不带结尾 / 的所在文件夹引用。_index.md只被其所在文件夹引用:

1
2
3
4
5
6
\{\{\< ref "/about" \>\}\}             // <- References /about/_index.md
\{\{\< ref "/about/_index" \>\}\}      //    Raises REF_NOT_FOUND error
\{\{\< ref "/about/credits.md" \>\}\}  // <- References /about/credits.md

\{\{\< ref "/products" \>\}\}          // <- References /products/index.md
\{\{\< ref "/products/index" \>\}\}    // <- References /products/index.md

​ 在Markdown中使用refrelref生成超链接:

1
[About](\{\{\< ref "/about" \>\}\} "About Us")

​ 如果文档无法被唯一解析,Hugo将发出错误或警告。错误行为可配置,请参阅下文。

链接到另一种语言版本

​ 要链接到文档的另一种语言版本,请使用以下语法:

1
\{\{\< relref path="document.md" lang="ja" \>\}\}

获取另一种输出格式

​ 要链接到文档的另一种输出格式,请使用以下语法:

1
\{\{\< relref path="document.md" outputFormat="rss" \>\}\}

标题ID

​ 使用Markdown文档类型时,Hugo为页面上的每个标题生成元素ID。例如:

1
## Reference

生成以下HTML:

1
<h2 id="reference">Reference</h2>

​ 在使用refrelref简码时,通过将ID附加到路径来获取标题的永久链接:

1
2
\{\{\< ref "document.md#reference" \>\}\}
\{\{\< relref "document.md#reference" \>\}\}

​ 通过包含属性来生成自定义标题ID。例如:

1
2
## Reference A {#foo}
## Reference B {id="bar"}

生成以下HTML:

1
2
<h2 id="foo">Reference A</h2>
<h2 id="bar">Reference B</h2>

​ 如果同一标题在页面上出现多次,Hugo将生成唯一的元素ID。例如:

1
2
3
## Reference
## Reference
## Reference

生成以下HTML:

1
2
3
<h2 id="reference">Reference</h2>
<h2 id="reference-1">Reference</h2>
<h2 id="reference-2">Reference</h2>

Ref 和 RelRef 配置

​ 自 Hugo 0.45 开始,该行为可以在 config.toml 中进行配置:

  • refLinksErrorLevel (“ERROR”)

    使用refrelref解析页面链接时,如果链接无法解析,将使用此日志级别记录。有效值为ERROR(默认)或WARNING。任何ERROR都将导致构建失败(exit -1)。

  • refLinksNotFoundURL

    refrelref 中找不到页面引用时使用的 URL 占位符。则原样使用。

另请参阅

5.17 - URL管理

URL Management - URL管理

https://gohugo.io/content-management/urls/

​ 通过前置元数据输入和站点配置中的设置来控制URL的结构和外观。

概述

​ 默认情况下,当Hugo渲染页面时,生成的URL与content目录中的文件路径匹配。例如:

1
content/posts/post-1.md → https://example.org/posts/post-1/

​ 您可以通过前置元数据值和站点配置选项来更改URL的结构和外观。

前置元数据

slug

Set the slug in 前置元数据 to override the last segment of the path. The slug value does not affect section pages.

​ 在前置元数据中设置slug以覆盖路径的最后一段。slug值不影响部分页面。

content/posts/post-1.md

=== “yaml”

``` yaml
---
slug: my-first-post
title: My First Post
---

```

=== “toml”

``` toml
+++
slug = 'my-first-post'
title = 'My First Post'
+++
```

=== “json”

``` json
{
   "slug": "my-first-post",
   "title": "My First Post"
}
```

​ 结果的URL将是:

1
https://example.org/posts/my-first-post/

url

​ 在前置元数据中设置url以覆盖整个路径。将其用于常规页面或section页面。

​ 具有以下前置元数据的:

content/posts/post-1.md

=== “yaml”

``` yaml
---
title: My First Article
url: /articles/my-first-article
---
```

=== “toml”

``` toml
+++
title = 'My First Article'
url = '/articles/my-first-article'
+++
```

=== “json”

``` json
{
   "title": "My First Article",
   "url": "/articles/my-first-article"
}
```

​ 结果的URL将是:

1
https://example.org/articles/my-first-article/

​ 如果包括文件扩展名:

content/posts/post-1.md

=== “yaml”

``` yaml
---
title: My First Article
url: /articles/my-first-article.html
---
```

=== “toml”

``` toml
+++
title = 'My First Article'
url = '/articles/my-first-article.html'
+++
```

=== “json”

``` json
{
   "title": "My First Article",
   "url": "/articles/my-first-article.html"
}
```

结果的URL将是:

1
https://example.org/articles/my-first-article.html

​ 在单语站点中,带有或不带有前导斜杠的url值相对于baseURL

​ 在多语言站点中:

  • 带有前导斜杠的url值相对于baseURL
  • 没有前导斜杠的url值相对于baseURL加上语言前缀。
Site type前置元数据 urlResulting URL
monolingual/abouthttps://example.org/about/
monolingualabouthttps://example.org/about/
multilingual/abouthttps://example.org/about/
multilingualabouthttps://example.org/de/about/

​ 如果在前置元数据中同时设置slugurl,则url值优先。

站点配置

​ 在站点配置中,为顶层section内的常规页面设置URL模式。这是递归的,影响后代常规页面。

​ 在站点配置中定义的permalinks不适用于section页面。要调整section页面的URL,请在前置元数据中设置url

例子

​ 使用此内容结构:

1
2
3
4
5
6
content/
├── posts/
│   ├── _index.md
│   ├── post-1.md
│   └── post-2.md
└── _index.md

​ 为posts section内的普通页面创建一个基于日期的递归层次结构:

config.

=== “yaml”

``` yaml
posts: /posts/:year/:month/:title/
```

=== “toml”

``` toml
posts = '/posts/:year/:month/:title/'
```

=== “json”

``` json
{
   "posts": "/posts/:year/:month/:title/"
}
```

​ 发布站点的结构将是:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public/
├── posts/
│   ├── 2023/
│   │   └── 03/
│   │       ├── post-1/
│   │       │   └── index.html
│   │       └── post-2/
│   │           └── index.html
│   └── index.html
├── favicon.ico
└── index.html

​ 要为内容根目录中的常规页面创建基于日期的层次结构:

config.

=== “yaml”

``` yaml
/: /:year/:month/:title/
```

=== “toml”

``` toml
'/' = '/:year/:month/:title/'
```

=== “json”

``` json
{
   "/": "/:year/:month/:title/"
}
```

​ 为内容根目录定义的URL模式不适用于递归。

​ 使用相同的方法处理分类(taxonomies)。例如,要省略URL的分类段(taxonomy segment):

config.

=== “yaml”

``` yaml
tags: /:title/
```

=== “toml”

``` toml
tags = '/:title/'
```

=== “json”

``` json
{
   "tags": "/:title/"
}
```

​ 前置元数据url值优先于permalinks中定义的URL模式。

Tokens

​ 在定义URL模式时使用这些标记。前置元数据中的date字段确定与时间相关的标记的值。

  • :year

    4位数字的年份

  • :month

    2位数字的月份

  • :monthname

    月份的名称

  • :day

    2位数字的日期

  • :weekday

    一周中的1位数字日期(星期日=0)

  • :weekdayname

    一周中日期的名称

  • :yearday

    1到3位数字的一年中的日期

  • :section

    内容的section

  • :sections

    内容的section层次结构。您可以使用切片语法选择section::sections[1:] 包括除第一个部分以外的所有部分,:sections[:last] 包括除最后一个部分以外的所有部分,:sections[last] 仅包括最后一个部分,:sections[1:2] 包括第2个和第3个section (这里应该是由问题的:按照go的语法这里应该只包括第1个section才对吧)。请注意,这种切片访问不会抛出任何越界错误,因此您不必非常精确。

  • :title

    内容的标题

  • :slug

    内容的 slug(如果在前置元数据中未提供 slug,则使用title)

  • :slugorfilename

    内容的 slug(如果在前置元数据中未提供 slug,则使用文件名)

  • :filename

    内容的文件名(不包括扩展名)

​ 对于与时间有关的值,您还可以使用 Go 的 time 包中定义的布局字符串组件。例如:

config.

=== “yaml”

``` yaml
permalinks:
  posts: /:06/:1/:2/:title/
```

=== “toml”

``` toml
[permalinks]
  posts = '/:06/:1/:2/:title/'
```

=== “json”

``` json
{
   "permalinks": {
      "posts": "/:06/:1/:2/:title/"
   }
}
```

外观

​ URL 的外观可以是丑陋的或漂亮的。

TypePathURL
uglycontent/about.mdhttps://example.org/about.html
prettycontent/about.mdhttps://example.org/about/

​ 默认情况下,Hugo 生成漂亮的 URL。要生成丑陋的 URL,请更改您的站点配置:

config.

=== “yaml”

``` yaml
uglyURLs: true
```

=== “toml”

``` toml
uglyURLs = true
```

=== “json”

``` json
{
   "uglyURLs": true
}
```

Post-processing

​ Hugo 提供了两个相互排斥的配置选项,用于在渲染页面后更改 URL。

Canonical URLs ( 规范化 URL )

​ 这是一个传统的配置选项,被模板函数和 markdown 渲染钩子取代,很可能会在未来的版本中被删除

​ 如果启用,Hugo 在渲染页面后执行搜索和替换。它搜索与 actionhrefsrcsrcseturl 属性相关联的站点相对 URL(具有前导斜杠)。然后,它添加 baseURL 来创建绝对 URL。

1
2
<a href="/about"> → <a href="https://example.org/about/">
<img src="/a.gif"> → <img src="https://example.org/a.gif">

​ 这是一种不完美、蛮力的方法,会影响内容以及HTML属性。正如上面提到的,这是一个旧的配置选项,可能会在未来的版本中被删除。

启用方法如下:

config.

=== “yaml”

``` yaml
canonifyURLs: true
```

=== “toml”

``` toml
canonifyURLs = true
```

=== “json”

``` json
{
   "canonifyURLs": true
}
```

Relative URLs

​ 除非您创建的是可通过文件系统导航的无服务器站点,否则不要启用此选项。

​ 如果启用此选项,Hugo将在渲染页面后执行搜索和替换。它将搜索与actionhrefsrcsrcseturl属性相关的站点相对URL(带有前导斜杠)。然后将URL转换为相对于当前页面的URL。

​ 例如,在渲染content/posts/post-1时:

1
2
<a href="/about"> → <a href="../../about">
<img src="/a.gif"> → <img src="../../a.gif">

​ 这是一种不完美、蛮力的方法,会影响内容以及HTML属性。正如上面提到的,除非您创建的是可通过文件系统导航的无服务器站点,否则不要启用此选项。

启用方法如下:

config.

=== “yaml”

``` yaml
relativeURLs: true
```

=== “toml”

``` toml
relativeURLs = true

```

=== “json”

``` json
{
   "relativeURLs": true
}

```

别名

​ 使用别名从旧URL重定向到新URL:

  • 带有前导斜杠的别名相对于baseURL
  • 没有前导斜杠的别名相对于当前目录

示例

​ 更改现有页面的文件名,并创建从先前URL到新URL的别名:

content/posts/new-file-name.md.

=== “yaml”

``` yaml
aliases:
- /posts/previous-file-name
```

=== “toml”

``` toml
aliases = ['/posts/previous-file-name']

```

=== “json”

``` json
{
   "aliases": [
      "/posts/previous-file-name"
   ]
}

```

Each of these directory-relative aliases is equivalent to the site-relative alias above:

​ 这些目录相对别名与上面的站点相对别名等效:

  • previous-file-name

  • ./previous-file-name

  • ../posts/previous-file-name

​ 您可以为当前页面创建多个别名:

content/posts/new-file-name.md.

=== “yaml”

``` yaml
aliases:
- previous-file-name
- original-file-name
```

=== “toml”

``` toml
aliases = ['previous-file-name', 'original-file-name']

```

=== “json”

``` json
{
   "aliases": [
      "previous-file-name",
      "original-file-name"
   ]
}

```

​ 在多语言站点中,可以使用目录相对别名,或者使用站点相对别名包含语言前缀:

content/posts/new-file-name.de.md.

=== “yaml”

``` yaml
aliases:
- /de/posts/previous-file-name
```

=== “toml”

``` toml
aliases = ['/de/posts/previous-file-name']

```

=== “json”

``` json
{
   "aliases": [
      "/de/posts/previous-file-name"
   ]
}
```

别名的工作原理

​ 使用上面的第一个示例,Hugo 生成了以下站点结构:

1
2
3
4
5
6
7
8
public/
├── posts/
│   ├── new-file-name/
│   │   └── index.html
│   ├── previous-file-name/
│   │   └── index.html
│   └── index.html
└── index.html

​ 从旧的 URL 到新 URL 的别名是客户端重定向:

posts/previous-file-name/index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <title>https://example.org/posts/new-file-name/</title>
    <link rel="canonical" href="https://example.org/posts/new-file-name/">
    <meta name="robots" content="noindex">
    <meta charset="utf-8">
    <meta http-equiv="refresh" content="0; url=https://example.org/posts/new-file-name/">
  </head>
</html>

Collectively, the elements in the head section:

head 部分的元素总结如下:

  • 告诉搜索引擎新的 URL 是规范的(canonical)
  • 告诉搜索引擎不要索引旧的 URL
  • 告诉浏览器重定向到新的 URL

​ Hugo 在渲染页面之前渲染别名文件。带有先前文件名的新页面将覆盖别名,这是预期的。

自定义

​ 创建一个新的模板(layouts/alias.html)来自定义别名文件的内容。该模板接收以下上下文:

  • Permalink

    被别名的页面链接

  • Page

    被别名的页面的 Page 数据

另请参阅

5.18 - 菜单

Menus - 菜单

https://gohugo.io/content-management/menus/

​ 通过定义条目、本地化每个条目以及渲染结果数据结构来创建菜单。

概述

​ 要为您的站点创建菜单步骤如下:

  1. 定义菜单条目
  2. 本地化每个条目
  3. 使用模板渲染菜单

​ 创建多个菜单,可以是平面或嵌套的。例如,创建一个用于页眉的主菜单,以及一个用于页脚的单独菜单。

​ 有三种方法可以定义菜单条目:

  1. 自动定义
  2. 在前置元数据中定义
  3. 在站点配置中定义

​ 虽然可以在定义菜单时结合使用这些方法,但如果在整个站点中使用一种方法,则更容易理解和维护菜单。

自动定义

​ 要为站点的每个顶级章节自动定义菜单条目,请在站点配置中启用section pages menu。

config.

=== “yaml”

``` yaml
sectionPagesMenu: main

```

=== “toml”

``` toml
sectionPagesMenu = 'main'

```

=== “json”

``` json
{
   "sectionPagesMenu": "main"
}

```

​ 这将创建一个菜单结构,您可以在模板中使用 site.Menus.main 访问它。有关详细信息,请参阅菜单模板

在前置元数据中定义

​ 要将一个页面添加到"main"菜单中:

content/about.md

=== “yaml”

``` yaml
---
menu: main
title: About
---
```

=== “toml”

``` toml
+++
menu = 'main'
title = 'About'
+++
```

=== “json”

``` json
{
   "menu": "main",
   "title": "About"
}
```

​ 您可以在模板中使用 site.Menus.main 访问该条目。有关详细信息,请参阅菜单模板

​ 要将一个页面添加到"main"和"footer"菜单中:

content/contact.md

=== “yaml”

``` yaml
---
menu:
- main
- footer
title: Contact
---
```

=== “toml”

``` toml
+++
menu = ['main', 'footer']
title = 'Contact'
+++
```

=== “json”

``` json
{
   "menu": [
      "main",
      "footer"
   ],
   "title": "Contact"
}
```

​ 您可以在模板中使用 site.Menus.mainsite.Menus.footer 访问该条目。有关详细信息,请参阅菜单模板

属性

​ 在前置元数据中定义菜单条目时,请使用以下这些属性:

  • identifier

    string)当两个或多个菜单条目具有相同name或者使用翻译表(translation tables)本地化name时,必填。必须以字母开头,后跟字母、数字或下划线。

  • name

    string)在渲染该菜单条目时要显示的文本。

  • params

    map)该菜单条目的用户定义属性。

  • parent

    string)该父菜单条目的identifier。如果未定义identifier,请使用name。在嵌套菜单中的子菜单条目中必填。

  • post

    string)在渲染该菜单条目时追加的HTML。

  • pre

    string)在渲染该菜单条目时前置的HTML。

  • title

    string)被渲染的该菜单条目的HTML的title属性。

  • weight

    int)非零整数,表示该条目相对于菜单根的位置,或者表示子条目相对于其父级的位置。较轻的条目上浮到顶部,较重的条目下沉到底部。

示例

​ 此前置元数据菜单条目演示了一些可用属性:

content/products/software.md

=== “yaml”

``` yaml
---
menu:
  main:
    params:
      class: center
    parent: Products
    pre: <i class="fa-solid fa-code"></i>
    weight: 20
title: Software
---
```

=== “toml”

``` toml
+++
title = 'Software'
[menu]
  [menu.main]
    parent = 'Products'
    pre = '<i class="fa-solid fa-code"></i>'
    weight = 20
    [menu.main.params]
      class = 'center'
+++
```

=== “json”

``` json
{
   "menu": {
      "main": {
         "params": {
            "class": "center"
         },
         "parent": "Products",
         "pre": "\u003ci class=\"fa-solid fa-code\"\u003e\u003c/i\u003e",
         "weight": 20
      }
   },
   "title": "Software"
}
```

​ 在模板中使用site.Menus.main访问该条目。有关详细信息,请参见菜单模板

在站点配置中定义

​ 要定义"main"菜单的条目:

config.

=== “yaml”

``` yaml
menu:
  main:
  - name: Home
    pageRef: /
    weight: 10
  - name: Products
    pageRef: /products
    weight: 20
  - name: Services
    pageRef: /services
    weight: 30
```

=== “toml”

``` toml
[menu]
[[menu.main]]
  name = 'Home'
  pageRef = '/'
  weight = 10
[[menu.main]]
  name = 'Products'
  pageRef = '/products'
  weight = 20
[[menu.main]]
  name = 'Services'
  pageRef = '/services'
  weight = 30
```

=== “json”

``` json
{
   "menu": {
      "main": [
         {
            "name": "Home",
            "pageRef": "/",
            "weight": 10
         },
         {
            "name": "Products",
            "pageRef": "/products",
            "weight": 20
         },
         {
            "name": "Services",
            "pageRef": "/services",
            "weight": 30
         }
      ]
   }
}
```

​ 这将创建一个菜单结构,您可以在模板中使用site.Menus.main访问。有关详细信息,请参见菜单模板

​ 要定义"footer"菜单的条目:

config.

=== “yaml”

``` yaml
menu:
  footer:
  - name: Terms
    pageRef: /terms
    weight: 10
  - name: Privacy
    pageRef: /privacy
    weight: 20
```

=== “toml”

``` toml
[menu]
[[menu.footer]]
  name = 'Terms'
  pageRef = '/terms'
  weight = 10
[[menu.footer]]
  name = 'Privacy'
  pageRef = '/privacy'
  weight = 20
```

=== “json”

``` json
{
   "menu": {
      "footer": [
         {
            "name": "Terms",
            "pageRef": "/terms",
            "weight": 10
         },
         {
            "name": "Privacy",
            "pageRef": "/privacy",
            "weight": 20
         }
      ]
   }
}
```

​ 这将创建一个菜单结构,您可以在模板中使用site.Menus.footer访问。有关详细信息,请参见菜单模板

属性

在前置元数据中定义的条目可用的属性也适用于在站点配置中定义的条目。

​ 在站点配置中定义的每个菜单条目都需要两个或多个属性:

  • 为内部链接指定namepageRef

  • 为外部链接指定nameurl

  • pageRef

    string)目标页面的文件路径,相对于content目录。省略语言代码和文件扩展名。内部链接则必填。

KindpageRef
home/
page/books/book-1
section/books
taxonomy/tags
term/tags/foo
  • url

    string)外部链接则必填。

示例

​ 这个嵌套菜单演示了一些可用的属性:

config.

=== “yaml”

``` yaml
menu:
  main:
  - name: Products
    pageRef: /products
    weight: 10
  - name: Hardware
    pageRef: /products/hardware
    parent: Products
    weight: 1
  - name: Software
    pageRef: /products/software
    parent: Products
    weight: 2
  - name: Services
    pageRef: /services
    weight: 20
  - name: Hugo
    params:
      rel: external
    pre: <i class="fa fa-heart"></i>
    url: https://gohugo.io/
    weight: 30
```

=== “toml”

``` toml
[menu]
[[menu.main]]
  name = 'Products'
  pageRef = '/products'
  weight = 10
[[menu.main]]
  name = 'Hardware'
  pageRef = '/products/hardware'
  parent = 'Products'
  weight = 1
[[menu.main]]
  name = 'Software'
  pageRef = '/products/software'
  parent = 'Products'
  weight = 2
[[menu.main]]
  name = 'Services'
  pageRef = '/services'
  weight = 20
[[menu.main]]
  name = 'Hugo'
  pre = '<i class="fa fa-heart"></i>'
  url = 'https://gohugo.io/'
  weight = 30
  [menu.main.params]
    rel = 'external'
```

=== “json”

``` json
{
   "menu": {
      "main": [
         {
            "name": "Products",
            "pageRef": "/products",
            "weight": 10
         },
         {
            "name": "Hardware",
            "pageRef": "/products/hardware",
            "parent": "Products",
            "weight": 1
         },
         {
            "name": "Software",
            "pageRef": "/products/software",
            "parent": "Products",
            "weight": 2
         },
         {
            "name": "Services",
            "pageRef": "/services",
            "weight": 20
         },
         {
            "name": "Hugo",
            "params": {
               "rel": "external"
            },
            "pre": "\u003ci class=\"fa fa-heart\"\u003e\u003c/i\u003e",
            "url": "https://gohugo.io/",
            "weight": 30
         }
      ]
   }
}
```

​ 这将创建一个菜单结构,您可以在模板中使用 site.Menus.main 访问。有关详细信息,请参阅菜单模板

本地化

​ Hugo提供了两种方法来本地化菜单条目。请参阅多语言

渲染

​ 请参阅菜单模板

另请参阅

5.19 - 静态文件

Static Files - 静态文件

https://gohugo.io/content-management/static-files/

​ 这些文件以静态方式(原样、无修改)在站点根目录上提供服务。

​ 默认情况下,站点项目中的 static/ 目录用于所有静态文件(例如样式表、JavaScript、图像)。这些静态文件将在站点根路径上提供服务(例如,如果您有 static/image.png 文件,则可以使用 http://{server-url}/image.png 访问它,在文档中包含它可以使用![Example image](/image.png) )

​ Hugo 可以通过在站点配置中配置 staticDir 参数来查找不同的目录,甚至多个目录以获取这些静态文件。所有静态目录中的所有文件将组成一个联合文件系统。

​ 这个联合文件系统将从您的站点根目录提供服务。因此,<SITE PROJECT>/static/me.png 文件将作为 <MY_BASEURL>/me.png 文件访问。

​ 这里是一个为多语言站点设置 staticDirstaticDir2 的示例:

config.

=== “yaml”

``` yaml
languages:
  en:
    baseURL: https://example.com
    languageName: English
    staticDir2: static_en
    title: In English
    weight: 2
  "no":
    baseURL: https://example.no
    languageName: Norsk
    staticDir:
    - staticDir_override
    - static_no
    title: På norsk
    weight: 1
staticDir:
- static1
- static2
```

=== “toml”

``` toml
staticDir = ['static1', 'static2']
[languages]
  [languages.en]
    baseURL = 'https://example.com'
    languageName = 'English'
    staticDir2 = 'static_en'
    title = 'In English'
    weight = 2
  [languages.no]
    baseURL = 'https://example.no'
    languageName = 'Norsk'
    staticDir = ['staticDir_override', 'static_no']
    title = 'På norsk'
    weight = 1
```

=== “json”

``` json
{
   "languages": {
      "en": {
         "baseURL": "https://example.com",
         "languageName": "English",
         "staticDir2": "static_en",
         "title": "In English",
         "weight": 2
      },
      "no": {
         "baseURL": "https://example.no",
         "languageName": "Norsk",
         "staticDir": [
            "staticDir_override",
            "static_no"
         ],
         "title": "På norsk",
         "weight": 1
      }
   },
   "staticDir": [
      "static1",
      "static2"
   ]
}
```

​ 在上面的示例中,未使用任何主题:

  • 英文站点将其静态文件作为"static1"、“static2"和"static_en"的联合体。对于文件重复,右边的版本将获胜。

  • 挪威站点将其静态文件作为"staticDir_override"和"static_no"的联合体。

  • Note 1

    staticDir2 中的 2(可以是 0 到 10 的数字)被添加以告诉 Hugo 您想将此目录添加到使用 staticDir 定义的全局静态目录集合中。在语言级别上使用 staticDir 将替换全局值(如挪威站点案例所示)。

  • Note 2

    上面的示例是一个multihost设置。在常规设置中,所有静态目录将对所有站点都可用。

另请参阅

5.20 - 目录

Table of Contents - 目录

https://gohugo.io/content-management/toc/

​ Hugo可以自动解析Markdown内容并创建一个目录,您可以在模板中使用它。

​ 以前,没有开箱即用的方法来指定要渲染TOC的标题级别。请参见相关的GitHub讨论(#1778)。因此,从{{ .Content }}中提取时,生成的<nav id="TableOfContents"><ul></ul></nav>将从<h1>开始。

​ Hugo v0.60.0切换到了Goldmark作为Markdown的默认库,该库具有改进和可配置的TOC实现。请看如何为Goldmark渲染器配置TOC

用法

​ 以通常的标题方式创建您的Markdown。以下是一些示例内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!-- Your 前置元数据 up here -->

## Introduction

One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.

## My Heading

He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready to slide off any moment.

### My Subheading

A collection of textile samples lay spread out on the table - Samsa was a travelling salesman - and above it there hung a picture that he had recently cut out of an illustrated magazine and housed in a nice, gilded frame. It showed a lady fitted out with a fur hat and fur boa who sat upright, raising a heavy fur muff that covered the whole of her lower arm towards the viewer. Gregor then turned to look out the window at the dull weather. Drops

​ Hugo将从##Introduction##My Heading###My Subheading创建一个目录,然后将其存储在页面变量.TableOfContents中。

​ 内置的.TableOfContents变量输出一个带有子<ul>元素的<nav id="TableOfContents">,其子<li>元素以适当的HTML标题开头。请查看可用设置,以配置要在TOC中包含哪些标题级别。

模板示例:基本TOC

​ 以下是一个非常基本的单页面模板示例:

layout/_default/single.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{{ define "main" }}
<main>
    <article>
    <header>
        <h1>{{ .Title }}</h1>
    </header>
        {{ .Content }}
    </article>
    <aside>
        {{ .TableOfContents }}
    </aside>
</main>
{{ end }}

模板示例:TOC Partial

​ 以下是一个部分模板,它为页面级别控制目录添加了稍微更多的逻辑。它假定您在内容的前置元数据中使用toc字段,除非将其特别设置为false,否则会将TOC添加到具有大于400的.WordCount(请参见页面变量)的任何页面。此示例还演示了如何在模板中使用条件语句

layouts/partials/toc.html

1
2
3
4
5
6
7
8
{{ if and (gt .WordCount 400 ) (.Params.toc) }}
<aside>
    <header>
    <h2>{{ .Title }}</h2>
    </header>
    {{ .TableOfContents }}
</aside>
{{ end }}

​ 通过前面的示例,即使页面中有> 400个单词且toc未设置为false,如果页面中没有标题可以被{{ .TableOfContents }}变量提取,也不会渲染目录。

使用AsciiDoc

​ Hugo支持使用AsciiDoc内容格式的目录。

​ 在内容文件的头部,指定AsciiDoc TOC指令,以确保生成目录。Hugo将使用生成的TOC来填充页面变量.TableOfContents,方式与Markdown描述的相同。请参见以下示例:

// <!-- Your 前置元数据 up here -->
:toc:
// Set toclevels to be at least your hugo [markup.tableOfContents.endLevel] config key
:toclevels: 4

== Introduction

One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.

== My Heading

He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready to slide off any moment.

=== My Subheading

A collection of textile samples lay spread out on the table - Samsa was a travelling salesman - and above it there hung a picture that he had recently cut out of an illustrated magazine and housed in a nice, gilded frame. It showed a lady fitted out with a fur hat and fur boa who sat upright, raising a heavy fur muff that covered the whole of her lower arm towards the viewer. Gregor then turned to look out the window at the dull weather. Drops

​ Hugo将获取此AsciiDoc并创建目录,并将其存储在页面变量.TableOfContents中,与Markdown描述的相同。

另请参阅

5.21 - 评论

Comments - 评论

​ Hugo内置了Disqus模板,但这不是唯一能够与您的新Hugo站点配合使用的评论系统。

​ Hugo支持Disqus,这是一个第三方服务,通过JavaScript为站点提供评论和社区功能。

​ 您的主题可能已经支持Disqus,但如果没有,可以通过Hugo内置的Disqus partial轻松添加到您的模板中。

添加Disqus

​ Hugo已经为您的模板提供了加载Disqus所需的所有代码。在将Disqus添加到您的站点之前,您需要设置一个帐户

配置Disqus

​ Disqus评论要求您在站点的配置文件中设置单个值,如下所示:

=== “yaml”

``` yaml
disqusShortname: yourDisqusShortname

```

=== “toml”

``` toml
disqusShortname = 'yourDisqusShortname'

```

=== “json”

``` json
{
   "disqusShortname": "yourDisqusShortname"
}

```

​ 对于许多站点来说,这样的配置已经足够。但是,您还可以在单个内容文件的前置元数据中设置以下内容:

  • disqus_identifier
  • disqus_title
  • disqus_url

渲染Hugo内置的Disqus部分模板

​ Disqus有其自己的内部模板可用,要渲染它,请在要出现评论的位置添加以下代码:

1
{{ template "_internal/disqus.html" . }}

替代方案

以下是Disqus的一些替代方案:

另请参阅

5.22 - 多语言模式

Multilingual Mode - 多语言模式

https://gohugo.io/content-management/multilingual/

​ Hugo支持创建并排展示多种语言的站点。

​ 您应该在站点配置中的languages部分定义可用的语言。

​ 另请参阅Hugo多语言第一部分:内容翻译

配置语言

​ 以下是多语言Hugo项目的站点配置示例:

config.

=== “yaml”

``` yaml
copyright: Everything is mine
defaultContentLanguage: en
languages:
  ar:
    languagedirection: rtl
    title: مدونتي
    weight: 2
  en:
    params:
      linkedin: https://linkedin.com/whoever
    title: My blog
    weight: 1
  fr:
    params:
      linkedin: https://linkedin.com/fr/whoever
      navigation:
        help: Aide
    title: Mon blogue
    weight: 2
  pt-pt:
    title: O meu blog
    weight: 3
params:
  navigation:
    help: Help
```

=== “toml”

``` toml
copyright = 'Everything is mine'
defaultContentLanguage = 'en'
[languages]
  [languages.ar]
    languagedirection = 'rtl'
    title = 'مدونتي'
    weight = 2
  [languages.en]
    title = 'My blog'
    weight = 1
    [languages.en.params]
      linkedin = 'https://linkedin.com/whoever'
  [languages.fr]
    title = 'Mon blogue'
    weight = 2
    [languages.fr.params]
      linkedin = 'https://linkedin.com/fr/whoever'
      [languages.fr.params.navigation]
        help = 'Aide'
  [languages.pt-pt]
    title = 'O meu blog'
    weight = 3
[params]
  [params.navigation]
    help = 'Help'
```

=== “json”

``` json
{
   "copyright": "Everything is mine",
   "defaultContentLanguage": "en",
   "languages": {
      "ar": {
         "languagedirection": "rtl",
         "title": "مدونتي",
         "weight": 2
      },
      "en": {
         "params": {
            "linkedin": "https://linkedin.com/whoever"
         },
         "title": "My blog",
         "weight": 1
      },
      "fr": {
         "params": {
            "linkedin": "https://linkedin.com/fr/whoever",
            "navigation": {
               "help": "Aide"
            }
         },
         "title": "Mon blogue",
         "weight": 2
      },
      "pt-pt": {
         "title": "O meu blog",
         "weight": 3
      }
   },
   "params": {
      "navigation": {
         "help": "Help"
      }
   }
}
```

​ 任何未在languages块中定义的内容都将回退到该键的全局值(例如英语en语言的copyright)。这也适用于params,如上面的示例所示:您将在法语中获得Aide的值,并在所有没有设置此参数的语言中获得Help

​ 使用上述配置,所有内容、站点地图、RSS源、分页和分类页将在英语(默认内容语言)下的/目录下渲染,然后在法语的/fr目录下渲染。

​ 在单页模板中使用前置元数据 Params时,忽略翻译的键中的params

defaultContentLanguage设置项目的默认语言。如果未设置,则默认语言为en

​ 如果需要将默认语言渲染在其自己的语言代码(/en)下,像其他语言一样,请设置defaultContentLanguageInSubdir:true

​ 只有明显的非全局选项可以按语言覆盖。全局选项的示例包括baseURLbuildDrafts等。

请注意:使用小写语言代码,即使是使用区域性语言(例如使用pt-pt而不是pt-PT)。当前Hugo语言内部将语言代码转换为小写字母,这可能会与未转换为小写字母的defaultContentLanguage等设置发生冲突。请在Hugo存储库问题跟踪器中跟踪此问题的演变。

禁用语言

​ 您可以禁用一个或多个语言。这在进行新翻译时非常有用。

config.

=== “yaml”

``` yaml
disableLanguages:
- fr
- ja
```

=== “toml”

``` toml
disableLanguages = ['fr', 'ja']
```

=== “json”

``` json
{
   "disableLanguages": [
      "fr",
      "ja"
   ]
}
```

​ 请注意,您不能禁用默认内容语言。

​ 我们将其保留为一个独立的设置,以便更容易通过操作系统环境进行设置:

1
HUGO_DISABLELANGUAGES="fr ja" hugo

​ 如果您已经在config.toml中有禁用的语言列表,可以像这样在开发环境中启用它们:

1
HUGO_DISABLELANGUAGES=" " hugo server

配置多语言Multihost

​ 从Hugo 0.31开始,我们支持多语言multihost配置。详见此问题的说明。

​ 这意味着现在可以为每种language配置一个baseURL

如果在language级别上设置了 baseURL,则所有语言都必须具有一个,且它们必须全部不同。

例如:

config.

=== “yaml”

``` yaml
languages:
  en:
    baseURL: https://example.com
    languageName: English
    title: In English
    weight: 2
  fr:
    baseURL: https://example.fr
    languageName: Français
    title: En Français
    weight: 1
```

=== “toml”

``` toml
[languages]
  [languages.en]
    baseURL = 'https://example.com'
    languageName = 'English'
    title = 'In English'
    weight = 2
  [languages.fr]
    baseURL = 'https://example.fr'
    languageName = 'Français'
    title = 'En Français'
    weight = 1
```

=== “json”

``` json
{
   "languages": {
      "en": {
         "baseURL": "https://example.com",
         "languageName": "English",
         "title": "In English",
         "weight": 2
      },
      "fr": {
         "baseURL": "https://example.fr",
         "languageName": "Français",
         "title": "En Français",
         "weight": 1
      }
   }
}
```

​ 有了上面的配置,这两个站点将生成到带有自己根目录的 public 中:

1
2
3
public
├── en
└── fr

​ 所有的URL(例如.Permalink等)都将从该根目录生成。因此,上面的英文主页的.Permalink将设置为https://example.com/。

​ 当您运行hugo server时,我们将启动多个HTTP服务器。您通常会在控制台中看到以下内容:

1
2
3
Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1)
Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1)
Press Ctrl+C to stop

​ 实时重新加载和在服务器之间使用--navigateToChanged会按预期工作。

翻译您的内容

​ 有两种管理内容翻译的方式。两种方式都可以确保每个页面都被分配了一种语言,并与其对应的翻译链接在一起。

按文件名翻译

​ 考虑以下示例:

  1. /content/about.en.md
  2. /content/about.fr.md

​ 第一个文件分配了英语语言,并链接到第二个文件。第二个文件分配了法语语言,并链接到第一个文件。

​ 它们的语言是根据文件名后缀添加的语言代码分配的。

​ 通过具有相同的路径和基本文件名,将内容部分链接在一起作为翻译页面。

​ 如果文件没有语言代码,它将被分配为默认语言。

按内容目录翻译

​ 该系统使用不同的内容目录来处理每种语言。每种语言的内容目录都是使用 contentDir 参数设置的。

config.

=== “yaml”

``` yaml
languages:
  en:
    contentDir: content/english
    languageName: English
    weight: 10
  fr:
    contentDir: content/french
    languageName: Français
    weight: 20
```

=== “toml”

``` toml
[languages]
  [languages.en]
    contentDir = 'content/english'
    languageName = 'English'
    weight = 10
  [languages.fr]
    contentDir = 'content/french'
    languageName = 'Français'
    weight = 20
```

=== “json”

``` json
{
   "languages": {
      "en": {
         "contentDir": "content/english",
         "languageName": "English",
         "weight": 10
      },
      "fr": {
         "contentDir": "content/french",
         "languageName": "Français",
         "weight": 20
      }
   }
}
```

contentDir 的值可以是任何有效的路径,甚至是绝对路径引用。唯一的限制是内容目录不能重叠。

​ 考虑以下示例与上述配置一起使用:

  1. /content/english/about.md
  2. /content/french/about.md

​ 第一个文件被分配为英语,并与第二个文件链接。第二个文件被分配为法语,并与第一个文件链接。

​ 它们的语言是根据它们放置所在的内容目录分配的。

​ 通过具有相同的路径和基名(相对于其语言内容目录),内容片段将作为翻译页面相互链接。

绕过默认链接

​ 任何在前置元数据中设置相同翻译键(translationKey)的页面将被链接为翻译页面,而不考虑基名或位置。

​ 考虑以下示例:

  1. /content/about-us.en.md
  2. /content/om.nn.md
  3. /content/presentation/a-propos.fr.md

=== “yaml”

``` yaml
translationKey: about
```

=== “toml”

``` toml
translationKey = 'about'
```

=== “json”

``` json
{
   "translationKey": "about"
}
```

​ 通过在所有三个页面的前置元数据参数中设置翻译键(translationKey)为 about,它们将被链接为翻译页面。

本地化永久链接

​ 因为路径和文件名用于处理链接,所有翻译页面将共享相同的URL(除了语言子目录)。

​ 为了本地化URL:

  • 对于常规页面,在前置元数据中设置slugurl
  • 对于章节页面,在前置元数据中设置url

​ 例如,法语翻译可以有自己本地化的slug

content/about.fr.md

=== “yaml”

``` yaml
---
slug: a-propos
title: A Propos
---
```

=== “toml”

``` toml
+++
slug = 'a-propos'
title = 'A Propos'
+++
```

=== “json”

``` json
{
   "slug": "a-propos",
   "title": "A Propos"
}
```

At render, Hugo will build both /about/ and /fr/a-propos/ without affecting the translation link.

​ 在渲染时,Hugo将同时构建/about//fr/a-propos/,而不影响翻译链接。

页面 Bundles

To avoid the burden of having to duplicate files, each Page Bundle inherits the resources of its linked translated pages’ bundles except for the content files (Markdown files, HTML files etc…).

为了避免重复文件的负担,每个页面包继承其链接的翻译页面包的资源,除了内容文件(Markdown文件,HTML文件等)。

Therefore, from within a template, the page will have access to the files from all linked pages’ bundles.

因此,在模板内,页面将可以访问所有链接页面包的文件。

If, across the linked bundles, two or more files share the same basename, only one will be included and chosen as follows:

如果在链接的包中,两个或多个文件具有相同的基名,则只包括一个,并按以下方式选择:

  • File from current language bundle, if present.
  • 当前语言包中的文件(如果存在)。
  • First file found across bundles by order of language Weight.
  • 按语言权重顺序在所有包中找到的第一个文件。

Page Bundle resources follow the same language assignment logic as content files, both by filename (image.jpg, image.fr.jpg) and by directory (english/about/header.jpg, french/about/header.jpg).

页面包资源遵循与内容文件相同的语言分配逻辑,包括文件名(image.jpg,image.fr.jpg)和目录(english/about/header.jpg,french/about/header.jpg)。

引用翻译内容

To create a list of links to translated content, use a template similar to the following:

要创建链接到翻译内容的链接列表,请使用类似以下的模板:

layouts/partials/i18nlist.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{{ if .IsTranslated }}
<h4>{{ i18n "translations" }}</h4>
<ul>
  {{ range .Translations }}
  <li>
    <a href="{{ .Permalink }}">{{ .Lang }}: {{ .Title }}{{ if .IsPage }} ({{ i18n "wordCount" . }}){{ end }}</a>
  </li>
  {{ end }}
</ul>
{{ end }}

The above can be put in a partial (i.e., inside layouts/partials/) and included in any template, whether a single content page or the homepage. It will not print anything if there are no translations for a given page.

上述内容可以放在partial中(即layouts/partials/文件夹中),并包含在任何模板中,无论是单个内容页面还是主页。如果没有给定页面的翻译,它将不会打印任何内容。

The above also uses the i18n function described in the next section.

上述内容还使用了下一节中描述的i18n函数。

列出所有可用语言

.AllTranslations on a Page can be used to list all translations, including the page itself. On the home page it can be used to build a language navigator:

在页面上使用.AllTranslations可以列出所有翻译,包括页面本身。在主页上,它可用于构建语言导航器:

layouts/partials/allLanguages.html

1
2
3
4
5
<ul>
{{ range $.Site.Home.AllTranslations }}
<li><a href="{{ .Permalink }}">{{ .Language.LanguageName }}</a></li>
{{ end }}
</ul>

字符串翻译

Hugo uses go-i18n to support string translations. See the project’s source repository to find tools that will help you manage your translation workflows.

Hugo使用go-i18n支持字符串翻译。请参见该项目的源存储库,以查找可帮助您管理翻译工作流程的工具。

Translations are collected from the themes/<THEME>/i18n/ folder (built into the theme), as well as translations present in i18n/ at the root of your project. In the i18n, the translations will be merged and take precedence over what is in the theme folder. Language files should be named according to RFC 5646 with names such as en-US.toml, fr.toml, etc.

从themes//i18n/文件夹(内置于主题中)以及位于项目根目录的i18n/文件夹中收集翻译。在i18n中,翻译将合并并优先于主题文件夹中的内容。语言文件应根据RFC 5646命名,例如en-US.toml、fr.toml等。

Artificial languages with private use subtags as defined in RFC 5646 § 2.2.7 are also supported. You may omit the art-x- prefix for brevity. For example:

RFC 5646§2.2.7中定义的带有私有使用子标记的人工语言也受支持。为简洁起见,您可以省略art-x-前缀。例如:

1
2
art-x-hugolang
hugolang

Private use subtags must not exceed 8 alphanumeric characters.

私有使用子标记不得超过8个字母数字字符。

查询基本翻译

From within your templates, use the i18n function like this:

在您的模板中,可以像这样使用i18n函数:

1
{{ i18n "home" }}

The function will search for the "home" id:

该函数将搜索"home"id:

i18n/en-US.

=== “yaml”

``` yaml
home:
  other: Home
```

=== “toml”

``` toml
[home]
  other = 'Home'
```

=== “json”

``` json
{
   "home": {
      "other": "Home"
   }
}
```

The result will be

结果将是

1
Home

查询带有变量的灵活翻译

Often you will want to use the page variables in the translation strings. To do so, pass the . context when calling i18n:

通常,您会想在翻译字符串中使用页面变量。要这样做,请在调用i18n时传递上下文。

1
{{ i18n "wordCount" . }}

The function will pass the . context to the "wordCount" id:

该函数将把上下文传递给"wordCount"id:

i18n/en-US.

=== “yaml”

``` yaml
wordCount:
  other: This article has {{ .WordCount }} words.
```

=== “toml”

``` toml
[wordCount]
  other = 'This article has {{ .WordCount }} words.'
```

=== “json”

``` json
{
   "wordCount": {
      "other": "This article has {{ .WordCount }} words."
   }
}
```

Assume .WordCount in the context has value is 101. The result will be:

假设上下文中的 .WordCount 值为 101。结果将是:

1
This article has 101 words.

查询单数/复数翻译

In other to meet singular/plural requirement, you must pass a dictionary (map) with a numeric .Count property to the i18n function. The below example uses .ReadingTime variable which has a built-in .Count property.

为了满足单数/复数要求,您必须将具有数字 .Count 属性的字典(map)传递给 i18n 函数。下面的示例使用内置的 .ReadingTime 变量,它具有一个 .Count 属性。

1
{{ i18n "readingTime" .ReadingTime }}

The function will read .Count from .ReadingTime and evaluate whether the number is singular (one) or plural (other). After that, it will pass to readingTime id in i18n/en-US.toml file:

函数将从 .ReadingTime 中读取 .Count 并评估数字是单数(one)还是复数(other)。之后,它将传递给 i18n/en-US.toml 文件中的 readingTime id:

i18n/en-US.

=== “yaml”

``` yaml
readingTime:
  one: One minute to read
  other: '{{ .Count }} minutes to read'
```

=== “toml”

``` toml
[readingTime]
  one = 'One minute to read'
  other = '{{ .Count }} minutes to read'
```

=== “json”

``` json
{
   "readingTime": {
      "one": "One minute to read",
      "other": "{{ .Count }} minutes to read"
   }
}
```

Assuming .ReadingTime.Count in the context has value is 525600. The result will be:

假设上下文中的 .ReadingTime.Count 值为 525600。结果将是:

1
525600 minutes to read

If .ReadingTime.Count in the context has value is 1. The result is:

如果上下文中的 .ReadingTime.Count 值为1。结果是:

1
One minute to read

In case you need to pass a custom data: ((dict "Count" numeric_value_only) is minimum requirement)

如果您需要传递自定义数据:((dict “Count” numeric_value_only) 是最小要求)

1
{{ i18n "readingTime" (dict "Count" 25 "FirstArgument" true "SecondArgument" false "Etc" "so on, so far") }}

本地化

The following localization examples assume your site’s primary language is English, with translations to French and German.

以下本地化示例假定您站点的主要语言为英语,并提供了法语和德语的翻译。

config.

=== “yaml”

``` yaml
defaultContentLanguage: en
languages:
  de:
    contentDir: content/de
    languageName: Deutsch
    weight: 3
  en:
    contentDir: content/en
    languageName: English
    weight: 1
  fr:
    contentDir: content/fr
    languageName: Français
    weight: 2
```

=== “toml”

``` toml
defaultContentLanguage = 'en'
[languages]
  [languages.de]
    contentDir = 'content/de'
    languageName = 'Deutsch'
    weight = 3
  [languages.en]
    contentDir = 'content/en'
    languageName = 'English'
    weight = 1
  [languages.fr]
    contentDir = 'content/fr'
    languageName = 'Français'
    weight = 2
```

=== “json”

``` json
{
   "defaultContentLanguage": "en",
   "languages": {
      "de": {
         "contentDir": "content/de",
         "languageName": "Deutsch",
         "weight": 3
      },
      "en": {
         "contentDir": "content/en",
         "languageName": "English",
         "weight": 1
      },
      "fr": {
         "contentDir": "content/fr",
         "languageName": "Français",
         "weight": 2
      }
   }
}
```

日期

With this 前置元数据:

有了这个前置元数据:

=== “yaml”

``` yaml
date: 2021-11-03T12:34:56+01:00
```

=== “toml”

``` toml
date = 2021-11-03T12:34:56+01:00
```

=== “json”

``` json
{
   "date": "2021-11-03T12:34:56+01:00"
}
```

And this template code:

以及这个模板代码:

1
{{ .Date | time.Format ":date_full" }}

The rendered page displays:

渲染的页面显示:

LanguageValue
EnglishWednesday, November 3, 2021
Françaismercredi 3 novembre 2021
DeutschMittwoch, 3. November 2021

See time.Format for details.

​ 详细信息请参见time.Format

货币 Currency

With this template code:

使用此模板代码:

1
{{ 512.5032 | lang.FormatCurrency 2 "USD" }}

The rendered page displays:

渲染的页面显示:

LanguageValue
English$512.50
Français512,50 $US
Deutsch512,50 $

See lang.FormatCurrency and lang.FormatAccounting for details.

数字

With this template code:

使用此模板代码:

1
{{ 512.5032 | lang.FormatNumber 2 }}

The rendered page displays:

渲染的页面显示:

LanguageValue
English512.50
Français512,50
Deutsch512,50

See lang.FormatNumber and lang.FormatNumberCustom for details.

请参考lang.FormatNumber和lang.FormatNumberCustom了解详情。

百分数

With this template code:

使用此模板代码:

1
{{ 512.5032 | lang.FormatPercent 2 }} ---> 512.50%

The rendered page displays:

渲染的页面显示:

LanguageValue
English512.50%
Français512,50 %
Deutsch512,50 %

See lang.FormatPercent for details.

请参考lang.FormatPercent了解详情。

菜单

Localization of menu entries depends on the how you define them:

菜单项的本地化取决于定义它们的方式:

  • When you define menu entries automatically using the section pages menu, you must use translation tables to localize each entry.
  • 当您使用部分页面菜单自动定义菜单项时,您必须使用翻译表来本地化每个菜单项。
  • When you define menu entries in 前置元数据, they are already localized based on the 前置元数据 itself. If the 前置元数据 values are insufficient, use translation tables to localize each entry.
  • 当您在前置matter中定义菜单项时,它们已经基于前置matter本身进行了本地化。如果前置matter值不足,请使用翻译表来本地化每个菜单项。
  • When you define menu entries in site configuration, you can (a) use translation tables, or (b) create language-specific menu entries under each language key.
  • 当您在站点配置中定义菜单项时,您可以(a)使用翻译表,或(b)在每个语言键下创建特定于语言的菜单项。

使用翻译表

When rendering the text that appears in menu each entry, the example menu template does this:

在渲染出现在菜单中的文本时,示例菜单模板执行以下操作:

1
{{ or (T .Identifier) .Name | safeHTML }}

It queries the translation table for the current language using the menu entry’s identifier and returns the translated string. If the translation table does not exist, or if the identifier key is not present in the translation table, it falls back to name.

它使用菜单项的标识符查询当前语言的翻译表,并返回已翻译的字符串。如果翻译表不存在,或者标识符键不在翻译表中,则回退到名称。

The identifier depends on how you define menu entries:

标识符取决于您如何定义菜单项:

  • If you define the menu entry automatically using the section pages menu, the identifier is the page’s .Section.
  • 如果您使用部分页面菜单自动定义菜单项,则标识符是页面的.Section。
  • If you define the menu entry in site configuration or in 前置元数据, set the identifier property to the desired value.
  • 如果您在站点配置或前置matter中定义菜单项,请将标识符属性设置为所需值。

For example, if you define menu entries in site configuration:

例如,如果您在站点配置中定义菜单项:

config.

=== “yaml”

``` yaml
menu:
  main:
  - identifier: products
    name: Products
    pageRef: /products
    weight: 10
  - identifier: services
    name: Services
    pageRef: /services
    weight: 20
```

=== “toml”

``` toml
[menu]
[[menu.main]]
  identifier = 'products'
  name = 'Products'
  pageRef = '/products'
  weight = 10
[[menu.main]]
  identifier = 'services'
  name = 'Services'
  pageRef = '/services'
  weight = 20
```

=== “json”

``` json
{
   "menu": {
      "main": [
         {
            "identifier": "products",
            "name": "Products",
            "pageRef": "/products",
            "weight": 10
         },
         {
            "identifier": "services",
            "name": "Services",
            "pageRef": "/services",
            "weight": 20
         }
      ]
   }
}
```

Create corresponding entries in the translation tables:

创建相应的翻译表条目:

i18n/de.

=== “yaml”

``` yaml
products: Produkte
services: Leistungen
```

=== “toml”

``` toml
products = 'Produkte'
services = 'Leistungen'
```

=== “json”

``` json
{
   "products": "Produkte",
   "services": "Leistungen"
}
```

创建语言特定的菜单条目

例如:

config.

=== “yaml”

``` yaml
languages:
  de:
    languageCode: de-DE
    languageName: Deutsch
    menu:
      main:
      - name: Produkte
        pageRef: /products
        weight: 10
      - name: Leistungen
        pageRef: /services
        weight: 20
    weight: 1
  en:
    languageCode: en-US
    languageName: English
    menu:
      main:
      - name: Products
        pageRef: /products
        weight: 10
      - name: Services
        pageRef: /services
        weight: 20
    weight: 2
```

=== “toml”

``` toml
[languages]
  [languages.de]
    languageCode = 'de-DE'
    languageName = 'Deutsch'
    weight = 1
    [languages.de.menu]
[[languages.de.menu.main]]
      name = 'Produkte'
      pageRef = '/products'
      weight = 10
[[languages.de.menu.main]]
      name = 'Leistungen'
      pageRef = '/services'
      weight = 20
  [languages.en]
    languageCode = 'en-US'
    languageName = 'English'
    weight = 2
    [languages.en.menu]
[[languages.en.menu.main]]
      name = 'Products'
      pageRef = '/products'
      weight = 10
[[languages.en.menu.main]]
      name = 'Services'
      pageRef = '/services'
      weight = 20
```

=== “json”

``` json
{
   "languages": {
      "de": {
         "languageCode": "de-DE",
         "languageName": "Deutsch",
         "menu": {
            "main": [
               {
                  "name": "Produkte",
                  "pageRef": "/products",
                  "weight": 10
               },
               {
                  "name": "Leistungen",
                  "pageRef": "/services",
                  "weight": 20
               }
            ]
         },
         "weight": 1
      },
      "en": {
         "languageCode": "en-US",
         "languageName": "English",
         "menu": {
            "main": [
               {
                  "name": "Products",
                  "pageRef": "/products",
                  "weight": 10
               },
               {
                  "name": "Services",
                  "pageRef": "/services",
                  "weight": 20
               }
            ]
         },
         "weight": 2
      }
   }
}
```

For a simple menu with two languages, these menu entries are easy to create and maintain. For a larger menu, or with more than two languages, using translation tables as described above is preferable.

对于只包含两种语言的简单菜单,这些菜单条目易于创建和维护。对于更大的菜单或包含两种以上语言的菜单,最好使用上述描述的翻译表。

缺少翻译

If a string does not have a translation for the current language, Hugo will use the value from the default language. If no default value is set, an empty string will be shown.

如果一个字符串在当前语言下没有翻译,Hugo 将使用默认语言的值。如果没有设置默认值,则显示为空字符串。

While translating a Hugo website, it can be handy to have a visual indicator of missing translations. The enableMissingTranslationPlaceholders configuration option will flag all untranslated strings with the placeholder [i18n] identifier, where identifier is the id of the missing translation.

在翻译 Hugo 站点时,有一个缺少翻译的可视化指示器会很方便。启用 enableMissingTranslationPlaceholders 配置选项会使用 [i18n] 占位符标记所有未翻译的字符串,其中 identifier 是缺失翻译的 id。

Hugo will generate your website with these missing translation placeholders. It might not be suitable for production environments.

Hugo 将生成带有这些缺失翻译占位符的站点。这可能不适合生产环境。

For merging of content from other languages (i.e. missing content translations), see lang.Merge.

要合并其他语言的内容(即缺失的内容翻译),请参阅 lang.Merge。

To track down missing translation strings, run Hugo with the --printI18nWarnings flag:

要追踪缺失的翻译字符串,请使用 –printI18nWarnings 标志运行 Hugo:

1
2
hugo --printI18nWarnings | grep i18n
i18n|MISSING_TRANSLATION|en|wordCount

多语言主题支持

To support Multilingual mode in your themes, some considerations must be taken for the URLs in the templates. If there is more than one language, URLs must meet the following criteria:

要在主题中支持多语言模式,必须在模板中考虑 URL。如果有多种语言,则 URL 必须符合以下标准:

  • Come from the built-in .Permalink or .RelPermalink
  • 来自内置的 .Permalink 或 .RelPermalink
  • Be constructed with the relLangURL template function or the absLangURL template function OR be prefixed with {{ .LanguagePrefix }}
  • 使用 relLangURL 模板函数或 absLangURL 模板函数构造 URL,或在 URL 前加上 {{.LanguagePrefix}}

If there is more than one language defined, the LanguagePrefix variable will equal /en (or whatever your CurrentLanguage is). If not enabled, it will be an empty string (and is therefore harmless for single-language Hugo websites).

如果定义了多种语言,则 LanguagePrefix 变量将等于 /en(或您的 CurrentLanguage),如果未启用,则为空字符串(对于单语言 Hugo 站点是无害的)。

使用 hugo new 生成多语言内容

If you organize content with translations in the same directory:

如果您将内容与翻译组织在同一个目录中:

1
2
hugo new post/test.en.md
hugo new post/test.de.md

If you organize content with translations in different directories:

如果您将翻译后的内容组织在不同的目录中:

1
2
hugo new content/en/post/test.md
hugo new content/de/post/test.md

另请参阅

5.23 - 语法高亮

Syntax Highlighting- 语法高亮

https://gohugo.io/content-management/syntax-highlighting/

​ Hugo 使用来自 Chroma 的非常快速的语法高亮功能。

​ Hugo 使用 Chroma作为其代码高亮器;它是使用 Go 构建的,非常非常快。

配置语法高亮器

​ 参见 配置高亮

生成语法高亮器 CSS

​ 如果在站点配置中运行时使用了 markup.highlight.noClasses=false,则需要一个样式表。

​ 您可以使用Hugo生成样式表:

1
hugo gen chromastyles --style=monokai > syntax.css

​ 运行hugo gen chromastyles -h以获取更多选项。请参阅https://xyproto.github.io/splash/docs/以获取可用样式的库。

高亮简码

​ 通过内置的highlight shortcode进行高亮显示。它需要一个必需的参数来指定编程语言,并需要一个闭合shortcode。

选项:

  • linenos:配置行号。有效值为 truefalsetableinline。如果在站点配置中配置了行号,则 false 将关闭行号。table 将提供可复制和粘贴的代码块。
  • hl_lines:列出要高亮显示的一组行号或行号范围。
  • linenostart=199:从 199 开始计数行号。
  • anchorlinenos:配置行号上的锚点。有效值为 truefalse
  • lineanchors:为行号配置前缀。将添加后缀-,因此在选项lineanchors=prefix下将第1行链接到页面时,将向页面添加锚prefix-1
  • hl_inline<code>(内联 HTML 元素)标记内部进行高亮。有效值为 truefalsecode 标记将获得一个名为 code-inline 的类。v0.101.0 中新增

示例:Highlight Shortcode

1
2
3
\{\{\< highlight go "linenos=table,hl_lines=8 15-17,linenostart=199" \>\}\}
// ... code
\{\{\< / highlight \>\}\}

得到的结果如下:

image-20230424182105273

高亮 Hugo/GO 模板代码

​ 为了在页面上突出显示Hugo/GO模板代码,在双大括号的开头添加/*,在右大括号前添加*/

1
\{\{\</* myshortcode */\>\}\}

得到的结果如下:

1
\{\{\< myshortcode \>\}\}

高亮模板函数

​ 请参见Highlight

Highlighting in Code Fences

​ 默认情况下,代码框中的高亮显示已启用。

1
2
3
```go {linenos=table,hl_lines=[8,"15-17"],linenostart=199}
// ... code
```

得到的结果如下:

image-20230424182105273

​ 这些选项与高亮简码中的选项相同,包括 linenos=false,但请注意略有不同的 Markdown 属性语法。

Chroma 高亮显示语言列表

​ 以下是Chroma词法分析器及其别名的完整列表(这些别名是在highlight模板函数或在代码框中使用的标识符):

  • ABAP

    abap

  • ABNF

    abnf

  • ActionScript

    as, actionscript

  • ActionScript 3

    as3, actionscript3

  • Ada

    ada, ada95, ada2005

  • AL

    al

  • Angular2

    ng2

  • ANTLR

    antlr

  • ApacheConf

    apacheconf, aconf, apache

  • APL

    apl

  • AppleScript

    applescript

  • Arduino

    arduino

  • ArmAsm

    armasm

  • Awk

    awk, gawk, mawk, nawk

  • Ballerina

    ballerina

  • Bash

    bash, sh, ksh, zsh, shell

  • BashSession

    bash-session, console, shell-session

  • Batchfile

    bat, batch, dosbatch, winbatch

  • BibTeX

    bib, bibtex

  • Bicep

    bicep

  • BlitzBasic

    blitzbasic, b3d, bplus

  • BNF

    bnf

  • BQN

    bqn

  • Brainfuck

    brainfuck, bf

  • C

    c

  • C#

    csharp, c#

  • C++

    cpp, c++

  • Caddyfile

    caddyfile, caddy

  • Caddyfile Directives

    caddyfile-directives, caddyfile-d, caddy-d

  • Cap’n Proto

    capnp

  • Cassandra CQL

    cassandra, cql

  • Ceylon

    ceylon

  • CFEngine3

    cfengine3, cf3

  • cfstatement

    cfs

  • ChaiScript

    chai, chaiscript

  • Chapel

    chapel, chpl

  • Cheetah

    cheetah, spitfire

  • Clojure

    clojure, clj

  • CMake

    cmake

  • COBOL

    cobol

  • CoffeeScript

    coffee-script, coffeescript, coffee

  • Common Lisp

    common-lisp, cl, lisp

  • Common Lisp

    common-lisp, cl, lisp

  • Coq

    coq

  • Crystal

    cr, crystal

  • CSS

    css

  • Cython

    cython, pyx, pyrex

  • D

    d

  • Dart

    dart

  • Diff

    diff, udiff

  • Django/Jinja

    django, jinja

  • dns

    zone, bind

  • Docker

    docker, dockerfile

  • DTD

    dtd

  • Dylan

    dylan

  • EBNF

    ebnf

  • Elixir

    elixir, ex, exs

  • Elm

    elm

  • EmacsLisp

    emacs, elisp, emacs-lisp

  • EmacsLisp

    emacs, elisp, emacs-lisp

  • Erlang

    erlang

  • Factor

    factor

  • Fennel

    fennel, fnl

  • Fish

    fish, fishshell

  • Forth

    forth

  • Fortran

    fortran, f90

  • FortranFixed

    fortranfixed

  • FSharp

    fsharp

  • GAS

    gas, asm

  • GDScript

    gdscript, gd

  • Genshi

    genshi, kid, xml+genshi, xml+kid

  • Genshi HTML

    html+genshi, html+kid

  • Genshi Text

    genshitext

  • Gherkin

    cucumber, Cucumber, gherkin, Gherkin

  • GLSL

    glsl

  • Gnuplot

    gnuplot

  • Go

    go, golang

  • Go HTML Template

    go-html-template

  • Go HTML Template

    go-html-template

  • Go Text Template

    go-text-template

  • GraphQL

    graphql, graphqls, gql

  • Groff

    groff, nroff, man

  • Groovy

    groovy

  • Handlebars

    handlebars, hbs

  • Haskell

    haskell, hs

  • Haxe

    hx, haxe, hxsl

  • HCL

    hcl

  • Hexdump

    hexdump

  • HLB

    hlb

  • HLSL

    hlsl

  • HTML

    html

  • HTTP

    http

  • Hy

    hylang

  • Idris

    idris, idr

  • Igor

    igor, igorpro

  • INI

    ini, cfg, dosini

  • Io

    io

  • J

    j

  • Java

    java

  • JavaScript

    js, javascript

  • JSON

    json

  • Julia

    julia, jl

  • Jungle

    jungle

  • Kotlin

    kotlin

  • Lighttpd configuration file

    lighty, lighttpd

  • LLVM

    llvm

  • Lua

    lua

  • Makefile

    make, makefile, mf, bsdmake

  • Mako

    mako

  • markdown

    md, mkd

  • Mason

    mason

  • Mathematica

    mathematica, mma, nb

  • Matlab

    matlab

  • mcfunction

    mcfunction

  • Meson

    meson, meson.build

  • Metal

    metal

  • MiniZinc

    minizinc, MZN, mzn

  • MLIR

    mlir

  • Modula-2

    modula2, m2

  • MonkeyC

    monkeyc

  • MorrowindScript

    morrowind, mwscript

  • Myghty

    myghty

  • MySQL

    mysql, mariadb

  • NASM

    nasm

  • Newspeak

    newspeak

  • Nginx configuration file

    nginx

  • Nim

    nim, nimrod

  • Nix

    nixos, nix

  • Objective-C

    objective-c, objectivec, obj-c, objc

  • OCaml

    ocaml

  • Octave

    octave

  • OnesEnterprise

    ones, onesenterprise, 1S, 1S:Enterprise

  • OpenEdge ABL

    openedge, abl, progress, openedgeabl

  • OpenSCAD

    openscad

  • Org Mode

    org, orgmode

  • PacmanConf

    pacmanconf

  • Perl

    perl, pl

  • PHP

    php, php3, php4, php5

  • PHTML

    phtml

  • Pig

    pig

  • PkgConfig

    pkgconfig

  • PL/pgSQL

    plpgsql

  • plaintext

    text, plain, no-highlight

  • Plutus Core

    plutus-core, plc

  • Pony

    pony

  • PostgreSQL SQL dialect

    postgresql, postgres

  • PostScript

    postscript, postscr

  • POVRay

    pov

  • PowerQuery

    powerquery, pq

  • PowerShell

    powershell, posh, ps1, psm1, psd1, pwsh

  • Prolog

    prolog

  • PromQL

    promql

  • properties

    java-properties

  • Protocol Buffer

    protobuf, proto

  • PSL

    psl

  • Puppet

    puppet

  • Python

    python, py, sage, python3, py3

  • Python 2

    python2, py2

  • QBasic

    qbasic, basic

  • QML

    qml, qbs

  • R

    splus, s, r

  • Racket

    racket, rkt

  • Ragel

    ragel

  • Raku

    perl6, pl6, raku

  • react

    jsx, react

  • ReasonML

    reason, reasonml

  • reg

    registry

  • reStructuredText

    rst, rest, restructuredtext

  • Rexx

    rexx, arexx

  • Ruby

    rb, ruby, duby

  • Rust

    rust, rs

  • SAS

    sas

  • Sass

    sass

  • Scala

    scala

  • Scheme

    scheme, scm

  • Scilab

    scilab

  • SCSS

    scss

  • Sed

    sed, gsed, ssed

  • Sieve

    sieve

  • Smalltalk

    smalltalk, squeak, st

  • Smarty

    smarty

  • Snobol

    snobol

  • Solidity

    sol, solidity

  • SPARQL

    sparql

  • SQL

    sql

  • SquidConf

    squidconf, squid.conf, squid

  • Standard ML

    sml

  • stas

  • Stylus

    stylus

  • Svelte

    svelte

  • Swift

    swift

  • SYSTEMD

    systemd

  • systemverilog

    systemverilog, sv

  • TableGen

    tablegen

  • TASM

    tasm

  • Tcl

    tcl

  • Tcsh

    tcsh, csh

  • Termcap

    termcap

  • Terminfo

    terminfo

  • Terraform

    terraform, tf

  • TeX

    tex, latex

  • Thrift

    thrift

  • TOML

    toml

  • TradingView

    tradingview, tv

  • Transact-SQL

    tsql, t-sql

  • Turing

    turing

  • Turtle

    turtle

  • Twig

    twig

  • TypeScript

    ts, tsx, typescript

  • TypoScript

    typoscript

  • TypoScriptCssData

    typoscriptcssdata

  • TypoScriptHtmlData

    typoscripthtmldata

  • V

    v, vlang

  • V shell

    vsh, vshell

  • Vala

    vala, vapi

  • VB.net

    vb.net, vbnet

  • verilog

    verilog, v

  • VHDL

    vhdl

  • VHS

    vhs, tape, cassette

  • VimL

    vim

  • vue

    vue, vuejs

  • WDTE

  • Whiley

    whiley

  • XML

    xml

  • Xorg

    xorg.conf

  • YAML

    yaml

  • YANG

    yang

  • Zed

    zed

  • Zig

    zig

另请参阅

6.1 - Hugo模板入门介绍

Introduction to Hugo Templating - Hugo模板入门介绍

https://gohugo.io/templates/introduction/

​ Hugo 使用 Go 的 html/templatetext/template 库作为模板的基础。

​ 以下仅为 Go 模板的入门指南。若想深入了解 Go 模板,请查看官方 Go 文档

​ Go 模板提供了一种极其简单的模板语言,坚信只有最基本的逻辑应该放在模板或视图层中。

基本语法

​ Go 模板是 HTML 文件,并加入了变量函数。Go 模板的变量和函数可以在 {{ }}中进行访问。

访问预定义变量

​ 预定义变量可以是当前作用域中已经存在的变量(如下面变量章节.Title示例),也可以是自定义变量(如该章节中的$address示例)。

1
2
{{ .Title }}
{{ $address }}

​ 函数的参数使用空格分隔。通常的语法如下:

1
{{ FUNCTION ARG1 ARG2 .. }}

​ 下面的示例使用12作为add函数的输入:

1
{{ add 1 2 }}

通过点符号访问方法和字段

​ 访问在内容前置元数据中定义的 Page 参数中的 bar

1
{{ .Params.bar }}

括号可以用来分组项

1
{{ if or (isset .Params "alt") (isset .Params "caption") }} Caption {{ end }}

单个语句可以分成多行

1
2
3
4
{{ if or
  (isset .Params "alt")
  (isset .Params "caption")
}}

原始字符串字面值可以包含换行符

1
2
{{ $msg := `Line one.
Line two.` }}

变量

​ 每个Go模板都有一个数据对象。在Hugo中,每个模板都传递了一个Page。在下面的示例中,.TitlePage变量中可访问的元素之一。

​ 由于Page是模板的默认作用域,因此可以通过点前缀(.Title)轻松访问当前作用域(. —— “the dot")中的Title元素:

1
<title>{{ .Title }}</title>

​ 值也可以存储在自定义变量中,并在之后被引用:

​ 自定义变量需要以$为前缀。

1
2
{{ $address := "123 Main St." }}
{{ $address }}

​ 使用=运算符可以重新定义变量。下面的示例在主页上打印"Var is Hugo Home”,在其他所有页面上打印"Var is Hugo Page":

1
2
3
4
5
{{ $var := "Hugo Page" }}
{{ if .IsHome }}
    {{ $var = "Hugo Home" }}
{{ end }}
Var is {{ $var }}

函数

​ Go模板仅提供了一些基本函数,但还提供了一种机制,使应用程序能够扩展原始函数集。

Hugo模板函数提供了特定于构建站点的附加功能。通过使用函数名和由空格分隔的所需参数来调用函数。如果没有重新编译Hugo,则无法添加模板函数。

示例1:添加数字

1
2
{{ add 1 2 }}
<!-- prints 3 -->

示例2:比较数字

1
2
{{ lt 1 2 }}
<!-- prints true (i.e., since 1 is less than 2) -->

​ 请注意,这两个示例都使用了Go模板的math函数。

​ 在Go模板文档中,有比Hugo文档中列出的更多的布尔运算符。

Includes

​ 在包含(Include)另一个模板时,您需要传递它需要访问的数据。

​ 为了传递当前上下文,请记住包含一个尾随点。

​ 模板位置始终从Hugo的layouts/目录开始。

Partial

partial函数用于使用语法{{ partial "<PATH>/<PARTIAL>.<EXTENSION>" . }}包含部分(partial)模板。

​ 包含layouts/partials/header.html部分(partial)模板的示例:

1
{{ partial "header.html" . }}

模板

​ 在早期版本的Hugo中,template函数用于包含部分(partial)模板。现在,它仅用于调用内部模板。语法为{{ template "_internal/<TEMPLATE>.<EXTENSION>" . }}

​ 可以在这里找到可用的内部模板。

​ 包含内部opengraph.html模板的示例:

1
{{ template "_internal/opengraph.html" . }}

逻辑

​ Go模板提供了最基本的迭代和条件逻辑。

迭代

​ Go模板大量使用range来迭代map、array或slice。以下是如何使用range的不同示例。

示例1:使用上下文(.)

1
2
3
{{ range $array }}
    {{ . }} <!-- The . represents an element in $array -->
{{ end }}

示例2:为数组元素的值声明变量名

1
2
3
{{ range $elem_val := $array }}
    {{ $elem_val }}
{{ end }}

示例3:为数组元素的索引和值声明变量名

​ 对于数组或切片,第一个声明的变量将映射到每个元素的索引。

1
2
3
{{ range $elem_index, $elem_val := $array }}
   {{ $elem_index }} -- {{ $elem_val }}
{{ end }}

示例4:为map元素的键和值声明变量名

​ 对于map,第一个声明的变量将映射到每个map元素的键。

1
2
3
{{ range $elem_key, $elem_val := $map }}
   {{ $elem_key }} -- {{ $elem_val }}
{{ end }}

示例5:针对空map、数组或切片的条件语句

​ 如果传递给range的map、数组或切片长度为零,则将执行else语句。

1
2
3
4
5
{{ range $array }}
    {{ . }}
{{ else }}
    <!-- This is only evaluated if $array is empty -->
{{ end }}

条件语句

ifelsewithorandnot提供了处理Go模板中条件逻辑的框架。与range一样,ifwith语句也是用{{ end }}关闭的。

​ Go 模板将以下值视为false

  • false (boolean)
  • 0 (integer)
  • 任何长度为零的数组、切片、映射或字符串

示例1:with

​ 通常使用with编写"if something exists, do this"这样的语句。

with会在其作用域内重新绑定上下文(.)(就像在range中一样)。

​ 如果变量不存在,或者如果它按上面所述计算为"false",则它会跳过该块。

1
2
3
{{ with .Params.title }}
    <h4>{{ . }}</h4>
{{ end }}

示例2:with..else

​ 下面的代码片段如果设置了"description"前置元数据的值,则使用它,否则使用默认的.Summary页面变量

1
2
3
4
5
{{ with .Param "description" }}
    {{ . }}
{{ else }}
    {{ .Summary }}
{{ end }}

​ 参见.Param函数

示例3:if

​ 编写with的另一种替代(更冗长)方法是使用if。在这里,.不会重新绑定。

​ 下面的示例是使用if重写的"示例1":

1
2
3
{{ if isset .Params "title" }}
    <h4>{{ index .Params "title" }}</h4>
{{ end }}

示例4:if..else

​ 下面的示例是使用if .. else重写的"示例2",并使用isset函数+ .Params变量(不同于.Param函数):

1
2
3
4
5
{{ if (isset .Params "description") }}
    {{ index .Params "description" }}
{{ else }}
    {{ .Summary }}
{{ end }}

示例5: if .. else if .. else

​ 与with不同,if还可以包含else if子句。

1
2
3
4
5
6
7
{{ if (isset .Params "description") }}
    {{ index .Params "description" }}
{{ else if (isset .Params "summary") }}
    {{ index .Params "summary" }}
{{ else }}
    {{ .Summary }}
{{ end }}

示例6: and & or

1
{{ if (and (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")) }}

管道

​ Go模板最强大的组件之一是能够将操作一层层堆叠在一起。这是通过使用管道来完成的。从Unix管道借鉴而来,概念很简单:每个管道的输出都成为下一个管道的输入。

​ 由于Go模板的语法非常简单,因此管道对于能够链接在一起的函数调用非常重要。管道的一个限制是它们只能处理单个值,该值成为下一个管道的最后一个参数。

​ 一些简单的示例应该有助于帮助您了解如何使用管道。

示例1: shuffle

​ 以下两个示例在功能上是相同的:

1
2
{{ shuffle (seq 1 5) }}
{{ (seq 1 5) | shuffle }}

示例2: index

​ 以下访问名为"disqus_url"的页面参数并转义HTML。此示例还使用内置于Go模板中的index函数

1
{{ index .Params "disqus_url" | html }}

示例3: 带有issetor

1
2
3
{{ if or (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr") }}
Stuff Here
{{ end }}

可以重写为

1
2
3
{{ if isset .Params "caption" | or isset .Params "title" | or isset .Params "attr" }}
Stuff Here
{{ end }}

上下文(也称"点")

​ Go模板最容易被忽视的理解概念是,{{ . }}始终指向当前上下文。

  • 在您的模板的顶层,它将是可用的数据集。
  • 但是,在迭代中,它将具有循环中当前项的值;即{{ . }}将不再引用整个页面可用的数据。

​ 如果您需要从循环内部访问页面级别的数据(例如,在前置元数据中设置的页面参数),则可能需要执行以下操作之一:

1.定义一个独立于上下文的变量

​ 以下示例演示如何定义一个独立于上下文的变量。

tags-range-with-page-variable.html

1
2
3
4
5
6
7
8
9
{{ $title := .Site.Title }}
<ul>
{{ range .Params.tags }}
    <li>
        <a href="/tags/{{ . | urlize }}">{{ . }}</a>
        - {{ $title }}
    </li>
{{ end }}
</ul>

请注意,一旦我们进入循环(即 range),{{ . }} 的值就已经改变了。我们在循环外面定义了一个变量({{ $title }}),并为其分配了一个值,以便我们可以从循环内部访问该值。

2.使用$.访问全局上下文

$ 在模板中具有特殊意义。$默认情况下被设置为 .(“the dot”)的起始值。这是Go text/template的文档功能。这意味着您可以从任何地方访问全局上下文。下面是先前的代码块的等效示例,但现在使用 $ 从全局上下文中获取 .Site.Title

range-through-tags-w-global.html

1
2
3
4
5
6
7
8
<ul>
{{ range .Params.tags }}
  <li>
    <a href="/tags/{{ . | urlize }}">{{ . }}</a>
            - {{ $.Site.Title }}
  </li>
{{ end }}
</ul>

​ 如果有人恶意重新定义特殊字符(例如 {{ $ := .Site }}),$ 的内置魔力将停止工作。不要这样做。当然,您可以在全局上下文中使用 {{ $ := . }} 来重置 $ 的默认值以恢复其功能。

空格

​ Go 1.6可以通过在相应的 {{}}分隔符旁边包含连字符(-)和空格来修剪Go标记的两侧的空格的功能。

​ 例如,以下Go模板将在其HTML输出中包含换行符和水平制表符:

1
2
3
<div>
  {{ .Title }}
</div>

它将输出:

1
2
3
<div>
  Hello, World!
</div>

​ 在以下示例中使用-将删除围绕.Title变量的额外空格并删除换行符:

1
2
3
<div>
  {{- .Title -}}
</div>

它将输出:

1
<div>Hello, World!</div>

Go 语言认为以下字符是空白字符:

  • 空格
  • 水平制表符
  • 回车符
  • 换行符

注释

​ 为了使您的模板组织有序并在团队之间共享信息,您可能希望向您的模板添加注释。在Hugo中有两种方法可以做到这一点。

Go模板注释

​ Go模板支持{{/**/}}来打开和关闭注释块。该块内的任何内容都不会被渲染。

例如:

1
Bonsoir, {{/* {{ add 0 + 2 }} */}}Eliott.

将渲染Bonsoir, Eliott.,而不关心注释块中的语法错误(add 0 + 2)。

HTML 注释

​ 您可以通过将 HTML 代码注释的字符串管道化到 safeHTML 中来添加 HTML 注释。

例如:

1
{{ "<!-- This is an HTML comment -->" | safeHTML }}

​ 如果您需要使用变量构造这样的HTML注释,只需将printf管道化到safeHTML

例如:

1
{{ printf "<!-- Our website is named: %s -->" .Site.Title | safeHTML }}

包含 Go 模板的 HTML 注释

​ 默认情况下,HTML注释会被删除,但其内容仍将被求值。这意味着尽管HTML注释永远不会将任何内容渲染到最终的HTML页面,但其中包含的代码可能会导致构建过程失败。

​ 不要尝试使用HTML注释来注释掉Go模板代码。

1
2
<!-- {{ $author := "Emma Goldman" }} was a great woman. -->
{{ $author }}

​ 模板引擎将删除HTML注释中的内容,但如果其中存在Go模板代码,则将首先求值任何Go模板代码。因此,上面的示例将渲染成Emma Goldman,因为$author变量在HTML注释中得到求值。但是,如果HTML注释中的代码有错误,构建将会失败。

Hugo参数

​ Hugo 提供了通过站点配置(用于整个站点的值)或每个特定内容的元数据(即前置元数据)向模板层传递值的选项。您可以定义任何类型的任何值,并在模板中任意使用它们,只要这些值得到前置元数据格式支持。

使用内容(page)参数

​ 您可以在单个内容的前置元数据中提供变量以供模板使用。

​ Hugo 文档中使用了一个示例。大多数页面都受益于提供目录,但有时目录并不合适。我们在前置元数据中定义了一个 notoc 变量,当设置为 true 时,将防止目录呈现。

以下是示例前置元数据:

content/example.md

=== “yaml”

``` yaml
---
notoc: true
title: Example
---
```

=== “toml”

``` toml
+++
notoc = true
title = 'Example'
+++
```

=== “json”

``` json
{
   "notoc": true,
   "title": "Example"
}
```

​ 以下是可以在 toc.html 局部模板中使用的对应代码示例:

layouts/partials/toc.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{{ if not .Params.notoc }}
<aside>
  <header>
    <a href="#{{ .Title | urlize }}">
    <h3>{{ .Title }}</h3>
    </a>
  </header>
  {{ .TableOfContents }}
</aside>
<a href="#" id="toc-toggle"></a>
{{ end }}

​ 我们希望页面的默认行为是包含目录,除非另有指定。此模板检查此页面前置元数据中的 notoc: 字段是否为 true

使用站点配置参数

​ 您可以在站点配置文件中任意定义任何数量的站点级参数。这些参数在您的模板中全局可用。

​ 例如,您可以声明以下内容:

config.

=== “yaml”

``` yaml
params:
  copyrighthtml: Copyright &#xA9; 2017 John Doe. All Rights Reserved.
  sidebarrecentlimit: 5
  twitteruser: spf13
```

=== “toml”

``` toml
[params]
  copyrighthtml = 'Copyright &#xA9; 2017 John Doe. All Rights Reserved.'
  sidebarrecentlimit = 5
  twitteruser = 'spf13'
```

=== “json”

``` json
{
   "params": {
      "copyrighthtml": "Copyright \u0026#xA9; 2017 John Doe. All Rights Reserved.",
      "sidebarrecentlimit": 5,
      "twitteruser": "spf13"
   }
}
```

​ 在页脚布局中,您可以声明仅在提供了 copyrighthtml 参数时才呈现的 <footer>。如果提供了该参数,则需要通过 safeHTML 函数声明该字符串可以安全使用,以便 HTML 实体不会被再次转义。这使您可以轻松地每年 1 月 1 日仅更新顶级配置文件,而无需在模板中查找。

1
2
3
4
5
{{ if .Site.Params.copyrighthtml }}
    <footer>
        <div class="text-center">{{ .Site.Params.CopyrightHTML | safeHTML }}</div>
    </footer>
{{ end }}

​ 一种替代写"if“并引用同一值的方法是使用withwith在其作用域内重新绑定上下文(.),如果该变量不存在,则跳过块:

layouts/partials/twitter.html

1
2
3
4
5
6
{{ with .Site.Params.twitteruser }}
    <div>
        <a href="https://twitter.com/{{ . }}" rel="author">
        <img src="/images/twitter.png" width="48" height="48" title="Twitter: {{ . }}" alt="Twitter"></a>
    </div>
{{ end }}

​ 最后,您也可以将"魔术常量"从您的布局中拉出来。以下示例使用first函数,以及.RelPermalink页面变量和.Site.Pages站点变量。

1
2
3
4
5
6
7
8
<nav>
  <h1>Recent Posts</h1>
  <ul>
  {{- range first .Site.Params.SidebarRecentLimit .Site.Pages -}}
      <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
  {{- end -}}
  </ul>
</nav>    

示例:显示未来事件

​ 假设有以下内容结构和前置元数据:

1
2
3
4
5
content/
└── events/
    ├── event-1.md
    ├── event-2.md
    └── event-3.md

content/events/event-1.md.

=== “yaml”

``` yaml
date: 2021-12-06T10:37:16-08:00
draft: false
end_date: 2021-12-05T11:00:00-08:00
start_date: 2021-12-05T09:00:00-08:00
title: Event 1
```

=== “toml”

``` toml
date = 2021-12-06T10:37:16-08:00
draft = false
end_date = 2021-12-05T11:00:00-08:00
start_date = 2021-12-05T09:00:00-08:00
title = 'Event 1'
```

=== “json”

``` json
{
   "date": "2021-12-06T10:37:16-08:00",
   "draft": false,
   "end_date": "2021-12-05T11:00:00-08:00",
   "start_date": "2021-12-05T09:00:00-08:00",
   "title": "Event 1"
}
```

​ 这个局部模板渲染未来的事件:

layouts/partials/future-events.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<h2>Future Events</h2>
<ul>
  {{ range where site.RegularPages "Type" "events" }}
    {{ if gt (.Params.start_date | time.AsTime) now }}
      {{ $startDate := .Params.start_date | time.Format ":date_medium" }}
      <li>
        <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a> - {{ $startDate }}
      </li>
    {{ end }}
  {{ end }}
</ul>

​ 如果将前置元数据限制为TOML格式,并省略日期字段周围的引号,则可以执行日期比较而无需强制转换。

layouts/partials/future-events.html

1
2
3
4
5
6
7
8
9
<h2>Future Events</h2>
<ul>
  {{ range where (where site.RegularPages "Type" "events") "Params.start_date" "gt" now }}
    {{ $startDate := .Params.start_date | time.Format ":date_medium" }}
    <li>
      <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a> - {{ $startDate }}
    </li>
  {{ end }}
</ul>

另请参阅

6.2 - Hugo 的查找顺序

Hugo’s Lookup Order - Hugo 的查找顺序

https://gohugo.io/templates/lookup-order/

​ Hugo按照一定的顺序查找给定页面的布局,从最具体的布局开始。

Hugo 布局查找规则

​ Hugo在选择给定页面的布局时会考虑下面列出的参数。它们按优先级排序。这应该很自然,但具体的参数变化请参考下面的表格。

  • Kind

    页面的Kind(主页是其中之一)。请参见下面每个种类的示例表格。这也确定了它是单页面(即常规内容页面。然后我们在_default/single.html中寻找HTML模板)还是列表页面(章节列表、主页、分类列表、分类术语。然后我们在_default/list.html中寻找HTML模板)。

  • Layout

    可以在页面前置元数据中设置。

  • 输出格式

    请参见自定义输出格式。输出格式既有一个name(例如rssamphtml),也有一个suffix(例如xmlhtml)。我们更喜欢两者匹配(例如index.amp.html),但寻找较不具体的模板。

请注意,如果输出格式的媒体类型定义了多个后缀,则只考虑第一个后缀。

  • Language

    模板名称中会考虑语言代码。如果站点语言是fr,则index.fr.amp.html将优于index.amp.html,但 index.amp.html 将在 index.fr.html 之前被选择。

  • Type

    如果在前置元数据中设置了type的值,则它是type的值,否则它是根章节的名称(例如"blog")。它总是有一个值,所以如果未设置,则值为"page"。

  • Section

    对于sectiontaxonomyterm类型很重要。

提示:下面的示例看起来很长、很复杂。这就是灵活性在起作用。大多数Hugo站点只包含少量模板:

1
2
3
4
5
├── _default
│   ├── baseof.html
│   ├── list.html
│   └── single.html
└── index.html

带有主题的 Hugo 布局查找规则

​ 在Hugo中,布局可以存在于项目或主题的布局文件夹中,并且会选择最具体的布局。Hugo将交错查找下面的布局,找到最具体的一个布局,无论是在项目还是主题中。

示例:常规页面的布局查找

ExampleOutputFormatSuffixTemplate Lookup Order
Single page in “posts” sectionHTMLhtmllayouts/posts/single.html.htmllayouts/posts/single.htmllayouts/_default/single.html.htmllayouts/_default/single.html
Base template for single page in “posts” sectionHTMLhtmllayouts/posts/single-baseof.html.htmllayouts/posts/baseof.html.htmllayouts/posts/single-baseof.htmllayouts/posts/baseof.htmllayouts/_default/single-baseof.html.htmllayouts/_default/baseof.html.htmllayouts/_default/single-baseof.htmllayouts/_default/baseof.html
Single page in “posts” section with layout setHTMLhtmllayouts/posts/demolayout.html.htmllayouts/posts/single.html.htmllayouts/posts/demolayout.htmllayouts/posts/single.htmllayouts/_default/demolayout.html.htmllayouts/_default/single.html.htmllayouts/_default/demolayout.htmllayouts/_default/single.html
Base template for single page in “posts” section with layout setHTMLhtmllayouts/posts/demolayout-baseof.html.htmllayouts/posts/single-baseof.html.htmllayouts/posts/baseof.html.htmllayouts/posts/demolayout-baseof.htmllayouts/posts/single-baseof.htmllayouts/posts/baseof.htmllayouts/_default/demolayout-baseof.html.htmllayouts/_default/single-baseof.html.htmllayouts/_default/baseof.html.htmllayouts/_default/demolayout-baseof.htmllayouts/_default/single-baseof.htmllayouts/_default/baseof.html
AMP single pageAMPhtmllayouts/posts/single.amp.htmllayouts/posts/single.htmllayouts/_default/single.amp.htmllayouts/_default/single.html
AMP single page, French languageAMPhtmllayouts/posts/single.fr.amp.htmllayouts/posts/single.amp.htmllayouts/posts/single.fr.htmllayouts/posts/single.htmllayouts/_default/single.fr.amp.htmllayouts/_default/single.amp.htmllayouts/_default/single.fr.htmllayouts/_default/single.html

示例:主页的布局查找

ExampleOutputFormatSuffixTemplate Lookup Order
Home pageHTMLhtmllayouts/index.html.htmllayouts/home.html.htmllayouts/list.html.htmllayouts/index.htmllayouts/home.htmllayouts/list.htmllayouts/_default/index.html.htmllayouts/_default/home.html.htmllayouts/_default/list.html.htmllayouts/_default/index.htmllayouts/_default/home.htmllayouts/_default/list.html
Base template for home pageHTMLhtmllayouts/index-baseof.html.htmllayouts/home-baseof.html.htmllayouts/list-baseof.html.htmllayouts/baseof.html.htmllayouts/index-baseof.htmllayouts/home-baseof.htmllayouts/list-baseof.htmllayouts/baseof.htmllayouts/_default/index-baseof.html.htmllayouts/_default/home-baseof.html.htmllayouts/_default/list-baseof.html.htmllayouts/_default/baseof.html.htmllayouts/_default/index-baseof.htmllayouts/_default/home-baseof.htmllayouts/_default/list-baseof.htmllayouts/_default/baseof.html
Home page with type setHTMLhtmllayouts/demotype/index.html.htmllayouts/demotype/home.html.htmllayouts/demotype/list.html.htmllayouts/demotype/index.htmllayouts/demotype/home.htmllayouts/demotype/list.htmllayouts/index.html.htmllayouts/home.html.htmllayouts/list.html.htmllayouts/index.htmllayouts/home.htmllayouts/list.htmllayouts/_default/index.html.htmllayouts/_default/home.html.htmllayouts/_default/list.html.htmllayouts/_default/index.htmllayouts/_default/home.htmllayouts/_default/list.html
Base template for home page with type setHTMLhtmllayouts/demotype/index-baseof.html.htmllayouts/demotype/home-baseof.html.htmllayouts/demotype/list-baseof.html.htmllayouts/demotype/baseof.html.htmllayouts/demotype/index-baseof.htmllayouts/demotype/home-baseof.htmllayouts/demotype/list-baseof.htmllayouts/demotype/baseof.htmllayouts/index-baseof.html.htmllayouts/home-baseof.html.htmllayouts/list-baseof.html.htmllayouts/baseof.html.htmllayouts/index-baseof.htmllayouts/home-baseof.htmllayouts/list-baseof.htmllayouts/baseof.htmllayouts/_default/index-baseof.html.htmllayouts/_default/home-baseof.html.htmllayouts/_default/list-baseof.html.htmllayouts/_default/baseof.html.htmllayouts/_default/index-baseof.htmllayouts/_default/home-baseof.htmllayouts/_default/list-baseof.htmllayouts/_default/baseof.html
Home page with layout setHTMLhtmllayouts/demolayout.html.htmllayouts/index.html.htmllayouts/home.html.htmllayouts/list.html.htmllayouts/demolayout.htmllayouts/index.htmllayouts/home.htmllayouts/list.htmllayouts/_default/demolayout.html.htmllayouts/_default/index.html.htmllayouts/_default/home.html.htmllayouts/_default/list.html.htmllayouts/_default/demolayout.htmllayouts/_default/index.htmllayouts/_default/home.htmllayouts/_default/list.html
AMP home, French languageAMPhtmllayouts/index.fr.amp.htmllayouts/home.fr.amp.htmllayouts/list.fr.amp.htmllayouts/index.amp.htmllayouts/home.amp.htmllayouts/list.amp.htmllayouts/index.fr.htmllayouts/home.fr.htmllayouts/list.fr.htmllayouts/index.htmllayouts/home.htmllayouts/list.htmllayouts/_default/index.fr.amp.htmllayouts/_default/home.fr.amp.htmllayouts/_default/list.fr.amp.htmllayouts/_default/index.amp.htmllayouts/_default/home.amp.htmllayouts/_default/list.amp.htmllayouts/_default/index.fr.htmllayouts/_default/home.fr.htmllayouts/_default/list.fr.htmllayouts/_default/index.htmllayouts/_default/home.htmllayouts/_default/list.html
JSON homeJSONjsonlayouts/index.json.jsonlayouts/home.json.jsonlayouts/list.json.jsonlayouts/index.jsonlayouts/home.jsonlayouts/list.jsonlayouts/_default/index.json.jsonlayouts/_default/home.json.jsonlayouts/_default/list.json.jsonlayouts/_default/index.jsonlayouts/_default/home.jsonlayouts/_default/list.json
RSS homeRSSxmllayouts/index.rss.xmllayouts/home.rss.xmllayouts/rss.xmllayouts/list.rss.xmllayouts/index.xmllayouts/home.xmllayouts/list.xmllayouts/_default/index.rss.xmllayouts/_default/home.rss.xmllayouts/_default/rss.xmllayouts/_default/list.rss.xmllayouts/_default/index.xmllayouts/_default/home.xmllayouts/_default/list.xmllayouts/_internal/_default/rss.xml

示例:章节页面的布局查找

ExampleOutputFormatSuffixTemplate Lookup Order
RSS section postsRSSxmllayouts/posts/section.rss.xmllayouts/posts/rss.xmllayouts/posts/list.rss.xmllayouts/posts/section.xmllayouts/posts/list.xmllayouts/section/section.rss.xmllayouts/section/rss.xmllayouts/section/list.rss.xmllayouts/section/section.xmllayouts/section/list.xmllayouts/_default/section.rss.xmllayouts/_default/rss.xmllayouts/_default/list.rss.xmllayouts/_default/section.xmllayouts/_default/list.xmllayouts/_internal/_default/rss.xml
Section list for “posts” sectionHTMLhtmllayouts/posts/posts.html.htmllayouts/posts/section.html.htmllayouts/posts/list.html.htmllayouts/posts/posts.htmllayouts/posts/section.htmllayouts/posts/list.htmllayouts/section/posts.html.htmllayouts/section/section.html.htmllayouts/section/list.html.htmllayouts/section/posts.htmllayouts/section/section.htmllayouts/section/list.htmllayouts/_default/posts.html.htmllayouts/_default/section.html.htmllayouts/_default/list.html.htmllayouts/_default/posts.htmllayouts/_default/section.htmllayouts/_default/list.html
Section list for “posts” section with type set to “blog”HTMLhtmllayouts/blog/posts.html.htmllayouts/blog/section.html.htmllayouts/blog/list.html.htmllayouts/blog/posts.htmllayouts/blog/section.htmllayouts/blog/list.htmllayouts/posts/posts.html.htmllayouts/posts/section.html.htmllayouts/posts/list.html.htmllayouts/posts/posts.htmllayouts/posts/section.htmllayouts/posts/list.htmllayouts/section/posts.html.htmllayouts/section/section.html.htmllayouts/section/list.html.htmllayouts/section/posts.htmllayouts/section/section.htmllayouts/section/list.htmllayouts/_default/posts.html.htmllayouts/_default/section.html.htmllayouts/_default/list.html.htmllayouts/_default/posts.htmllayouts/_default/section.htmllayouts/_default/list.html
Section list for “posts” section with layout set to “demoLayout”HTMLhtmllayouts/posts/demolayout.html.htmllayouts/posts/posts.html.htmllayouts/posts/section.html.htmllayouts/posts/list.html.htmllayouts/posts/demolayout.htmllayouts/posts/posts.htmllayouts/posts/section.htmllayouts/posts/list.htmllayouts/section/demolayout.html.htmllayouts/section/posts.html.htmllayouts/section/section.html.htmllayouts/section/list.html.htmllayouts/section/demolayout.htmllayouts/section/posts.htmllayouts/section/section.htmllayouts/section/list.htmllayouts/_default/demolayout.html.htmllayouts/_default/posts.html.htmllayouts/_default/section.html.htmllayouts/_default/list.html.htmllayouts/_default/demolayout.htmllayouts/_default/posts.htmllayouts/_default/section.htmllayouts/_default/list.html

示例:分类页面的布局查找

ExampleOutputFormatSuffixTemplate Lookup Order
Taxonomy in categoriesRSSxmllayouts/categories/category.terms.rss.xmllayouts/categories/terms.rss.xmllayouts/categories/taxonomy.rss.xmllayouts/categories/rss.xmllayouts/categories/list.rss.xmllayouts/categories/category.terms.xmllayouts/categories/terms.xmllayouts/categories/taxonomy.xmllayouts/categories/list.xmllayouts/category/category.terms.rss.xmllayouts/category/terms.rss.xmllayouts/category/taxonomy.rss.xmllayouts/category/rss.xmllayouts/category/list.rss.xmllayouts/category/category.terms.xmllayouts/category/terms.xmllayouts/category/taxonomy.xmllayouts/category/list.xmllayouts/taxonomy/category.terms.rss.xmllayouts/taxonomy/terms.rss.xmllayouts/taxonomy/taxonomy.rss.xmllayouts/taxonomy/rss.xmllayouts/taxonomy/list.rss.xmllayouts/taxonomy/category.terms.xmllayouts/taxonomy/terms.xmllayouts/taxonomy/taxonomy.xmllayouts/taxonomy/list.xmllayouts/_default/category.terms.rss.xmllayouts/_default/terms.rss.xmllayouts/_default/taxonomy.rss.xmllayouts/_default/rss.xmllayouts/_default/list.rss.xmllayouts/_default/category.terms.xmllayouts/_default/terms.xmllayouts/_default/taxonomy.xmllayouts/_default/list.xmllayouts/_internal/_default/rss.xml
Taxonomy list in categoriesHTMLhtmllayouts/categories/category.terms.html.htmllayouts/categories/terms.html.htmllayouts/categories/taxonomy.html.htmllayouts/categories/list.html.htmllayouts/categories/category.terms.htmllayouts/categories/terms.htmllayouts/categories/taxonomy.htmllayouts/categories/list.htmllayouts/category/category.terms.html.htmllayouts/category/terms.html.htmllayouts/category/taxonomy.html.htmllayouts/category/list.html.htmllayouts/category/category.terms.htmllayouts/category/terms.htmllayouts/category/taxonomy.htmllayouts/category/list.htmllayouts/taxonomy/category.terms.html.htmllayouts/taxonomy/terms.html.htmllayouts/taxonomy/taxonomy.html.htmllayouts/taxonomy/list.html.htmllayouts/taxonomy/category.terms.htmllayouts/taxonomy/terms.htmllayouts/taxonomy/taxonomy.htmllayouts/taxonomy/list.htmllayouts/_default/category.terms.html.htmllayouts/_default/terms.html.htmllayouts/_default/taxonomy.html.htmllayouts/_default/list.html.htmllayouts/_default/category.terms.htmllayouts/_default/terms.htmllayouts/_default/taxonomy.htmllayouts/_default/list.html

示例:术语页面的布局查找

ExampleOutputFormatSuffixTemplate Lookup Order
Term in categoriesRSSxmllayouts/categories/term.rss.xmllayouts/categories/category.rss.xmllayouts/categories/taxonomy.rss.xmllayouts/categories/rss.xmllayouts/categories/list.rss.xmllayouts/categories/term.xmllayouts/categories/category.xmllayouts/categories/taxonomy.xmllayouts/categories/list.xmllayouts/term/term.rss.xmllayouts/term/category.rss.xmllayouts/term/taxonomy.rss.xmllayouts/term/rss.xmllayouts/term/list.rss.xmllayouts/term/term.xmllayouts/term/category.xmllayouts/term/taxonomy.xmllayouts/term/list.xmllayouts/taxonomy/term.rss.xmllayouts/taxonomy/category.rss.xmllayouts/taxonomy/taxonomy.rss.xmllayouts/taxonomy/rss.xmllayouts/taxonomy/list.rss.xmllayouts/taxonomy/term.xmllayouts/taxonomy/category.xmllayouts/taxonomy/taxonomy.xmllayouts/taxonomy/list.xmllayouts/category/term.rss.xmllayouts/category/category.rss.xmllayouts/category/taxonomy.rss.xmllayouts/category/rss.xmllayouts/category/list.rss.xmllayouts/category/term.xmllayouts/category/category.xmllayouts/category/taxonomy.xmllayouts/category/list.xmllayouts/_default/term.rss.xmllayouts/_default/category.rss.xmllayouts/_default/taxonomy.rss.xmllayouts/_default/rss.xmllayouts/_default/list.rss.xmllayouts/_default/term.xmllayouts/_default/category.xmllayouts/_default/taxonomy.xmllayouts/_default/list.xmllayouts/_internal/_default/rss.xml
Taxonomy term in categoriesHTMLhtmllayouts/categories/term.html.htmllayouts/categories/category.html.htmllayouts/categories/taxonomy.html.htmllayouts/categories/list.html.htmllayouts/categories/term.htmllayouts/categories/category.htmllayouts/categories/taxonomy.htmllayouts/categories/list.htmllayouts/term/term.html.htmllayouts/term/category.html.htmllayouts/term/taxonomy.html.htmllayouts/term/list.html.htmllayouts/term/term.htmllayouts/term/category.htmllayouts/term/taxonomy.htmllayouts/term/list.htmllayouts/taxonomy/term.html.htmllayouts/taxonomy/category.html.htmllayouts/taxonomy/taxonomy.html.htmllayouts/taxonomy/list.html.htmllayouts/taxonomy/term.htmllayouts/taxonomy/category.htmllayouts/taxonomy/taxonomy.htmllayouts/taxonomy/list.htmllayouts/category/term.html.htmllayouts/category/category.html.htmllayouts/category/taxonomy.html.htmllayouts/category/list.html.htmllayouts/category/term.htmllayouts/category/category.htmllayouts/category/taxonomy.htmllayouts/category/list.htmllayouts/_default/term.html.htmllayouts/_default/category.html.htmllayouts/_default/taxonomy.html.htmllayouts/_default/list.html.htmllayouts/_default/term.htmllayouts/_default/category.htmllayouts/_default/taxonomy.htmllayouts/_default/list.html

另请参阅

6.3 - 自定义输出格式

Custom Output Formats - 自定义输出格式

https://gohugo.io/templates/output-formats/

​ Hugo可以将内容输出为多种格式,包括日历事件、电子书格式、Google AMP和JSON搜索索引,或任何自定义文本格式。

​ 本页介绍了如何正确配置站点的媒体类型和输出格式,以及如何为自定义输出创建模板。

媒体类型

媒体类型(也称为MIME类型和内容类型)是用于在互联网上传输文件格式和格式内容的两部分标识符。

​ 这是Hugo中的完整内置媒体类型集:

typesuffixes
application/json[json]
application/manifest+json[webmanifest]
application/octet-stream[]
application/pdf[pdf]
application/rss+xml[xml rss]
application/toml[toml]
application/xml[xml]
application/yaml[yaml yml]
font/otf[otf]
font/ttf[ttf]
image/bmp[bmp]
image/gif[gif]
image/jpeg[jpg jpeg jpe jif jfif]
image/png[png]
image/svg+xml[svg]
image/webp[webp]
text/calendar[ics]
text/css[css]
text/csv[csv]
text/html[html]
text/javascript[js jsm mjs]
text/jsx[jsx]
text/markdown[md markdown]
text/plain[txt]
text/tsx[tsx]
text/typescript[ts]
text/x-sass[sass]
text/x-scss[scss]
video/3gpp[3gpp 3gp]
video/mp4[mp4]
video/mpeg[mpg mpeg]
video/ogg[ogv]
video/webm[webm]
video/x-msvideo[avi]

注意:

  • 可以添加自定义媒体类型或更改默认值;例如,如果您想将text/html的后缀更改为asp
  • Suffixes是在Hugo中用于该媒体类型的URL和文件名的值。
  • Type是定义新/自定义Output Formats时必须使用的标识符(见下文)。
  • 完整的媒体类型集将在Hugo的内置开发服务器中注册,以确保它们被浏览器识别。

​ 要添加或修改媒体类型,请在站点配置中的mediaTypes部分中定义它,可以为所有站点或特定语言定义。

config.

=== “yaml”

``` yaml
mediaTypes:
  text/enriched:
    suffixes:
    - enr
  text/html:
    suffixes:
    - asp
```

=== “toml”

``` toml
[mediaTypes]
  [mediaTypes.'text/enriched']
    suffixes = ['enr']
  [mediaTypes.'text/html']
    suffixes = ['asp']
```

=== “json”

``` json
{
   "mediaTypes": {
      "text/enriched": {
         "suffixes": [
            "enr"
         ]
      },
      "text/html": {
         "suffixes": [
            "asp"
         ]
      }
   }
}
```

​ 上面的示例添加了一个新的媒体类型text/enriched,并更改了内置的text/html媒体类型的后缀。

注意:这些媒体类型是针对您的输出格式进行配置的。如果要重新定义Hugo的默认输出格式(例如HTML),还需要重新定义媒体类型。因此,如果要将HTML输出格式的后缀从html(默认)更改为htm

config.

=== “yaml”

``` yaml
mediaTypes:
  text/html:
    suffixes:
    - htm
outputFormats:
  HTML:
    mediaType: text/html
```

=== “toml”

``` toml
[mediaTypes]
  [mediaTypes.'text/html']
    suffixes = ['htm']
[outputFormats]
  [outputFormats.HTML]
    mediaType = 'text/html'
```

=== “json”

``` json
{
   "mediaTypes": {
      "text/html": {
         "suffixes": [
            "htm"
         ]
      }
   },
   "outputFormats": {
      "HTML": {
         "mediaType": "text/html"
      }
   }
}
```

注意,要让上述内容生效,您还需要在站点配置中添加 outputs 定义。

输出格式定义

​ 给定一个媒体类型和一些其他配置,您可以获得一个输出格式。

​ 这是Hugo的所有内置输出格式:

namemediaTypepathbaseNamerelprotocolisPlainTextisHTMLnoUglypermalinkable
HTMLtext/htmlindexcanonicalfalsetruefalsetrue
AMPtext/htmlampindexamphtmlfalsetruefalsetrue
CSStext/cssstylesstylesheettruefalsefalsefalse
CSVtext/csvindexalternatetruefalsefalsefalse
Calendartext/calendarindexalternatewebcal://truefalsefalsefalse
JSONapplication/jsonindexalternatetruefalsefalsefalse
MARKDOWNtext/markdownindexalternatetruefalsefalsefalse
ROBOTStext/plainrobotsalternatetruefalsefalsefalse
RSSapplication/rss+xmlindexalternatefalsefalsetruefalse
Sitemapapplication/xmlsitemapsitemapfalsefalsetruefalse
WebAppManifestapplication/manifest+jsonmanifestmanifesttruefalsefalsefalse
  • 一个页面可以按您想要的多种输出格式输出,只要它们在文件系统上解析为唯一路径即可定义无限数量的输出格式。在上面的表格中,最好的例子是AMP vs HTMLAMPPath值为amp,因此不会覆盖HTML版本。例如,我们现在可以同时拥有 /index.html/amp/index.html
  • MediaType 必须匹配已定义媒体类型的Type
  • 您可以定义新的输出格式或重新定义内置的输出格式;例如,如果您想将AMP页面放在不同的路径中。

​ 要添加或修改输出格式,请在站点配置文件中的 outputFormats 部分中定义它,无论是为所有站点还是为给定的语言。

config.

=== “yaml”

``` yaml
outputFormats:
  MyEnrichedFormat:
    baseName: myindex
    isPlainText: true
    mediaType: text/enriched
    protocol: bep://
```

=== “toml”

``` toml
[outputFormats]
  [outputFormats.MyEnrichedFormat]
    baseName = 'myindex'
    isPlainText = true
    mediaType = 'text/enriched'
    protocol = 'bep://'
```

=== “json”

``` json
{
   "outputFormats": {
      "MyEnrichedFormat": {
         "baseName": "myindex",
         "isPlainText": true,
         "mediaType": "text/enriched",
         "protocol": "bep://"
      }
   }
}
```

​ 上述示例是虚构的,但如果用于具有 baseURL https://example.org 的站点的主页,它将产生一个具有 URL bep://example.org/myindex.enr 的纯文本主页。

配置输出格式

​ 以下是输出格式的完整配置选项列表及其默认值:

  • name

    输出格式标识符。用于定义您页面的输出格式。

  • mediaType

    这必须与已定义的媒体类型的Type匹配。

  • path

    保存输出文件的子路径。

  • baseName

    用于列表文件名(主页等)的基本文件名。默认值:index

  • rel

    可用于在link标记中创建 rel 值。默认值:alternate

  • protocol

    将替换 baseURL 中此输出格式的"http://“或"https://"。

  • isPlainText

    使用 Go 的纯文本模板解析器进行模板解析。默认值: false

  • isHTML

    仅在与 HTML 类型格式相关的情况下使用,例如页面别名。默认值: false

  • noUgly

    用于关闭丑陋的 URL(如果在站点中设置了 uglyURLstrue)。默认值: false

  • notAlternative

    enable if it doesn’t make sense to include this format in an AlternativeOutputFormats format listing on Page (e.g., with CSS). Note that we use the term alternative and not alternate here, as it does not necessarily replace the other format. Default: false.

    如果在PageAlternativeOutputFormats 格式列表中包含此格式不合理(例如使用 CSS),则启用此选项。请注意,此处我们使用 alternative 而不是 alternate 一词,因为它并不一定替代其他格式。默认值: false

  • permalinkable

    使 .Permalink.RelPermalink 返回渲染输出格式而不是主格式(见下文)。默认情况下,对于 HTMLAMP 启用此选项。默认值: false

  • weight

    将其设置为非零值将用作第一个排序标准。

页面的输出格式

​ 在 Hugo 中,Page可以在文件系统上呈现为多种输出格式。

默认输出格式

​ 每个Page都有一个 Kind 属性,其默认输出格式是基于此属性设置的。

KindDefault Output Formats
pageHTML
homeHTML, RSS
sectionHTML, RSS
taxonomyHTML, RSS
termHTML, RSS

自定义输出格式

​ 这可以通过在Page前置元数据或站点配置(对所有站点或每种语言)中定义一个outputs列表来更改。

​ 站点配置文件中的示例:

config.

=== “yaml”

``` yaml
outputs:
  home:
  - HTML
  - AMP
  - RSS
  page:
  - HTML
```

=== “toml”

``` toml
[outputs]
  home = ['HTML', 'AMP', 'RSS']
  page = ['HTML']
```

=== “json”

``` json
{
   "outputs": {
      "home": [
         "HTML",
         "AMP",
         "RSS"
      ],
      "page": [
         "HTML"
      ]
   }
}
```

请注意,在上面的示例中,sectiontaxonomyterm的输出格式将保持其默认值 ["HTML", "RSS"]

KindDescriptionExample
homeThe landing page for the home page/index.html
pageThe landing page for a given pagemy-post page (/posts/my-post/index.html)
sectionThe landing page of a given sectionposts section (/posts/index.html)
taxonomyThe landing page for a taxonomytags taxonomy (/tags/index.html)
termThe landing page for one taxonomy’s termterm awesome in tags taxonomy (/tags/awesome/index.html)
  • outputs 定义是每种PageKindpagehomesectiontaxonomyterm)的。

  • These can be overridden per Page in the front matter of content files.

  • 所使用的名称(例如 HTMLAMP)必须与已定义的输出格式的Name匹配。

    这些名称不区分大小写。

  • 这些可以在内容文件的前置元数据中针对每个Page进行覆盖。

​ 以下是一个在内容文件中定义呈现Page输出格式的前置元数据的示例:

content/example.md

=== “yaml”

``` yaml
---
outputs:
- html
- amp
- json
title: Example
---
```

=== “toml”

``` toml
+++
outputs = ['html', 'amp', 'json']
title = 'Example'
+++
```

=== “json”

``` json
{
   "outputs": [
      "html",
      "amp",
      "json"
   ],
   "title": "Example"
}
```

输出格式列表

​ 每个Page都有 .OutputFormats(所有格式,包括当前格式)和 .AlternativeOutputFormats 变量,后者可用于在站点的 <head> 中创建link rel 列表。

1
2
3
{{ range .AlternativeOutputFormats -}}
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
{{ end -}}

输出格式链接

Page 上的 .Permalink.RelPermalink 将返回为该页面定义的第一个输出格式(通常为 HTML,如果没有其他定义的话)。这与调用它们的模板文件无关。

来自 single.json.json

1
2
3
4
{{ .RelPermalink }} > /that-page/
{{ with  .OutputFormats.Get "json" -}}
{{ .RelPermalink }} > /that-page/index.json
{{- end }}

​ 为了使它们返回当前模板文件的输出格式,给定的输出格式应设置其 permalinkable 属性为 true

与上面相同的模板文件,带有json 输出格式的 permalinkable 设置为 true:

1
2
3
4
{{ .RelPermalink }} > /that-page/index.json
{{ with  .OutputFormats.Get "html" -}}
{{ .RelPermalink }} > /that-page/
{{- end }}

​ 从内容文件中,您可以使用 refrelref 简码

1
2
[Neat](\{\{\< ref "blog/neat.md" "amp" \>\}\})
[Who](\{\{\< relref "about.md#who" "amp" \>\}\})

您的输出格式模板

​ 一个新的输出格式需要一个相应的模板才能渲染任何有用的内容。

​ 对于 Hugo 0.20 及更高版本的关键区别在于,Hugo 查看输出格式的 Name 和 MediaType 的 Suffixes,以选择用于渲染给定 Page 的模板。

​ 以下表格显示了不同输出格式的示例、所使用的后缀以及 Hugo 的模板查找顺序。表格中的所有示例都可以:

ExampleOutputFormatSuffixTemplate Lookup Order
“posts” 章节的单个页面HTMLhtml[layouts/posts/single.html.html layouts/posts/single.html layouts/_default/single.html.html layouts/_default/single.html]
“posts” 章节的单个页面基础模板HTMLhtml[layouts/posts/single-baseof.html.html layouts/posts/baseof.html.html layouts/posts/single-baseof.html layouts/posts/baseof.html layouts/_default/single-baseof.html.html layouts/_default/baseof.html.html layouts/_default/single-baseof.html layouts/_default/baseof.html]
Single page in “posts” section with layout setHTMLhtml[layouts/posts/demolayout.html.html layouts/posts/single.html.html layouts/posts/demolayout.html layouts/posts/single.html layouts/_default/demolayout.html.html layouts/_default/single.html.html layouts/_default/demolayout.html layouts/_default/single.html]
Base template for single page in “posts” section with layout setHTMLhtml[layouts/posts/demolayout-baseof.html.html layouts/posts/single-baseof.html.html layouts/posts/baseof.html.html layouts/posts/demolayout-baseof.html layouts/posts/single-baseof.html layouts/posts/baseof.html layouts/_default/demolayout-baseof.html.html layouts/_default/single-baseof.html.html layouts/_default/baseof.html.html layouts/_default/demolayout-baseof.html layouts/_default/single-baseof.html layouts/_default/baseof.html]
AMP single pageAMPhtml[layouts/posts/single.amp.html layouts/posts/single.html layouts/_default/single.amp.html layouts/_default/single.html]
AMP single page, French languageAMPhtml[layouts/posts/single.fr.amp.html layouts/posts/single.amp.html layouts/posts/single.fr.html layouts/posts/single.html layouts/_default/single.fr.amp.html layouts/_default/single.amp.html layouts/_default/single.fr.html layouts/_default/single.html]
Home pageHTMLhtml[layouts/index.html.html layouts/home.html.html layouts/list.html.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/index.html.html layouts/_default/home.html.html layouts/_default/list.html.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
Base template for home pageHTMLhtml[layouts/index-baseof.html.html layouts/home-baseof.html.html layouts/list-baseof.html.html layouts/baseof.html.html layouts/index-baseof.html layouts/home-baseof.html layouts/list-baseof.html layouts/baseof.html layouts/_default/index-baseof.html.html layouts/_default/home-baseof.html.html layouts/_default/list-baseof.html.html layouts/_default/baseof.html.html layouts/_default/index-baseof.html layouts/_default/home-baseof.html layouts/_default/list-baseof.html layouts/_default/baseof.html]
Home page with type setHTMLhtml[layouts/demotype/index.html.html layouts/demotype/home.html.html layouts/demotype/list.html.html layouts/demotype/index.html layouts/demotype/home.html layouts/demotype/list.html layouts/index.html.html layouts/home.html.html layouts/list.html.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/index.html.html layouts/_default/home.html.html layouts/_default/list.html.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
Base template for home page with type setHTMLhtml[layouts/demotype/index-baseof.html.html layouts/demotype/home-baseof.html.html layouts/demotype/list-baseof.html.html layouts/demotype/baseof.html.html layouts/demotype/index-baseof.html layouts/demotype/home-baseof.html layouts/demotype/list-baseof.html layouts/demotype/baseof.html layouts/index-baseof.html.html layouts/home-baseof.html.html layouts/list-baseof.html.html layouts/baseof.html.html layouts/index-baseof.html layouts/home-baseof.html layouts/list-baseof.html layouts/baseof.html layouts/_default/index-baseof.html.html layouts/_default/home-baseof.html.html layouts/_default/list-baseof.html.html layouts/_default/baseof.html.html layouts/_default/index-baseof.html layouts/_default/home-baseof.html layouts/_default/list-baseof.html layouts/_default/baseof.html]
Home page with layout setHTMLhtml[layouts/demolayout.html.html layouts/index.html.html layouts/home.html.html layouts/list.html.html layouts/demolayout.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/demolayout.html.html layouts/_default/index.html.html layouts/_default/home.html.html layouts/_default/list.html.html layouts/_default/demolayout.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
AMP home, French languageAMPhtml[layouts/index.fr.amp.html layouts/home.fr.amp.html layouts/list.fr.amp.html layouts/index.amp.html layouts/home.amp.html layouts/list.amp.html layouts/index.fr.html layouts/home.fr.html layouts/list.fr.html layouts/index.html layouts/home.html layouts/list.html layouts/_default/index.fr.amp.html layouts/_default/home.fr.amp.html layouts/_default/list.fr.amp.html layouts/_default/index.amp.html layouts/_default/home.amp.html layouts/_default/list.amp.html layouts/_default/index.fr.html layouts/_default/home.fr.html layouts/_default/list.fr.html layouts/_default/index.html layouts/_default/home.html layouts/_default/list.html]
JSON homeJSONjson[layouts/index.json.json layouts/home.json.json layouts/list.json.json layouts/index.json layouts/home.json layouts/list.json layouts/_default/index.json.json layouts/_default/home.json.json layouts/_default/list.json.json layouts/_default/index.json layouts/_default/home.json layouts/_default/list.json]
RSS homeRSSxml[layouts/index.rss.xml layouts/home.rss.xml layouts/rss.xml layouts/list.rss.xml layouts/index.xml layouts/home.xml layouts/list.xml layouts/_default/index.rss.xml layouts/_default/home.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/index.xml layouts/_default/home.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
RSS section postsRSSxml[layouts/posts/section.rss.xml layouts/posts/rss.xml layouts/posts/list.rss.xml layouts/posts/section.xml layouts/posts/list.xml layouts/section/section.rss.xml layouts/section/rss.xml layouts/section/list.rss.xml layouts/section/section.xml layouts/section/list.xml layouts/_default/section.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/section.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
Taxonomy in categoriesRSSxml[layouts/categories/category.terms.rss.xml layouts/categories/terms.rss.xml layouts/categories/taxonomy.rss.xml layouts/categories/rss.xml layouts/categories/list.rss.xml layouts/categories/category.terms.xml layouts/categories/terms.xml layouts/categories/taxonomy.xml layouts/categories/list.xml layouts/category/category.terms.rss.xml layouts/category/terms.rss.xml layouts/category/taxonomy.rss.xml layouts/category/rss.xml layouts/category/list.rss.xml layouts/category/category.terms.xml layouts/category/terms.xml layouts/category/taxonomy.xml layouts/category/list.xml layouts/taxonomy/category.terms.rss.xml layouts/taxonomy/terms.rss.xml layouts/taxonomy/taxonomy.rss.xml layouts/taxonomy/rss.xml layouts/taxonomy/list.rss.xml layouts/taxonomy/category.terms.xml layouts/taxonomy/terms.xml layouts/taxonomy/taxonomy.xml layouts/taxonomy/list.xml layouts/_default/category.terms.rss.xml layouts/_default/terms.rss.xml layouts/_default/taxonomy.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/category.terms.xml layouts/_default/terms.xml layouts/_default/taxonomy.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
Term in categoriesRSSxml[layouts/categories/term.rss.xml layouts/categories/category.rss.xml layouts/categories/taxonomy.rss.xml layouts/categories/rss.xml layouts/categories/list.rss.xml layouts/categories/term.xml layouts/categories/category.xml layouts/categories/taxonomy.xml layouts/categories/list.xml layouts/term/term.rss.xml layouts/term/category.rss.xml layouts/term/taxonomy.rss.xml layouts/term/rss.xml layouts/term/list.rss.xml layouts/term/term.xml layouts/term/category.xml layouts/term/taxonomy.xml layouts/term/list.xml layouts/taxonomy/term.rss.xml layouts/taxonomy/category.rss.xml layouts/taxonomy/taxonomy.rss.xml layouts/taxonomy/rss.xml layouts/taxonomy/list.rss.xml layouts/taxonomy/term.xml layouts/taxonomy/category.xml layouts/taxonomy/taxonomy.xml layouts/taxonomy/list.xml layouts/category/term.rss.xml layouts/category/category.rss.xml layouts/category/taxonomy.rss.xml layouts/category/rss.xml layouts/category/list.rss.xml layouts/category/term.xml layouts/category/category.xml layouts/category/taxonomy.xml layouts/category/list.xml layouts/_default/term.rss.xml layouts/_default/category.rss.xml layouts/_default/taxonomy.rss.xml layouts/_default/rss.xml layouts/_default/list.rss.xml layouts/_default/term.xml layouts/_default/category.xml layouts/_default/taxonomy.xml layouts/_default/list.xml layouts/_internal/_default/rss.xml]
Section list for “posts” sectionHTMLhtml[layouts/posts/posts.html.html layouts/posts/section.html.html layouts/posts/list.html.html layouts/posts/posts.html layouts/posts/section.html layouts/posts/list.html layouts/section/posts.html.html layouts/section/section.html.html layouts/section/list.html.html layouts/section/posts.html layouts/section/section.html layouts/section/list.html layouts/_default/posts.html.html layouts/_default/section.html.html layouts/_default/list.html.html layouts/_default/posts.html layouts/_default/section.html layouts/_default/list.html]
Section list for “posts” section with type set to “blog”HTMLhtml[layouts/blog/posts.html.html layouts/blog/section.html.html layouts/blog/list.html.html layouts/blog/posts.html layouts/blog/section.html layouts/blog/list.html layouts/posts/posts.html.html layouts/posts/section.html.html layouts/posts/list.html.html layouts/posts/posts.html layouts/posts/section.html layouts/posts/list.html layouts/section/posts.html.html layouts/section/section.html.html layouts/section/list.html.html layouts/section/posts.html layouts/section/section.html layouts/section/list.html layouts/_default/posts.html.html layouts/_default/section.html.html layouts/_default/list.html.html layouts/_default/posts.html layouts/_default/section.html layouts/_default/list.html]
Section list for “posts” section with layout set to “demoLayout”HTMLhtml[layouts/posts/demolayout.html.html layouts/posts/posts.html.html layouts/posts/section.html.html layouts/posts/list.html.html layouts/posts/demolayout.html layouts/posts/posts.html layouts/posts/section.html layouts/posts/list.html layouts/section/demolayout.html.html layouts/section/posts.html.html layouts/section/section.html.html layouts/section/list.html.html layouts/section/demolayout.html layouts/section/posts.html layouts/section/section.html layouts/section/list.html layouts/_default/demolayout.html.html layouts/_default/posts.html.html layouts/_default/section.html.html layouts/_default/list.html.html layouts/_default/demolayout.html layouts/_default/posts.html layouts/_default/section.html layouts/_default/list.html]
Taxonomy list in categoriesHTMLhtml[layouts/categories/category.terms.html.html layouts/categories/terms.html.html layouts/categories/taxonomy.html.html layouts/categories/list.html.html layouts/categories/category.terms.html layouts/categories/terms.html layouts/categories/taxonomy.html layouts/categories/list.html layouts/category/category.terms.html.html layouts/category/terms.html.html layouts/category/taxonomy.html.html layouts/category/list.html.html layouts/category/category.terms.html layouts/category/terms.html layouts/category/taxonomy.html layouts/category/list.html layouts/taxonomy/category.terms.html.html layouts/taxonomy/terms.html.html layouts/taxonomy/taxonomy.html.html layouts/taxonomy/list.html.html layouts/taxonomy/category.terms.html layouts/taxonomy/terms.html layouts/taxonomy/taxonomy.html layouts/taxonomy/list.html layouts/_default/category.terms.html.html layouts/_default/terms.html.html layouts/_default/taxonomy.html.html layouts/_default/list.html.html layouts/_default/category.terms.html layouts/_default/terms.html layouts/_default/taxonomy.html layouts/_default/list.html]
Taxonomy term in categoriesHTMLhtml[layouts/categories/term.html.html layouts/categories/category.html.html layouts/categories/taxonomy.html.html layouts/categories/list.html.html layouts/categories/term.html layouts/categories/category.html layouts/categories/taxonomy.html layouts/categories/list.html layouts/term/term.html.html layouts/term/category.html.html layouts/term/taxonomy.html.html layouts/term/list.html.html layouts/term/term.html layouts/term/category.html layouts/term/taxonomy.html layouts/term/list.html layouts/taxonomy/term.html.html layouts/taxonomy/category.html.html layouts/taxonomy/taxonomy.html.html layouts/taxonomy/list.html.html layouts/taxonomy/term.html layouts/taxonomy/category.html layouts/taxonomy/taxonomy.html layouts/taxonomy/list.html layouts/category/term.html.html layouts/category/category.html.html layouts/category/taxonomy.html.html layouts/category/list.html.html layouts/category/term.html layouts/category/category.html layouts/category/taxonomy.html layouts/category/list.html layouts/_default/term.html.html layouts/_default/category.html.html layouts/_default/taxonomy.html.html layouts/_default/list.html.html layouts/_default/term.html layouts/_default/category.html layouts/_default/taxonomy.html layouts/_default/list.html]

​ Hugo 现在还可以检测 partials 的媒体类型和输出格式(如果可能的话),并使用这些信息来决定是否将 partial 解析为纯文本模板。

​ Hugo将查找给定的名称,因此您可以根据需要随意命名它。但是,如果要将其视为纯文本,请使用文件后缀,如果需要,还要使用输出格式的名称。 模式如下:

1
[partial name].[OutputFormat].[suffix]

​ 以下 partial 是一个纯文本模板(输出格式为 CSV,由于这是唯一带有后缀 csv 的输出格式,因此我们不需要包含输出格式的Name):

1
{{ partial "mytextpartial.csv" . }}

另请参阅

6.4 - 基础模板和块

Base Templates and Blocks - 基础模板和块

https://gohugo.io/templates/base/

​ 基本模板和块结构允许您定义主模板的外壳(即页面的Chrome)。

block关键字允许您定义页面一个或多个主模板的外壳,然后根据需要填充或覆盖部分(portions )。

基础模板查找顺序

​ 基础模板查找顺序紧跟它所应用的模板的查找顺序(例如,_default/list.html)。

​ 有关详细信息和示例,请参见模板查找顺序

定义基础模板

​ 以下定义了一个简单的基础模板 _default/baseof.html。作为默认模板,它是从所有页面渲染的外壳,除非您在查找顺序的开头指定另一个*baseof.html

layouts/_default/baseof.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>{{ block "title" . }}
      <!-- Blocks may include default content. -->
      {{ .Site.Title }}
    {{ end }}</title>
  </head>
  <body>
    <!-- Code that all your templates share, like a header -->
    {{ block "main" . }}
      <!-- The part of the page that begins to differ between templates -->
    {{ end }}
    {{ block "footer" . }}
    <!-- More shared code, perhaps a footer but that can be overridden if need be in  -->
    {{ end }}
  </body>
</html>

覆盖基础模板

​ 从上面的基本模板,您可以定义默认的列表模板。默认的列表模板将继承上面定义的所有代码,然后可以根据需要实现自己的"main"块:

layouts/_default/list.html

1
2
3
4
5
6
7
8
9
{{ define "main" }}
  <h1>Posts</h1>
  {{ range .Pages }}
    <article>
      <h2>{{ .Title }}</h2>
      {{ .Content }}
    </article>
  {{ end }}
{{ end }}

​ 这将用实际有用的内容替换我们(基本上为空的)"main"块的内容,对于列表中的内容,我们没有定义"title"块,因此在列表中保留了来自基础模板的内容。

​ 放置在块定义之外的代码会破坏您的布局,这甚至包括HTML注释。例如:

1
2
3
4
<!-- Seemingly harmless HTML comment..that will break your layout at build -->
{{ define "main" }}
...your code here
{{ end }}

请参见Hugo讨论论坛中的此主题

​ 以下显示了如何使用特定于默认单个页面模板的代码覆盖基础模板的"main""title"块区域:

layouts/_default/single.html

1
2
3
4
5
6
7
8
{{ define "title" }}
  <!-- This will override the default value set in baseof.html; i.e., "{{ .Site.Title }}" in the original example-->
  {{ .Title }} &ndash; {{ .Site.Title }}
{{ end }}
{{ define "main" }}
  <h1>{{ .Title }}</h1>
  {{ .Content }}
{{ end }}

另请参阅

6.5 - Markdown渲染钩子

Markdown Render Hooks - Markdown渲染钩子

https://gohugo.io/templates/render-hooks/

​ 渲染钩子允许自定义模板覆盖markdown渲染功能。

​ 请注意,这只支持Goldmark渲染器。

​ 您可以通过在layouts/_default/_markup中创建名称为render-{kind}的模板来覆盖默认的Markdown渲染为HTML的某些部分。

​ 您还可以在layouts/[type/section]/_markup中创建特定于type/section的钩子,例如:layouts/blog/_markup

​ 目前支持的钩子种类有:

​ 如果需要,您可以定义特定于输出格式语言的模板。您的layouts文件夹可能如下所示:

1
2
3
4
5
6
7
8
9
layouts/
└── _default/
    └── _markup/
        ├── render-codeblock-bash.html
        ├── render-codeblock.html
        ├── render-heading.html
        ├── render-image.html
        ├── render-image.rss.xml
        └── render-link.html

​ 以下是上述用法的一些示例:

  • 使用.GetPage解析链接引用。这将使链接可移植,因为您可以将./my-post.md(和在GitHub上可以使用的类似构造)转换为/blog/2019/01/01/my-post/等。
  • 为外部链接添加target=_blank
  • 解析和处理图像。
  • 添加标题链接

渲染钩子应用于标题、链接和图像

传递给render-linkrender-image的上下文

render-linkrender-image模板将接收到以下上下文:

  • Page

    正在被渲染的Page

  • Destination

    The URL.

  • Title

    title属性。

  • Text

    渲染后的(HTML)链接文本。

  • PlainText

    上述文本的纯文本版本。

传递给render-heading的上下文

render-heading模板将接收以下上下文:

  • Page

    正在被渲染的页面

  • Level

    标题级别(1-6)

  • Anchor

    在该页面中唯一的自动生成的HTML id。

  • Text

    被渲染后的(HTML)文本。

  • PlainText

    上述内容的纯文本版本。

  • Attributes (map)

    一个属性映射(例如idclass)。需要注意的是,对于链接,这个映射目前始终为空。

The render-image templates will also receive:

render-image模板还将接收:

带标题的Markdown链接示例

1
[Text](https://www.gohugo.io "Title")

​ 以下是render-link.html模板的代码示例:

layouts/_default/_markup/render-link.html

1
<a href="{{ .Destination | safeURL }}"{{ with .Title }} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener"{{ end }}>{{ .Text | safeHTML }}</a>

图像Markdown示例

1
![Text](https://gohugo.io/images/hugo-logo-wide.svg "Title")

​ 以下是render-image.html模板的代码示例:

layouts/_default/_markup/render-image.html

1
2
3
<p class="md__image">
  <img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title }} title="{{ . }}"{{ end }} />
</p>

标题链接示例

​ 给定此模板文件

layouts/_default/_markup/render-heading.html

1
<h{{ .Level }} id="{{ .Anchor | safeURL }}">{{ .Text | safeHTML }} <a href="#{{ .Anchor | safeURL }}">¶</a></h{{ .Level }}>

​ 以及这个 markdown

1
### Section A

​ 渲染出的 HTML 代码将是

1
<h3 id="section-a">Section A <a href="#section-a">¶</a></h3>

代码块的渲染钩子

New in v0.93.0

​ 您可以为所有代码块或特定类型/语言(例如下面的bash)添加钩子模板:

image-20230425200136050

​ 这些代码块的默认行为是进行代码高亮,但是由于可以向这些代码块传递属性,因此它们可以用于几乎任何事情。一个示例是内置的GoAT Diagrams或这个Mermaid Diagram Code Block Hook示例。

​ 代码块模板中您可以获取到的上下文(".")包括:

  • Type (string)

    代码块的类型。这将是编程语言,例如bash,用于进行代码高亮。

  • Attributes (map)

    从Markdown传递的属性(例如{ attrName1=attrValue1 attrName2="attr Value 2" })。

  • Options (map)

    Chroma 高亮处理选项。仅在 Type 是已知的 Chroma Lexer 时才填充。

  • Inner (string)

    代码围栏之间的文本。

  • Ordinal (integer)

    当前文档中所有代码块的从零开始的序数。

  • Page

    所属的Page

  • Position

    在错误日志中有用,因为它会打印出文件名和位置(行号、列号),例如 {{ errorf "error in code block: %s" .Position }}

另请参阅

6.6 - 在Hugo中的内容列表

Lists of Content in Hugo - 在Hugo中的内容列表

https://gohugo.io/templates/lists/

​ 列表在 Hugo 中在渲染站点主页、章节页面、分类列表或分类术语列表时具有特定的含义和用法。

什么是列表页面模板?

​ 列表页面模板是用于在单个 HTML 页面中渲染多个内容的模板。唯一的例外是主页,它仍然是一个列表,但有自己的专用模板

​ Hugo 在其最真实的意义上使用列表这个术语;即按字母或数字顺序的一系列材料。Hugo 在任何传统上列出内容的输出 HTML 页面上都使用列表模板:

​ 有关模板查找顺序,请参见模板查找

​ 列表页面的概念源于Web的分层心理模型,最好通过可视化进行演示:

Image demonstrating a hierarchical website sitemap.

列表默认值

默认模板

​ 由于章节列表和分类列表(注意,不是分类术语列表)在模板方面都是列表,因此它们在查找顺序中都有相同的终止默认值 _default/list.htmlthemes/<THEME>/layouts/_default/list.html。此外,章节列表分类列表_default 中都有自己的默认列表模板。

​ 有关完整参考,请参阅模板查找顺序

将内容和前置元数据添加到列表页

​ 自从 v0.18 以来,Hugo 中的所有内容都是Page。这意味着列表页面和主页可以有关联的内容文件(即_index.md),其中包含页面元数据(即前置元数据)和内容。

​ 这种新模型允许您通过 .Params 包含特定于列表的前置元数据,并且意味着列表模板(例如 layouts/_default/list.html)可以访问所有页面变量

​ 重要的是要注意,所有 _index.md 内容文件都将根据列表模板而不是单个页面模板进行渲染。

示例项目目录

​ 以下是一个典型的Hugo项目的content目录的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.
...
├── content
|   ├── posts
|   |   ├── _index.md
|   |   ├── post-01.md
|   |   └── post-02.md
|   └── quote
|   |   ├── quote-01.md
|   |   └── quote-02.md
...

​ 使用上述示例,假设您在content/posts/_index.md中有以下内容:

content/posts/_index.md

1
2
3
4
5
6
7
8
9
---
title: My Go Journey
date: 2017-03-23
publishdate: 2017-03-24
---

I decided to start learning Go in March 2017.

Follow my journey through this new blog.

​ 现在,您可以在列表模板中访问此_index.md的内容:

layouts/_default/list.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{{ define "main" }}
<main>
  <article>
    <header>
      <h1>{{ .Title} }</h1>
    </header>
    <!-- "{{ .Content} }" pulls from the markdown content of the corresponding _index.md -->
    {{ .Content }}
  </article>
  <ul>
    <!-- Ranges through content/posts/*.md -->
    {{ range .Pages }}
      <li>
        <a href="{{ .Permalink }}">{{ .Date.Format "2006-01-02" }} | {{ .Title }}</a>
      </li>
    {{ end }}
  </ul>
</main>
{{ end }}

​ 上面将输出以下 HTML:

example.com/posts/index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!--top of your baseof code-->
<main>
    <article>
        <header>
            <h1>My Go Journey</h1>
        </header>
        <p>I decided to start learning Go in March 2017.</p>
        <p>Follow my journey through this new blog.</p>
    </article>
    <ul>
        <li><a href="/posts/post-01/">Post 1</a></li>
        <li><a href="/posts/post-02/">Post 2</a></li>
    </ul>
</main>
<!--bottom of your baseof-->

没有 _index.md 的列表页面

​ 您不必为每个列表页面(即章节、分类、分类术语等)或主页创建 _index.md 文件。如果 Hugo 在渲染列表模板时在相应的内容章节中找不到 _index.md,则将创建该页面,但没有 {{ .Content }},只有 .Title 等的默认值。

​ 将相同的 layouts/_default/list.html 模板应用于上面的 quotes 章节将渲染以下输出。请注意,quotes 没有可供提取的 _index.md 文件:

example.com/quote/index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!--baseof-->
<main>
    <article>
        <header>
        <!-- Hugo assumes that .Title is the name of the section since there is no _index.md content file from which to pull a "title:" field -->
            <h1>Quotes</h1>
        </header>
    </article>
    <ul>
        <li><a href="https://example.com/quote/quotes-01/">Quote 1</a></li>
        <li><a href="https://example.com/quote/quotes-02/">Quote 2</a></li>
    </ul>
</main>
<!--baseof-->

默认情况下,Hugo会将列表标题进行复数化处理,因此在使用 .Title 页面变量时,quote部分会变为"Quotes"。您可以通过在站点配置中使用pluralizeListTitles指令来更改此设置。

示例列表模板

章节模板

​ 这个列表模板是从spf13.com的模板进行了略微修改。它使用局部模板来渲染页面的外壳,而不是使用基础模板。下面的示例还使用了内容视图模板 li.htmlsummary.html

layouts/section/posts.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{{ partial "header.html" . }}
{{ partial "subheader.html" . }}
<main>
  <div>
   <h1>{{ .Title }}</h1>
        <ul>
        <!-- Renders the li.html content view for each content/posts/*.md -->
            {{ range .Pages }}
                {{ .Render "li" }}
            {{ end }}
        </ul>
  </div>
</main>
{{ partial "footer.html" . }}

分类模板

layouts/_default/taxonomy.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{{ define "main" }}
<main>
  <div>
   <h1>{{ .Title }}</h1>
   <!-- ranges through each of the content files associated with a particular taxonomy term and renders the summary.html content view -->
    {{ range .Pages }}
        {{ .Render "summary" }}
    {{ end }}
  </div>
</main>
{{ end }}

内容排序

​ Hugo 根据您在前置元数据中提供的内容来渲染列表。除了合理的默认值外,Hugo 还提供了多种方法,以便在列表模板内快速进行内容排序:

Default: Weight > Date > LinkTitle > FilePath

layouts/partials/default-order.html

1
2
3
4
5
6
7
8
<ul>
    {{ range .Pages }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按权重

​ 较低的权重具有较高的优先级。因此,权重较低的内容将排在前面。

layouts/partials/by-weight.html

1
2
3
4
5
6
7
8
<ul>
    {{ range .Pages.ByWeight }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按日期

layouts/partials/by-date.html

1
2
3
4
5
6
7
8
9
<ul>
    <!-- orders content according to the "date" field in front matter -->
    {{ range .Pages.ByDate }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按发布日期

layouts/partials/by-publish-date.html

1
2
3
4
5
6
7
8
9
<ul>
    <!-- orders content according to the "publishdate" field in front matter -->
    {{ range .Pages.ByPublishDate }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按到期日期

layouts/partials/by-expiry-date.html

1
2
3
4
5
6
7
8
<ul>
    {{ range .Pages.ByExpiryDate }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按最后修改日期

layouts/partials/by-last-mod.html

1
2
3
4
5
6
7
8
9
<ul>
    <!-- orders content according to the "lastmod" field in front matter -->
    {{ range .Pages.ByLastmod }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按长度

layouts/partials/by-length.html

1
2
3
4
5
6
7
8
9
<ul>
    <!-- orders content according to content length in ascending order (i.e., the shortest content will be listed first) -->
    {{ range .Pages.ByLength }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按标题

layouts/partials/by-title.html

1
2
3
4
5
6
7
8
9
<ul>
    <!-- ranges through content in ascending order according to the "title" field set in front matter -->
    {{ range .Pages.ByTitle }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按链接标题

layouts/partials/by-link-title.html

1
2
3
4
5
6
7
8
9
<ul>
    <!-- ranges through content in ascending order according to the "linktitle" field in front matter. If a "linktitle" field is not set, the range will start with content that only has a "title" field and use that value for .LinkTitle -->
    {{ range .Pages.ByLinkTitle }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .LinkTitle }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按参数

​ 根据指定的前置元数据参数进行排序。如果内容没有指定的前置元数据字段,则使用站点的 .Site.Params 默认值。如果在某些条目中根本找不到该参数,这些条目将一起出现在排序的末尾。

layouts/partials/by-rating.html

1
2
3
4
<!-- Ranges through content according to the "rating" field set in front matter -->
{{ range (.Pages.ByParam "rating") }}
  <!-- ... -->
{{ end }}

​ 如果目标的前置元数据字段嵌套在另一个字段下,则您可以使用点表示法来访问该字段。

layouts/partials/by-nested-param.html

1
2
3
{{ range (.Pages.ByParam "author.last_name") }}
  <!-- ... -->
{{ end }}

倒序排序

​ 可以将倒序排序应用于上述任何一种方法。以下示例以 ByDate 为例:

layouts/partials/by-date-reverse.html

1
2
3
4
5
6
7
8
<ul>
    {{ range .Pages.ByDate.Reverse }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

分组内容

​ Hugo 提供一些函数,可按章节、类型、日期等对页面进行分组。

按页面字段

layouts/partials/by-page-field.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Groups content according to content section. The ".Key" in this instance will be the section's title. -->
{{ range .Pages.GroupBy "Section" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

​ 在上面的例子中,您可能希望 {{ .Title }} 指向您已添加到 _index.md 文件中的title字段。您可以使用 .GetPage 函数来访问此值:

layouts/partials/by-page-field.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!-- Groups content according to content section.-->
{{ range .Pages.GroupBy "Section" }}
<!-- Checks for existence of _index.md for a section; if available, pulls from "title" in front matter -->
{{ with $.Site.GetPage "section" .Key }}
<h3>{{ .Title }}</h3>
{{ else }}
<!-- If no _index.md is available, ".Key" defaults to the section title and filters to title casing -->
<h3>{{ .Key | title }}</h3>
{{ end }}
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

按日期

layouts/partials/by-page-date.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Groups content by month according to the "date" field in front matter -->
{{ range .Pages.GroupByDate "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

在新版本 v0.97.0 中GroupByDate 函数接受与 time.Format 中相同的时间格式,并且结果中的 .Key 会根据当前语言进行本地化。

按发布日期

layouts/partials/by-page-publish-date.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Groups content by month according to the "publishDate" field in front matter -->
{{ range .Pages.GroupByPublishDate "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .PublishDate.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

在新版本 v0.97.0 中GroupByDate 函数接受与 time.Format 中相同的时间格式,并且结果中的 .Key 会根据当前语言进行本地化。

按照上次修改时间

layouts/partials/by-page-lastmod.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Groups content by month according to the "lastMod" field in front matter -->
{{ range .Pages.GroupByLastmod "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Lastmod.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

在新版本 v0.97.0 中GroupByDate 函数接受与 time.Format 中相同的时间格式,并且结果中的 .Key 会根据当前语言进行本地化。

按过期日期

layouts/partials/by-page-expiry-date.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Groups content by month according to the "expiryDate" field in front matter -->
{{ range .Pages.GroupByExpiryDate "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .ExpiryDate.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

在新版本 v0.97.0 中GroupByDate 函数接受与 time.Format 中相同的时间格式,并且结果中的 .Key 会根据当前语言进行本地化。

按照页面参数

layouts/partials/by-page-param.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Groups content according to the "param_key" field in front matter -->
{{ range .Pages.GroupByParam "param_key" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

按照页面参数和日期格式

​ 在按date分组的模板中,使用了 Go 的布局字符串来进一步分组。有关如何使用 Go 的布局字符串格式化 Hugo 中的日期的更多示例,请参见 Format 函数

layouts/partials/by-page-param-as-date.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- Groups content by month according to the "param_key" field in front matter -->
{{ range .Pages.GroupByParamDate "param_key" "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

反向键顺序

​ 分组的排序是按字母数字顺序的键进行排序(A-Z、1-100),并按照日期的逆序排列(即,最新的日期排在最前面)。

​ 虽然这些是逻辑上的默认值,但并不总是期望的排序。有两种不同的语法可以更改 Hugo 的默认分组排序,它们都以相同的方式工作。

1. 添加 Reverse 方法

1
2
{{ range (.Pages.GroupBy "Section").Reverse }}
{{ range (.Pages.GroupByDate "2006-01").Reverse }}

2. 提供另一种方向

1
2
{{ range .Pages.GroupByDate "2006-01" "asc" }}
{{ range .Pages.GroupBy "Section" "desc" }}

组内排序

​ 由于Grouping返回一个{{ .Key }}和一个页面片段,因此上述所有排序方法都可用。

​ 以下是示例的排序方式:

  1. 根据前置元数据中的date字段按月份分组内容。
  2. 按升序列出分组(即最旧的分组先列出)。
  3. 每个分组内的页面根据title按字母顺序排序。

layouts/partials/by-group-by-page.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{{ range .Pages.GroupByDate "2006-01" "asc" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages.ByTitle }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

筛选和限制列表

​ 有时,您只想列出可用内容的子集。一个常见的方法是仅在博客主页上显示主要章节的文章。

​ 有关详细信息,请参见where函数first函数的文档。

另请参阅

6.7 - 主页模板

Homepage Template - 主页模板

https://gohugo.io/templates/homepage/

​ 站点的主页通常与其他页面格式不同。因此,Hugo 使您能够轻松地将新站点的主页定义为独特的模板。

​ 主页是一个Page,因此可使用所有页面变量站点变量

​ 主页模板是构建站点所必需的唯一模板,因此在启动新站点和模板时非常有用。如果您正在开发单页面站点,则它也是唯一必需的模板。

主页模板查找顺序

​ 请参见模板查找

向主页添加内容和前置元数据

​ 主页与 Hugo 中的其他列表页面类似,可以从 _index.md 文件接受内容和 前置元数据。该文件应该位于您的 content 文件夹的根目录下(即 content/_index.md)。然后,您可以像处理其他任何内容文件一样向主页添加正文和元数据(metadata )。

​ 有关如何使用 _index.md 向列表页面添加内容和前置元数据的更多信息,请参见下面的主页模板或内容组织

示例主页模板

​ 以下是一个主页模板示例,它使用 partial基础模板和位于 content/_index.md 中的内容文件来填充 {{ .Title }}{{ .Content }} 页面变量

layouts/index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{{ define "main" }}
  <main aria-role="main">
    <header class="homepage-header">
      <h1>{{ .Title }}</h1>
      {{ with .Params.subtitle }}
      <span class="subtitle">{{ . }}</span>
      {{ end }}
    </header>
    <div class="homepage-content">
      <!-- Note that the content for index.html, as a sort of list page, will pull from content/_index.md -->
      {{ .Content }}
    </div>
    <div>
      {{ range first 10 .Site.RegularPages }}
          {{ .Render "summary" }}
      {{ end }}
    </div>
  </main>
{{ end }}

6.8 - 分类法(Taxonomy)模板

Taxonomy Templates - 分类法(Taxonomy)模板

https://gohugo.io/templates/taxonomy-templates/

​ Taxonomy(分类法)模板包括分类法列表页面、分类法条目页面以及在单页模板中使用分类法。

​ Hugo 支持用户定义的内容分组,称为分类法。分类法是展示内容之间逻辑关系的分类法方法。如果您对 Hugo 如何利用这个强大功能不熟悉,请参见内容管理下的分类法

​ Hugo 提供了多种在项目模板中使用分类法的方式:

分类法列表模板

​ 分类法列表页面模板是列表,因此具有可用于列表页面的所有变量和方法。

分类法列表模板查找顺序

​ 请参见模板查找

分类法条目模板

分类法条目模板查找顺序

​ 请参见模板查找

分类法方法

A Taxonomy is a map[string]WeightedPages.

​ 分类法是一个 map[string]WeightedPages

  • .Get(term)

    返回条目的 WeightedPages。

  • .Count(term)

    分配给该条目的内容数量。

  • .Alphabetical

    Returns an OrderedTaxonomy (slice) ordered by Term.

    返回一个按条目排序的 OrderedTaxonomy(切片)。

  • .ByCount

    返回一个按条目数量排序的 OrderedTaxonomy(切片)。

  • .Reverse

    返回一个按相反顺序排序的 OrderedTaxonomy(切片)。必须与 一个OrderedTaxonomy 一起使用。

OrderedTaxonomy

​ 由于 Map 是无序的,因此 OrderedTaxonomy 是一个具有定义顺序的特殊结构。

1
2
3
4
[]struct {
    Name          string
    WeightedPages WeightedPages
}

​ 该切片的每个元素都有:

  • .Term

    使用的条目。

  • .WeightedPages

    一个加权页面的切片。

  • .Count

    分配给该条目的内容数量。

  • .Pages

    分配给该条目的所有页面。所有列表方法都可用于此。

WeightedPages

​ WeightedPages是WeightedPage的一个切片。

1
type WeightedPages []WeightedPage
  • .Count(term)

    被分配到此条目的内容数量。

  • .Pages

    返回一个页面的切片,可以使用任何 列表方法 进行排序。

在分类法条目模板中显示自定义元数据

​ 如果您需要为每个分类法条目显示自定义元数据,您需要在/content/<TAXONOMY>/<TERM>/_index.md路径下为该条目创建一个页面,并在其前置元数据中添加元数据,如分类法文档中所述。以其中显示的演员分类法为例,在您的分类法条目模板中,您可以通过迭代变量.Pages来访问您的自定义字段:

1
2
3
4
5
6
7
8
<ul>
    {{ range .Pages }}
        <li>
            <a href="{{ .Permalink }}">{{ .Title }}</a>
            {{ .Params.wikipedia }}
        </li>
    {{ end }}
</ul>

排序分类法

​ 分类法可以按字母键或分配给该键的内容数量排序。

按字母顺序示例

1
2
3
4
5
<ul>
    {{ range .Data.Terms.Alphabetical }}
            <li><a href="{{ .Page.Permalink }}">{{ .Page.Title }}</a> {{ .Count }}</li>
    {{ end }}
</ul>

在分类法中排序内容

​ Hugo在分类法中使用dateweight来排序内容。

​ 在 Hugo 中,每篇内容可以选择性地被分配一个日期。它也可以为每个所属分类法分配一个权重。

​ 当在分类法中迭代内容时,默认排序方式与用于章节和列表页面相同:首先按权重,然后按日期排序。这意味着,如果两篇内容的权重相同,则最近日期的内容将首先显示。

​ 任何一篇内容的默认权重为0。零意味着"does not have a weight",而不是"has a weight of numerical value zero"。

​ 因此,权重为零的条目被特殊处理:如果两个页面的权重不相等,并且其中一个是零,则具有零权重的页面将始终出现在另一个页面之后,而不用考虑另一个页面的权重。因此,应谨慎使用零权重:例如,如果正权重和负权重都用于在两个方向上扩展序列,则具有零权重的页面将不会出现在列表的中间,而是在末尾。

分配权重

​ 每个内容可以分别为它所属的每个分类法(taxonomies)赋予一个权重(weight)。

content/example.md

=== “yaml”

``` yaml
---
categories:
- d
categories_weight: 44
tags:
- a
- b
- c
tags_weight: 22
title: Example
---
```

=== “toml”

``` toml
+++
categories = ['d']
categories_weight = 44
tags = ['a', 'b', 'c']
tags_weight = 22
title = 'Example'
+++
```

=== “json”

``` json
{
   "categories": [
      "d"
   ],
   "categories_weight": 44,
   "tags": [
      "a",
      "b",
      "c"
   ],
   "tags_weight": 22,
   "title": "Example"
}
```

​ 惯例是使用taxonomyname_weight

​ 在上面的例子中,这篇内容在渲染分配给"tag" 分类法中的"a"、“b” 和 “c” 值的页面时具有22的权重。

​ 在渲染’d’类别时,它还被赋予了44的权重。

​ 这样做可以使同一篇内容在不同的分类法中出现在不同的位置。

​ 目前,分类法仅支持默认的内容排序方式,即权重->日期。

​ 使用分类法将需要提供两种不同的模板。

​ 这两中模板在模板章节中都有详细介绍。

列表模板是用于在单个HTML页面中渲染多篇内容的任一模板。此模板将用于生成所有自动创建的分类法页面。

分类法模板是用于生成给定模板的条目列表的模板。

​ 除了使用 Hugo 自动生成的 列表模板 来创建分类法页面外,还有四种常见的方式可以展示您的分类法数据:

  1. 对于给定篇的内容,您可以列出附加的条目
  2. 对于给定篇的内容,您可以列出具有相同条目的其他内容
  3. 您可以列出某一分类法的所有条目
  4. 您可以列出所有分类法(及其条目)

显示单篇内容的分类法

​ 在内容模板中,您可能希望显示分配给该内容的分类法。

​ 由于我们利用前置元数据系统为内容定义分类法,因此分配给每篇内容的分类法位于通常的位置(即 .Params.<TAXONOMYPLURAL>)。

示例:在单页模板中列出标签

1
2
3
4
5
<ul>
    {{ range (.GetTerms "tags") }}
        <li><a href="{{ .Permalink }}">{{ .LinkTitle }}</a></li>
    {{ end }}
</ul>

​ 如果您想要内联列出分类法,您将需要注意标题中的可选复数结尾(如果有多个分类法),以及逗号。假设我们有一个名为 “directors” 的分类法,如 TOML 格式的前置元数据所示:directors: [ "Joel Coen", "Ethan Coen" ]

​ 要列出这样的分类法,请使用以下方法:

示例:在单页模板中使用逗号分隔标签

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{{ $taxo := "directors" }} <!-- Use the plural form here -->
{{ with .Param $taxo }}
    <strong>Director{{ if gt (len .) 1 }}s{{ end }}:</strong>
    {{ range $index, $director := . }}
        {{- if gt $index 0 }}, {{ end -}}
        {{ with $.Site.GetPage (printf "/%s/%s" $taxo $director) -}}
            <a href="{{ .Permalink }}">{{ $director }}</a>
        {{- end -}}
    {{- end -}}
{{ end }}

​ 或者,如果只需要使用分隔符列出分类法,则可以使用delimit 模板函数作为快捷方式。详见GitHub上的#2143讨论。

列出具有相同分类法条目的内容

​ 如果您正在使用分类法来管理一系列文章,您可以列出与同一分类法相关联的各个页面。这也是一种快速粗略的方法来展示相关内容:

示例:显示同一系列的内容

1
2
3
4
5
<ul>
    {{ range .Site.Taxonomies.series.golang }}
        <li><a href="{{ .Page.RelPermalink }}">{{ .Page.Title }}</a></li>
    {{ end }}
</ul>

列出给定分类法中的所有内容

​ 这在侧边栏中作为"特色内容"将非常有用。您甚至可以通过为内容分配不同的条目来创建不同的"特色内容" 章节。

示例:对"Featured"内容进行分组

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<section id="menu">
    <ul>
        {{ range $key, $taxonomy := .Site.Taxonomies.featured }}
        <li>{{ $key }}</li>
        <ul>
            {{ range $taxonomy.Pages }}
            <li hugo-nav="{{ .RelPermalink }}"><a href="{{ .Permalink }}">{{ .LinkTitle }}</a></li>
            {{ end }}
        </ul>
        {{ end }}
    </ul>
</section>

渲染站点的分类法

​ 如果您希望显示站点分类法的所有键列表,可以从每个页面都可以访问的.Site变量中检索它们。

​ 这可以采用标签云、菜单或简单列表的形式。

​ 以下示例显示站点标签分类法中的所有条目:

示例:列出所有站点标签

1
2
3
4
5
<ul>
    {{ range .Site.Taxonomies.tags }}
            <li><a href="{{ .Page.Permalink }}">{{ .Page.Title }}</a> {{ .Count }}</li>
    {{ end }}
</ul>

示例:列出所有分类法、条目和分配的内容

​ 这个示例将列出所有分类法及其条目,以及分配给每个条目的所有内容。

layouts/partials/all-taxonomies.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<section>
    <ul id="all-taxonomies">
        {{ range $taxonomy_term, $taxonomy := .Site.Taxonomies }}
            {{ with $.Site.GetPage (printf "/%s" $taxonomy_term) }}
                <li><a href="{{ .Permalink }}">{{ $taxonomy_term }}</a>
                    <ul>
                        {{ range $key, $value := $taxonomy }}
                            <li>{{ $key }}</li>
                            <ul>
                                {{ range $value.Pages }}
                                    <li hugo-nav="{{ .RelPermalink }}">
                                        <a href="{{ .Permalink }}">{{ .LinkTitle }}</a>
                                    </li>
                                {{ end }}
                            </ul>
                        {{ end }}
                    </ul>
                </li>
            {{ end }}
        {{ end }}
    </ul>
</section>

.Site.GetPage 用于分类法

​ 由于分类法是列表,可以使用.GetPage函数使用简洁的语法获取与特定分类法条目相关联的所有页面。下面对站点上所有标签进行全面的遍历,并链接到每个条目的单独分类页面,而不必使用上面的"列出所有站点标签"示例中更脆弱的URL构建方法:

links-to-all-tags.html

1
2
3
4
5
6
7
8
{{ $taxo := "tags" }}
<ul class="{{ $taxo }}">
    {{ with ($.Site.GetPage (printf "/%s" $taxo)) }}
        {{ range .Pages }}
            <li><a href="{{ .Permalink }}">{{ .Title }}</a></li>
        {{ end }}
    {{ end }}
</ul>

另请参阅

6.9 - 章节页面模板

Section Page Templates - 章节页面模板

https://gohugo.io/templates/section-templates/

​ 用于章节页面的模板是列表,因此具有所有可用于列举页面的变量和方法。

向章节模板添加内容和前置元数据

​ 为了有效利用章节页面模板,您应首先了解Hugo的内容组织方式,特别是添加内容和前置元数据到章节和其他列表页面的_index.md文件的目的。

章节模板查找顺序

​ 请参见模板查找

页面种类

​ Hugo 中的每个Page都有一个 .Kind 属性。

KindDescriptionExample
home主页的着陆页/index.html
page指定页面的着陆页my-post page (/posts/my-post/index.html)
section指定章节的着陆页posts section (/posts/index.html)
taxonomy分类的着陆页tags taxonomy (/tags/index.html)
term某一分类条目的着陆页term awesome in tags taxonomy (/tags/awesome/index.html)

.Site.GetPage with Sections

.Kind可以轻松地与模板中的where函数结合使用,创建特定类型的内容列表。这种方法非常适合创建列表,但有时您可能想通过章节的路径获取单个章节的索引页面。

.GetPage函数查找给定Kindpath的索引页。

​ 您可以使用两个参数调用.Site.GetPagekind(上述有效Kind之一)和kind value

例如:

  • {{ .Site.GetPage "section" "posts" }}
  • {{ .Site.GetPage "page" "search" }}

示例:创建默认章节模板

layouts/_default/section.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{{ define "main" }}
  <main>
      {{ .Content }}
          <ul class="contents">
          {{ range .Paginator.Pages }}
              <li>{{ .Title }}
                  <div>
                    {{ partial "summary.html" . }}
                  </div>
              </li>
          {{ end }}
          </ul>
      {{ partial "pagination.html" . }}
  </main>
{{ end }}

示例:使用 .Site.GetPage

.Site.GetPage 的示例假设有以下项目目录结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
.
└── content
    ├── blog
    │   ├── _index.md # "title: My Hugo Blog" in the front matter
    │   ├── post-1.md
    │   ├── post-2.md
    │   └── post-3.md
    └── events #Note there is no _index.md file in "events"
        ├── event-1.md
        └── event-2.md

​ 如果没有找到 _index.md 页面,则 .Site.GetPage 将返回 nil。因此,如果 content/blog/_index.md 不存在,则该模板将输出该章节的名称:

1
<h1>{{ with .Site.GetPage "section" "blog" }}{{ .Title }}{{ end }}</h1>

​ 由于 blog 有一个带有前置元数据的章节索引页位于 content/blog/_index.md,因此上述代码将返回以下结果:

1
<h1>My Hugo Blog</h1>

​ 但如果我们尝试在 events 章节使用相同的代码,则 Hugo 会默认使用章节标题,因为没有 content/events/_index.md 可供提取内容和前置元数据:

1
<h1>{{ with .Site.GetPage "section" "events" }}{{ .Title }}{{ end }}</h1>

​ 然后返回以下结果:

1
<h1>Events</h1>

另请参阅

6.10 - 单页模板

Single Page Templates - 单页模板

​ 在 Hugo 中,内容的主要视图是单个视图。Hugo 会为每个 Markdown 文件提供相应的单个模板进行渲染。

单页模板查找顺序

​ 请参阅模板查找

单页模板示例

​ 内容页面的类型是 page,因此可以在它们的模板中使用所有 页面变量站点变量

posts/single.html

​ 这个单页模板使用了 Hugo 的 基础模板.Format 函数 来处理日期、.WordCount 页面变量 以及遍历单一内容的特定分类法with 也用来检查是否在前置元数据中设置了分类法。

layouts/posts/single.html

 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
34
35
36
37
38
39
40
41
{{ define "main" }}

<section id="main">
  <h1 id="title">{{ .Title }}</h1>
  <div>
    <article id="content">
      {{ .Content }}
    </article>
  </div>
</section>
<aside id="meta">
  <div>
  <section>
    <h4 id="date"> {{ .Date.Format "Mon Jan 2, 2006" }} </h4>
    <h5 id="wordcount"> {{ .WordCount }} Words </h5>
  </section>
    {{ with .GetTerms "topics" }}
      <ul id="topics">
        {{ range . }}
          <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
        {{ end }}
      </ul>
    {{ end }}
    {{ with .GetTerms "tags" }}
      <ul id="tags">
        {{ range . }}
          <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
        {{ end }}
      </ul>
    {{ end }}
  </div>
  <div>
    {{ with .PrevInSection }}
      <a class="previous" href="{{ .Permalink }}"> {{ .Title }}</a>
    {{ end }}
    {{ with .NextInSection }}
      <a class="next" href="{{ .Permalink }}"> {{ .Title }}</a>
    {{ end }}
  </div>
</aside>
{{ end }}

​ 要轻松生成一个内容类型的新实例(例如,在像 project/ 这样的章节中生成新的 .md 文件),并预先配置好前置元数据,请使用内容原型

另请参阅

6.11 - 内容视图模板

Content View Templates - 内容视图模板

https://gohugo.io/templates/views/

​ Hugo可以渲染内容的替代视图,这在列表和摘要视图中特别有用。

​ 这些替代的内容视图在列表模板中特别有用。

​ 以下是内容视图的常见用例:

  • 您希望在主页上显示每种类型的内容,但仅以有限的摘要视图显示。
  • 您只想在分类列表页面上显示您的内容的项目列表。视图通过将每种不同类型的内容的渲染委托给内容本身来使此过程变得非常简单。

创建内容视图

​ 要创建新视图,请在每个不同的内容类型目录中创建具有视图名称的模板。以下示例包含用于postsproject内容类型的"li"视图和"summary"视图。正如您所看到的,这些视图与单个内容视图模板single.html并排。您甚至可以为给定类型提供特定的视图,并继续使用_default/single.html作为主视图。

1
2
3
4
5
6
7
8
9
  ▾ layouts/
    ▾ posts/
        li.html
        single.html
        summary.html
    ▾ project/
        li.html
        single.html
        summary.html

​ Hugo还支持使用默认内容模板,以在没有为该类型提供特定内容视图模板的情况下使用。内容视图也可以在_default目录中定义,并且将像列表和单个模板一样工作,最终作为查找顺序的一部分向下传递到_default目录中。

1
2
3
4
5
▾ layouts/
  ▾ _default/
      li.html
      single.html
      summary.html

哪个模板将被渲染?

​ 以下是内容视图的查找顺序:

  1. /layouts/<TYPE>/<VIEW>.html
  2. /layouts/_default/<VIEW>.html
  3. /themes/<THEME>/layouts/<TYPE>/<VIEW>.html
  4. /themes/<THEME>/layouts/_default/<VIEW>.html

示例:列表中的内容视图

​ 以下示例演示了如何在列表模板中使用内容视图。

list.html

​ 在此示例中,将.Render被传递到模板中以调用render函数.Render是一种特殊的函数,它指示内容使用第一个参数提供的视图模板渲染自身。在本例中,该模板将渲染以下summary.html视图:

layouts/_default/list.html

1
2
3
4
5
6
7
8
<main id="main">
  <div>
    <h1 id="title">{{ .Title }}</h1>
    {{ range .Pages }}
      {{ .Render "summary" }}
    {{ end }}
  </div>
</main>

summary.html

​ Hugo将整个页面对象传递给以下summary.html视图模板。(有关完整列表,请参见页面变量。)

layouts/_default/summary.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<article class="post">
  <header>
    <h2><a href='{{ .Permalink }}'> {{ .Title }}</a> </h2>
    <div class="post-meta">{{ .Date.Format "Mon, Jan 2, 2006" }} - {{ .FuzzyWordCount }} Words </div>
  </header>
  {{ .Summary }}
  <footer>
  <a href='{{ .Permalink }}'><nobr>Read more →</nobr></a>
  </footer>
</article>

li.html

​ 继续上一个示例,我们可以通过更改调用 .Render 函数中的参数来使用较小的 li.html 视图(即 {{ .Render "li" }})。

layouts/_default/li.html

1
2
3
4
<li>
  <a href="{{ .Permalink }}">{{ .Title }}</a>
  <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
</li>

另请参阅

6.12 - 数据模板

Data Templates - 数据模板

https://gohugo.io/templates/data-templates/

​ 除了Hugo内置的变量,您可以在模板或简码中指定自己的自定义数据,这些数据可以来自本地和动态源。

​ Hugo支持从位于Hugo项目根目录下的data目录中的YAML、JSON、XML和TOML文件加载数据。

data文件夹

data 文件夹应该存储在生成站点时 Hugo 需要使用的其他数据。

​ 数据文件不用于生成独立的页面。它们应该通过以下方式补充内容文件:

  • 当前置元数据字段过于复杂时扩展内容;或
  • 在模板中显示一个更大的数据集(参见下面的示例)

​ 在这两种情况下,最好将这些数据外包到它们(自己的)的文件中。

​ 这些文件必须是 YAML、JSON、XML 或 TOML 文件(使用 .yml.yaml.json.xml.toml 扩展名)。这些数据将作为 map 存储在 .Site.Data 变量中。

​ 要使用 site.Data.filename 表示法访问数据,该filename必须以下划线或 Unicode 字母开头,后跟零个或多个下划线、Unicode 字母或 Unicode 数字。例如:

  • 123.json - 无效的
  • x123.json - 有效的
  • _123.json - 有效的

​ 要使用 index 函数访问这些数据,则该文件名无关紧要。例如:

数据文件模板代码
123.json{{ index .Site.Data "123" }}
x123.json{{ index .Site.Data "x123" }}
_123.json{{ index .Site.Data "_123" }}
x-123.json{{ index .Site.Data "x-123" }}

主题中的数据文件

​ 数据文件也可以在主题中使用。

​ 但是,请注意,主题数据文件与项目目录合并,以项目目录为优先。也就是说,如果存在相同名称和相对路径的两个文件,则根项目 data 目录中文件中的数据将覆盖 themes/<THEME>/data 目录中文件中的数据(对于重复的键)。

​ 因此,主题作者应该小心,不要包含用户可以轻松覆盖的数据文件,因为用户可能决定自定义主题。对于不应被覆盖的特定于主题的数据项,最好在文件夹结构前加上命名空间,例如 mytheme/data/<THEME>/somekey/...。要检查是否存在此类重复项,请使用 -v 标志运行 hugo。

​ 从数据文件创建数据模板的映射中的键将是一组点链接的 pathfilename 和文件中的 key(如果适用)。

​ 以下是最好的说明例子:

示例:Jaco Pastorius的个人唱片

Jaco Pastorius 是一位伟大的贝斯手,但他的个人唱片分类目录非常简短,足以作为一个示例。John Patitucci 是另一位贝斯巨匠。

​ 下面的示例有点牵强,但它说明了数据文件的灵活性。这个示例使用 TOML 作为文件格式,其中包含以下两个数据文件:

  • data/jazz/bass/jacopastorius.toml
  • data/jazz/bass/johnpatitucci.toml

jacopastorius.toml 包含以下内容。 johnpatitucci.toml 包含类似的列表:

jacopastorius.

=== “yaml”

``` yaml
discography:
- 1974 - Modern American Music … Period! The Criteria Sessions
- 1974 - Jaco
- 1976 - Jaco Pastorius
- 1981 - Word of Mouth
- 1981 - The Birthday Concert (released in 1995)
- 1982 - Twins I & II (released in 1999)
- 1983 - Invitation
- 1986 - Broadway Blues (released in 1998)
- 1986 - Honestly Solo Live (released in 1990)
- 1986 - Live In Italy (released in 1991)
- 1986 - Heavy'n Jazz (released in 1992)
- 1991 - Live In New York City, Volumes 1-7.
- 1999 - Rare Collection (compilation)
- '2003 - Punk Jazz: The Jaco Pastorius Anthology (compilation)'
- 2007 - The Essential Jaco Pastorius (compilation)
```

=== “toml”

``` toml
discography = ['1974 - Modern American Music … Period! The Criteria Sessions', '1974 - Jaco', '1976 - Jaco Pastorius', '1981 - Word of Mouth', '1981 - The Birthday Concert (released in 1995)', '1982 - Twins I & II (released in 1999)', '1983 - Invitation', '1986 - Broadway Blues (released in 1998)', '1986 - Honestly Solo Live (released in 1990)', '1986 - Live In Italy (released in 1991)', "1986 - Heavy'n Jazz (released in 1992)", '1991 - Live In New York City, Volumes 1-7.', '1999 - Rare Collection (compilation)', '2003 - Punk Jazz: The Jaco Pastorius Anthology (compilation)', '2007 - The Essential Jaco Pastorius (compilation)']
```

=== “json”

``` json
{
   "discography": [
      "1974 - Modern American Music … Period! The Criteria Sessions",
      "1974 - Jaco",
      "1976 - Jaco Pastorius",
      "1981 - Word of Mouth",
      "1981 - The Birthday Concert (released in 1995)",
      "1982 - Twins I \u0026 II (released in 1999)",
      "1983 - Invitation",
      "1986 - Broadway Blues (released in 1998)",
      "1986 - Honestly Solo Live (released in 1990)",
      "1986 - Live In Italy (released in 1991)",
      "1986 - Heavy'n Jazz (released in 1992)",
      "1991 - Live In New York City, Volumes 1-7.",
      "1999 - Rare Collection (compilation)",
      "2003 - Punk Jazz: The Jaco Pastorius Anthology (compilation)",
      "2007 - The Essential Jaco Pastorius (compilation)"
   ]
}
```

​ 可以通过 .Site.Data.jazz.bass 访问贝斯手列表,通过添加文件名而不带后缀名来访问单个贝斯手,例如 .Site.Data.jazz.bass.jacopastorius

​ 现在可以在模板中呈现所有贝斯手的唱片列表:

1
2
3
{{ range $.Site.Data.jazz.bass }}
   {{ partial "artist.html" . }}
{{ end }}

​ 然后在 partials/artist.html 中:

1
2
3
4
5
<ul>
{{ range .discography }}
  <li>{{ . }}</li>
{{ end }}
</ul>

​ 发现新的喜欢的贝斯手?只需在相同的目录中添加另一个 .toml 文件即可。

示例:从数据文件中访问命名的值

​ 假设在 data/ 下的 User0123.[yml|toml|xml|json] 数据文件中,您有以下数据结构:

User0123.

=== “yaml”

``` yaml
Achievements:
- Can create a Key, Value list from Data File
- Learns Hugo
- Reads documentation
Name: User0123
Short Description: He is a **jolly good** fellow.
```

=== “toml”

``` toml
Achievements = ['Can create a Key, Value list from Data File', 'Learns Hugo', 'Reads documentation']
Name = 'User0123'
'Short Description' = 'He is a **jolly good** fellow.'
```

=== “json”

``` json
{
   "Achievements": [
      "Can create a Key, Value list from Data File",
      "Learns Hugo",
      "Reads documentation"
   ],
   "Name": "User0123",
   "Short Description": "He is a **jolly good** fellow."
}
```

​ 您可以使用以下代码在布局中渲染 Short Description

1
<div>Short Description of {{ .Site.Data.User0123.Name }}: <p>{{ index .Site.Data.User0123 "Short Description" | markdownify }}</p></div>

​ 请注意使用 markdownify 模板函数。这将通过 Markdown 渲染引擎发送描述。

获取远程数据

​ 使用 getJSONgetCSV 获取远程数据:

1
2
{{ $dataJ := getJSON "url" }}
{{ $dataC := getCSV "separator" "url" }}

​ 如果为 URL 使用前缀或后缀,则这些函数接受可变参数

1
2
{{ $dataJ := getJSON "url prefix" "arg1" "arg2" "arg n" }}
{{ $dataC := getCSV  "separator" "url prefix" "arg1" "arg2" "arg n" }}

getCSV 的分隔符(separator)必须放在第一个位置,并且只能是一个字符长。

​ 所有传递的参数将连接到最终 URL:

1
2
{{ $urlPre := "https://api.github.com" }}
{{ $gistJ := getJSON $urlPre "/users/GITHUB_USERNAME/gists" }}

​ 这将在内部解析为以下内容:

1
{{ $gistJ := getJSON "https://api.github.com/users/GITHUB_USERNAME/gists" }}

添加 HTTP 标头

getJSONgetCSV 都以可选的 map 作为最后一个参数,例如:

1
{{ $data := getJSON "https://example.org/api" (dict "Authorization" "Bearer abcd") }}

​ 如果您需要同一标头键的多个值,请使用切片:

1
{{ $data := getJSON "https://example.org/api" (dict "X-List" (slice "a" "b" "c")) }}

CSV 文件示例

​ 对于getCSV,一个字符长的分隔符必须放在第一个位置,然后是URL。以下是从已发布的CSV在partial模板中创建HTML表格的示例:

layouts/partials/get-csv.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  <table>
    <thead>
      <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Salary</th>
      </tr>
    </thead>
    <tbody>
    {{ $url := "https://example.com/finance/employee-salaries.csv" }}
    {{ $sep := "," }}
    {{ range $i, $r := getCSV $sep $url }}
      <tr>
        <td>{{ index $r 0 }}</td>
        <td>{{ index $r 1 }}</td>
        <td>{{ index $r 2 }}</td>
      </tr>
    {{ end }}
    </tbody>
  </table>

​ 表达式{{ index $r number }}必须用于输出当前行的第n列。

缓存 URL

​ 每个下载的URL将被缓存到默认文件夹$TMPDIR/hugo_cache/中。变量$TMPDIR将被解析为依赖于您系统的临时目录。

​ 使用命令行标志--cacheDir,您可以指定系统上的任何文件夹作为缓存目录。

​ 您还可以在主配置文件中设置cacheDir

​ 如果您不喜欢缓存,可以使用命令行标志--ignoreCache完全禁用缓存。

使用 REST URL 进行身份验证

​ 目前,您只能使用可以放入URL中的那些身份验证方法。OAuth和其他身份验证方法未实现。

加载本地文件

​ 要使用getJSONgetCSV加载本地文件,源文件必须位于Hugo的工作目录中。文件扩展名不重要,但(文件的)内容重要。

​ 它应用了与上面在获取远程数据中相同的输出逻辑。

​ 要使用getCSV加载的本地CSV文件必须位于data目录之外

数据文件的 LiveReload

​ 当URL的内容发生更改时,没有机会触发LiveReload。但是,当本地文件更改时(即,data/*themes/<THEME>/data/*),将触发LiveReload。不支持符号链接。请注意,由于下载数据需要一段时间,Hugo会在数据下载完成之前停止处理Markdown文件。

​ 如果更改了任何本地文件并触发了LiveReload,则Hugo将从缓存中读取数据驱动(URL)内容。如果您禁用了缓存(例如,通过使用hugo server --ignoreCache运行服务器),Hugo将在每次LiveReload触发时重新下载内容。这可能会产生巨大的流量。您可能会很快达到API限制。

数据驱动内容的示例

数据格式规范

另请参阅

6.13 - 局部模板

Partial Templates - 局部模板

https://gohugo.io/templates/partials/

​ Partial 是在列表和页面模板中使用的更小的上下文感知组件,可以经济地使用以保持模板 DRY。

局部模板查找顺序

​ Partial 模板(如单页面模板列表页面模板)具有特定的查找顺序。然而,partial 更简单,因为 Hugo 只会检查两个地方:

  1. layouts/partials/*<PARTIALNAME>.html
  2. themes/<THEME>/layouts/partials/*<PARTIALNAME>.html

​ 这允许某一主题的最终用户将 partial 的内容复制到同名文件中以进行进一步的自定义

在您的模板中使用 Partial

​ Hugo 项目中的所有 partial 都位于一个名为 layouts/partials 的目录中。为了更好的组织,您还可以在 partials 中创建多个子目录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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 都使用以下模式:

1
{{ partial "<PATH>/<PARTIAL>.html" . }}

​ 新手 Hugo 用户最常见的错误之一是未能向 partial 调用传递上下文。在上述模式中,请注意如何使用“点号”(.)作为第二个参数来给出 partial 上下文。您可以在Hugo 模板介绍中了解更多有关"the dot"的信息。

<PARTIAL>包括baseof已被保留。(#5373

​ 如上例目录结构所示,您可以在partials中嵌套目录以获得更好的源代码组织。您只需要使用相对于partials目录的嵌套 partial 路径即可:

1
2
{{ partial "header/site-header.html" . }}
{{ partial "footer/scripts.html" . }}

变量作用域

​ partial 调用中的第二个参数是要传递下去的变量。上述示例传递了.,这告诉接收 partial 的模板应用当前上下文

​ 这意味着 partial 只能访问这些变量。partial 是被隔离的,无法访问外部作用域。在 partial 内部,$.Var 等同于 .Var

从 Partial 返回一个值

​ 除了输出标记之外,partial 还可以用于返回任何类型的值。为了返回一个值,partial 必须在partial 的末尾包括一个孤立的 return 语句。

示例 GetFeatured

1
2
3
4
5
6
{{/* layouts/partials/GetFeatured.html */}}
{{ return first . (where site.RegularPages "Params.featured" true) }}
{{/* layouts/index.html */}}
{{ range partial "GetFeatured.html" 5 }}
  [...]
{{ end }}

示例 GetImage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{{/* layouts/partials/GetImage.html */}}
{{ $image := false }}
{{ with .Params.gallery }}
  {{ $image = index . 0 }}
{{ end }}
{{ with .Params.image }}
  {{ $image = . }}
{{ end }}
{{ return $image }}
{{/* layouts/_default/single.html */}}
{{ with partial "GetImage.html" . }}
  [...]
{{ end }}

​ 每个 partial 文件只允许一个 return 语句。

内联 Partial

​ 您还可以在模板中内联定义 partial。但是请记住,模板命名空间是全局的,因此您需要确保名称是唯一的,以避免冲突。

1
2
3
4
5
6
Value: {{ partial "my-inline-partial.html" . }}

{{ define "partials/my-inline-partial.html" }}
{{ $value := 32 }}
{{ return $value }}
{{ end }}

缓存的 Partials

partialCached模板函数可以为不需要在每次调用时重新渲染的复杂模板提供显著的性能提升。最简单的用法如下:

1
{{ partialCached "footer.html" . }}

​ 您也可以传递附加参数给partialCached,以创建缓存 partial 模板的变体

​ 例如,您可以告诉Hugo只对每个章节渲染一次footer.html partial 模板:

1
{{ partialCached "footer.html" . .Section }}

​ 如果您需要传递额外的参数以创建唯一的变体,您可以传递任意数量的变体参数:

1
{{ partialCached "footer.html" . .Params.country .Params.province }}

​ 注意,变体参数不会被传递给底层的 partial 模板,它们只用于创建唯一的缓存键。

示例 header.html

​ 下面的header.html partial 模板被用于spf13.com

layouts/partials/header.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!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>

header.html 这个示例的partial 是在 Hugo 引入 block templates 之前创建的。关于如何定义主模板(例如站点的头部、页头和页脚)的外部 chrome 或 shell,可以在 base templates and blocks 中了解更多信息。您甚至可以组合使用 blocks 和 partials,以增加灵活性。

示例 footer.html

​ 下面的footer.html partial 模板被用于spf13.com

layouts/partials/footer.html

1
2
3
4
5
6
7
8
9
<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>

另请参阅

6.14 - 创建自己的简码

Create Your Own Shortcodes - 创建自己的简码

https://gohugo.io/templates/shortcode-templates/

​ 您可以使用与单页和列表页相同的模板语法来创建自己的简码,以扩展Hugo内置的简码。

​ 简码是一种将模板合并成小型、可重用的代码片段的方式,您可以直接在内容中嵌入这些代码片段。从这个意义上说,您可以将简码视为页面和列表模板基本内容文件之间的中间件。

​ Hugo还提供了常见用例的内置简码。(参见内容管理:简码。)

创建自定义Shortcodes

​ Hugo的内置简码涵盖了许多常见但不是全部的用例。幸运的是,Hugo提供了轻松创建自定义简码以满足您站点需求的功能。

文件位置

​ 要创建一个简码,请在 源文件组织layouts/shortcodes 目录中放置一个 HTML 模板。请仔细考虑文件名,因为简码名称将与文件名相同,但没有 .html 扩展名。例如,layouts/shortcodes/myshortcode.html 将根据您选择的参数类型使用 \{\{\< myshortcode /\>\}\}\{\{\% myshortcode \/\%\}\} 进行调用。

​ 您可以在子文件夹中组织您的简码,例如在 layouts/shortcodes/boxes 中。然后,这些简码将使用它们的相对路径进行访问,例如:

1
\{{\< boxes/square \>\}\}

​ 注意正斜杠。

简码模板查找顺序

​ 简码模板具有简单的查找顺序

  1. /layouts/shortcodes/<SHORTCODE>.html
  2. /themes/<THEME>/layouts/shortcodes/<SHORTCODE>.html

位置参数 vs 命名参数

​ 您可以使用以下类型的参数创建简码:

  • 位置参数
  • 命名参数
  • 位置或命名参数(即"灵活(flexible)")

​ 在具有位置参数的简码中,参数的顺序很重要。如果简码有一个必需的单一值(例如下面的youtube简码),则位置参数非常有效,并且需要的内容作者输入较少。

​ 对于具有多个或可选参数的更复杂的布局,命名参数效果最好。虽然不太简洁,但命名参数需要较少的内容作者记忆,并且可以按任意顺序添加到简码声明中。

​ 允许两种类型的参数(即"灵活(flexible)“的简码)对于复杂的布局非常有用,您可以设置默认值,这些默认值可以很容易地被用户覆盖。

访问参数

​ 可以通过 .Get 方法访问所有简码参数。无论是将键(即字符串)还是数字传递给 .Get 方法取决于您是否正在访问命名或位置参数。

​ 要通过名称访问参数,请使用.Get方法,后跟命名参数作为引用字符串的形式:

1
{{ .Get "class" }}

​ 要通过位置访问参数,请使用 .Get,后跟数字位置,要记住位置参数是从零开始编号的:

1
{{ .Get 0 }}

​ 对于第二个位置,您只需要使用:

1
{{ .Get 1 }}

​ 当输出取决于参数是否设置时,使用with 很棒:

1
{{ with .Get "class" }} class="{{ . }}"{{ end }}

.Get 也可以用于检查是否已提供参数。当条件取决于两个值中的任一个或两个值时,这非常有用:

1
{{ if or (.Get "title") (.Get "alt") }} alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "title" }}{{ end }}"{{ end }}

.Inner

​ 如果使用了闭合的简码,.Inner 变量将被填充为开放和闭合简码之间的内容。如果需要闭合的简码,则可以检查 .Inner 的长度以指示其存在。

​ 通过.Inner变量声明内容的简码也可以使用自闭合语法来声明,而无需内容和结束标签:

1
\{\{\< innershortcode \/\>\}\}

任何引用.Inner的简码都必须是闭合的或自闭合的。

.Params

​ 简码中的.Params变量包含传递给简码的参数列表,用于更复杂的用例。您也可以使用以下逻辑访问更高级别的参数:

  • $.Params

    这些是直接传递到简码声明中的参数(例如,YouTube视频ID)

  • $.Page.Params

    引用该页面的参数;在这种情况下, 该"page"指的是声明简码的内容文件(例如,内容的前置元数据中的shortcode_color字段可以通过$.Page.Params.shortcode_color访问)。

  • $.Page.Site.Params

    引用您站点配置文件中定义的全局变量。

.IsNamedParams

.IsNamedParams 变量检查简码声明是否使用了命名参数,并返回一个布尔值。

​ 例如,您可以创建一个 image 简码,可以使用命名参数 src 或第一个位置参数,具体取决于内容作者的偏好。假设 image 简码的调用方式如下:

1
\{\{\< image src="images/my-image.jpg" \>\}\}

​ 然后,您可以将以下内容包含在您的简码模板中:

1
2
3
4
5
{{ if .IsNamedParams }}
<img src="{{ .Get "src" }}" alt="">
{{ else }}
<img src="{{ .Get 0 }}" alt="">
{{ end }}

​ 请查看下面的 Vimeo 简码示例 以了解 .IsNamedParams 的用法。

​ 虽然可以创建接受位置参数和命名参数的简码模板,但是在内容中声明的简码不能混合参数类型。因此,像 \{\{\< image src="images/my-image.jpg" "This is my alt text" \>\}\} 这样声明的简码将返回一个错误。

​ 您还可以使用变量.Page访问所有普通页面变量

​ 简码也可以嵌套。在嵌套的简码标签中,您可以使用 .Parent 变量 访问父级简码的上下文,这对于从根继承常见的简码参数非常有用。

检查是否存在

​ 您可以通过在该页面模板中调用.HasShortcode,并提供简码的名称来检查页面上是否使用了特定的简码。当您想要在头部中包含仅由该简码使用的特定脚本或样式时,这一功能有时很有用。

自定义简码示例

​ 以下是通过在/layouts/shortcodes中的简码模板文件创建的不同类型的简码示例。

单词示例:year

​ 假设您想在不需要不断查看 Markdown 的情况下,在内容文件中保持版权年份的更新。您的目标是可以按照以下方式调用简码:

1
\{\{\< year \>\}\}

/layouts/shortcodes/year.html

1
{{ now.Format "2006" }}

单位置示例:YouTube

​ 内嵌视频是 Markdown 内容中常见的补充,但很容易变得不美观。以下是 Hugo 的内置 YouTube 简码 使用的代码:

1
\{\{\< youtube 09jf3ow9jfw \>\}\}

​ 将会加载 /layouts/shortcodes/youtube.html 中的模板:

/layouts/shortcodes/youtube.html

1
2
3
4
<div class="embed video-player">
<iframe class="youtube-player" type="text/html" width="640" height="385" src="https://www.youtube.com/embed/{{ index .Params 0 }}" allowfullscreen frameborder="0">
</iframe>
</div>

youtube-embed.html

1
2
3
4
5
6
7
<div class="embed video-player">
    <iframe class="youtube-player" type="text/html"
        width="640" height="385"
        src="https://www.youtube.com/embed/09jf3ow9jfw"
        allowfullscreen frameborder="0">
    </iframe>
</div>

单命名示例:image

​ 假设您想创建自己的 img 简码,而不是使用 Hugo 的内置 figure 简码。您的目标是可以在内容文件中按照以下方式调用简码:

content-image.md

1
\{\{\< img src="/media/spf13.jpg" title="Steve Francia" \>\}\}

​ 您已经在 /layouts/shortcodes/img.html 中创建了简码,它会加载以下简码模板:

/layouts/shortcodes/img.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!-- image -->
<figure {{ with .Get "class" }}class="{{ . }}"{{ end }}>
  {{ with .Get "link" }}<a href="{{ . }}">{{ end }}
    <img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" }}{{ end }}"{{ end }} />
    {{ if .Get "link" }}</a>{{ end }}
    {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr") }}
      <figcaption>{{ if isset .Params "title" }}
        <h4>{{ .Get "title" }}</h4>{{ end }}
        {{ if or (.Get "caption") (.Get "attr") }}<p>
        {{ .Get "caption" }}
        {{ with .Get "attrlink" }}<a href="{{ . }}"> {{ end }}
          {{ .Get "attr" }}
        {{ if .Get "attrlink" }}</a> {{ end }}
        </p> {{ end }}
      </figcaption>
  {{ end }}
</figure>
<!-- image -->

​ 将被渲染为:

img-output.html

1
2
3
4
5
6
<figure>
  <img src="/media/spf13.jpg"  />
  <figcaption>
      <h4>Steve Francia</h4>
  </figcaption>
</figure>

单灵活示例:vimeo

1
2
\{\{\< vimeo 49718712 \>\}\}
\{\{\< vimeo id="49718712" class="flex-video" \>\}\}

​ 将会加载 /layouts/shortcodes/vimeo.html 中的模板:

/layouts/shortcodes/vimeo.html

1
2
3
4
5
6
7
8
9
{{ if .IsNamedParams }}
  <div class="{{ if .Get "class" }}{{ .Get "class" }}{{ else }}vimeo-container{{ end }}">
    <iframe src="https://player.vimeo.com/video/{{ .Get "id" }}" allowfullscreen></iframe>
  </div>
{{ else }}
  <div class="{{ if len .Params | eq 2 }}{{ .Get 1 }}{{ else }}vimeo-container{{ end }}">
    <iframe src="https://player.vimeo.com/video/{{ .Get 0 }}" allowfullscreen></iframe>
  </div>
{{ end }}

​ 将被渲染为:

vimeo-iframes.html

1
2
3
4
5
6
<div class="vimeo-container">
  <iframe src="https://player.vimeo.com/video/49718712" allowfullscreen></iframe>
</div>
<div class="flex-video">
  <iframe src="https://player.vimeo.com/video/49718712" allowfullscreen></iframe>
</div>

成对示例:highlight

​ 以下内容取自 highlight,它是 Hugo 内置简码 之一。

highlight-example.md

1
2
3
4
5
\{\{\< highlight html \>\}\}
  <html>
    <body> This HTML </body>
  </html>
\{\{\< /highlight \>\}\}

highlight 简码的模板使用以下代码,它已经包含在 Hugo 中:

1
{{ .Get 0 | highlight .Inner }}

​ HTML 示例代码块的渲染输出如下:

syntax-highlighted.html

1
2
3
4
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f92672">&lt;html&gt;</span>
    <span style="color: #f92672">&lt;body&gt;</span> This HTML <span style="color: #f92672">&lt;/body&gt;</span>
<span style="color: #f92672">&lt;/html&gt;</span>
</pre></div>

嵌套的简码:图像库

​ Hugo的.Parent 简码变量简码的上下文中被调用时提供了对父简码上下文的访问,这为常见的简码参数提供了继承模型。

​ 下面的示例是人为的,但演示了该概念。假设您有一个 gallery 简码,它期望一个名为 class 的参数:

layouts/shortcodes/gallery.html

1
2
3
<div class="{{ .Get "class" }}">
  {{ .Inner }}
</div>

​ 您还有一个 img 简码,只有一个名为 src 的参数,您想在 gallery 和其他简码中调用它,以使父级定义每个 img 的上下文:

layouts/shortcodes/img.html

1
2
3
4
5
6
{{- $src := .Get "src" -}}
{{- with .Parent -}}
  <img src="{{ $src }}" class="{{ .Get "class" }}-image">
{{- else -}}
  <img src="{{ $src }}">
{{- end -}}

​ 然后您可以在内容中按以下方式调用您的简码:

1
2
3
4
5
\{\{\< gallery class="content-gallery" \>\}\}
  \{\{\< img src="/images/one.jpg" \>\}\}
  \{\{\< img src="/images/two.jpg" \>\}\}
\{\{\< /gallery \>\}\}
\{\{\< img src="/images/three.jpg" \>\}\}

​ 这将输出以下 HTML。请注意,前两个 img 简码继承了通过调用父级 gallery 设置的 class 值为 content-gallery,而第三个 img 只使用了 src

1
2
3
4
5
<div class="content-gallery">
    <img src="/images/one.jpg" class="content-gallery-image">
    <img src="/images/two.jpg" class="content-gallery-image">
</div>
<img src="/images/three.jpg">

简码中的错误处理

​ 使用 errorf 模板函数和 .Position 变量可获得简码中有用的错误消息:

1
2
3
4
{{ with .Get "name" }}
{{ else }}
{{ errorf "missing value for param 'name': %s" .Position }}
{{ end }}

​ 当上述失败时,您会看到类似下面的 ERROR 日志:

1
ERROR 2018/11/07 10:05:55 missing value for param name: "/Users/bep/dev/go/gohugoio/hugo/docs/content/en/variables/shortcodes.md:32:1"

更多简码示例

​ 更多简码示例可以在 spf13.com 的简码目录Hugo 文档的简码目录 中找到。

内联简码

​ 您也可以内联实现您的简码——例如,在您使用它们的内容文件中。这对于您只需要在一个地方使用脚本非常有用。

​ 这个功能默认是禁用的,但可以在您的站点配置中启用:

config.

=== “yaml”

``` yaml
enableInlineShortcodes: true
```

=== “toml”

``` toml
enableInlineShortcodes = true
```

=== “json”

``` json
{
   "enableInlineShortcodes": true
}
```

​ 它出于安全原因默认禁用。Hugo 模板处理使用的安全模型假定模板作者是可信的,但内容文件不是,因此模板是安全的,可以避免因输入数据格式不正确而出现注入问题。但在大多数情况下,您也可以完全控制内容,那么 enableInlineShortcodes = true 将被认为是安全的。但要注意:它允许从内容文件中执行 ad-hoc Go 文本模板

​ 启用后,您可以在内容文件中执行以下操作:

1
\{\{\< time.inline \>\}\}{{ now }}\{\{\< /time.inline \>\}\}

​ 上述代码将打印当前日期和时间。

请注意,内联简码的内部内容将被解析并作为一个具有与常规简码模板相同上下文的 Go 文本模板执行。

​ 这意味着可以通过.Page.Title等方式访问当前页面。这也意味着没有"嵌套内联简码"的概念。

​ 同一个内联简码可以在同一个内容文件中多次重复使用,如果需要不同的参数,则使用自闭合语法:

1
\{\{\< time.inline /\>\}\}

另请参阅

6.15 - 本地文件模板

Local File Templates - 本地文件模板

https://gohugo.io/templates/files/

​ Hugo 的 readDirreadFile 函数使得遍历项目目录结构和将文件内容写入模板变得容易。

遍历本地文件

​ 使用 Hugo 的 readDirreadFile 模板函数,您可以遍历服务器上站点的文件。

使用 readDir

readDir 函数 返回一个由 os.FileInfo 组成的数组。它以文件的 path 作为单个字符串参数。这个路径可以指向您站点上的任何目录(即服务器文件系统中的目录)。

​ 路径是绝对还是相对并不重要,因为对于 readDir 函数,您站点的根目录(通常是 ./public/)实际上同时扮演两个角色:

  1. 文件系统根目录
  2. 当前工作目录

使用 readFile

readfile 函数 从磁盘读取文件并将其转换为字符串,以便由其他 Hugo 函数操纵或按原样添加。readFile 将文件(包括路径)作为传递给该函数的参数。

​ 在模板中使用 readFile 函数时,请确保路径相对于Hugo 项目根目录

1
{{ readFile "/content/templates/local-file-templates" }}

readFile 示例:将项目文件添加到内容

​ 由于 readFile 是一个函数,因此它仅在模板中可用,而不在内容中可用。然而,我们可以创建一个简单的 简码模板,来调用 readFile,将第一个参数通过该函数传递,然后允许一个可选的第二个参数将文件通过 Markdown 处理器。将这个 简码添加到内容中的模式如下:

1
\{\{\< readfile file="/path/to/local/file.txt" markdown="true" \>\}\}

​ 如果要使用 readFile 为主题创建自定义简码,请注意,简码的使用将参考项目根目录,而不是您的 themes 目录。

另请参阅

6.16 - 自定义404页面

Custom 404 Page - 自定义404页面

https://gohugo.io/templates/404/

​ 如果您知道如何创建单页模板,那么您可以无限制地创建自定义404页面。

​ 当使用 Hugo 与 GitHub Pages 时,可以通过在 layouts 文件夹的根目录中创建 404.html 模板文件来提供 自定义的404 错误页面。当 Hugo 生成您的站点时,404.html 文件将被放置在根目录中。

​ 404 页面将拥有可用于模板的所有常规页面变量

​ 除了标准页面变量外,404 页面还可以从 .Pages 访问所有站点内容。

1
2
▾ layouts/
    404.html

404.html

​ 这是一个基本的404.html模板示例:

​ 以下是一个基本的 404.html 模板示例:

layouts/404.html

1
2
3
4
5
6
7
{{ define "main" }}
  <main id="main">
    <div>
      <h1 id="title"><a href="{{ "" | relURL }}">Go Home</a></h1>
    </div>
  </main>
{{ end }}

自动加载

​ 您的 404.html 文件可以在访问者输入错误的 URL 路径时自动加载,具体取决于您正在使用的 Web 服务器环境。例如:

  • GitHub PagesGitLab Pages。404 页面是自动的。
  • Apache。您可以在站点根目录的 .htaccess 文件中指定 ErrorDocument 404 /404.html
  • Nginx。您可以在 nginx.conf 文件中指定 error_page 404 /404.html;详情在此
  • Amazon AWS S3。在为静态 Web 服务设置存储桶时,您可以从 S3 GUI 中指定错误文件。
  • Amazon CloudFront。您可以在 CloudFront 控制台的错误页面章节指定页面。详情在此
  • Caddy Server。使用 handle_errors 指令为一个或多个状态码指定错误页面。详情在此
  • Netlify。在 content/_redirects 中添加 /* /404.html 404详情在此
  • Azure Static Web App。在配置文件 staticwebapp.config.json 中设置 responseOverrides.404.rewriteresponseOverrides.404.statusCode详情在此
  • Azure Storage 作为静态站点托管。您可以在 Azure 门户的静态站点配置页中指定Error document path详情在此
  • DigitalOcean App 平台。您可以在应用程序规范文件中指定 error_document 或使用控制面板设置错误文档。详情在此
  • Firebase Hosting/404.html 自动用作404页面。

hugo server 不会自动加载您的自定义 404.html 文件,但是您可以通过将浏览器导航到/404.html来测试您的自定义"not found"页面的外观。

6.17 - 菜单模板

Menu Templates - 菜单模板

https://gohugo.io/templates/menu-templates/

​ 在您的模板中使用菜单变量和方法来渲染菜单。

概述

​ 在定义菜单条目之后,使用菜单变量和方法来渲染菜单。

​ 有三个因素决定如何渲染菜单:

  1. 定义菜单条目的方法:自动定义在前置元数据中定义在站点配置中定义
  2. 菜单结构:平面或嵌套
  3. 用于本地化菜单条目的方法:站点配置或翻译表

​ 下面的示例处理了每种组合。

示例

​ 这个局部模板递归地"遍历"菜单结构,渲染本地化、可访问的嵌套列表。

layouts/partials/menu.html

 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
34
35
36
{{- $page := .page }}
{{- $menuID := .menuID }}

{{- with index site.Menus $menuID }}
  <nav>
    <ul>
      {{- partial "inline/menu/walk.html" (dict "page" $page "menuEntries" .) }}
    </ul>
  </nav>
{{- end }}

{{- define "partials/inline/menu/walk.html" }}
  {{- $page := .page }}
  {{- range .menuEntries }}
    {{- $attrs := dict "href" .URL }}
    {{- if $page.IsMenuCurrent .Menu . }}
      {{- $attrs = merge $attrs (dict "class" "active" "aria-current" "page") }}
    {{- else if $page.HasMenuCurrent .Menu .}}
      {{- $attrs = merge $attrs (dict "class" "ancestor" "aria-current" "true") }}
    {{- end }}
    <li>
      <a
        {{- range $k, $v := $attrs }}
          {{- with $v }}
            {{- printf " %s=%q" $k $v | safeHTMLAttr }}
          {{- end }}
        {{- end -}}
      >{{ or (T .Identifier) .Name | safeHTML }}</a>
      {{- with .Children }}
        <ul>
          {{- partial "inline/menu/walk.html" (dict "page" $page "menuEntries" .) }}
        </ul>
      {{- end }}
    </li>
  {{- end }}
{{- end }}

​ 调用上面的局部,传递一个菜单ID和当前页面的上下文。

layouts/_default/single.html

1
2
{{ partial "menu.html" (dict "menuID" "main" "page" .) }}
{{ partial "menu.html" (dict "menuID" "footer" "page" .) }}

页面引用

​ 无论您如何定义菜单条目,与页面相关联的条目都可以访问页面变量和方法。

​ 这个简单的示例在每个条目的name旁边渲染一个名为version的页面参数。使用withif来处理(a) 指向外部资源的条目,或者(b) version参数未定义的条目。

layouts/_default/single.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{{- range site.Menus.main }}
  <a href="{{ .URL }}">
    {{ .Name }}
    {{- with .Page }}
      {{- with .Params.version -}}
        ({{ . }})
      {{- end }}
    {{- end }}
  </a>
{{- end }}

菜单条目参数

当您在站点配置或前置元数据中定义菜单条目时,可以包括params键,如以下示例所示:

​ 当您在站点配置中定义菜单条目或在前置元数据中定义菜单条目时,您可以像这些示例中那样包含一个params键:

​ 这个简单的示例为每个锚点元素呈现一个class属性。使用withif来处理params.class未定义的条目。

layouts/partials/menu.html

1
2
3
4
5
{{- range site.Menus.main }}
  <a {{ with .Params.class -}} class="{{ . }}" {{ end -}} href="{{ .URL }}">
    {{ .Name }}
  </a>
{{- end }}

本地化

​ Hugo提供了两种本地化菜单条目的方法。详见多语言

另请参阅

6.18 - 分页

Pagination - 分页

​ Hugo支持对主页、章节页面和分类目录进行分页。

​ Hugo分页功能真正的强大之处在于与where函数及其类似SQL的操作符:firstlastafter相结合使用。您甚至可以按照Hugo中熟悉的方式对内容进行排序

配置分页

​ 可以在站点配置中配置分页:

  • paginate

    默认值为10。这个设置可以在模板中被覆盖。

  • paginatePath

    默认值为page。允许您为您的分页页面设置不同的路径。

​ 将paginate设置为正值将把主页、章节和分类列表页面拆分为这个大小的块。但是请注意,对于章节、分类和主页的分页页面的生成是惰性的——如果没有通过.Paginator引用,这些页面将不会被创建(见下文)。

paginatePath用于调整分页器中页面的URL(默认设置会生成这样的URL形式/page/1/)。

列出分页器页面

​ 提供.Paginator帮助您构建分页器菜单。此功能目前仅在主页和列表页面(即分类和章节列表)上受支持。

​ 有两种配置和使用.Paginator的方法:

  1. 最简单的方法是只需从模板中调用.Paginator.Pages。它将包含该页面的页面。
  2. 使用可用的模板函数和排序选项选择另一组页面,并将切片传递给.Paginate,例如
  • {{ range (.Paginate ( first 50 .Pages.ByTitle )).Pages }}
  • {{ range (.Paginate .RegularPagesRecursive).Pages }}.

​ 对于给定的页面,它是上面选项之一。.Paginator是静态的,一旦创建就不能更改。

​ 如果在同一页中多次调用 .Paginator.Paginate,您应该确保所有调用都是相同的。一旦在生成页面时调用了 .Paginator.Paginate,其结果就会被缓存,任何后续相似的调用都将重用缓存的结果。这意味着任何不符合第一个调用的这种调用都不会按预期行事。

(请记住,函数参数是急切地求值的,因此像 $paginator := cond x .Paginator (.Paginate .RegularPagesRecursive) 这样的调用就是您不应该做的事情。请使用 if/else 确保恰好有一个求值。)

​ 全局页面大小设置(Paginate)可以通过提供正整数作为最后一个参数来覆盖。下面的示例将每页显示五个项:

  • {{ range (.Paginator 5).Pages }}
  • {{ $paginator := .Paginate (where .Pages "Type" "posts") 5 }}

也可以将 GroupBy 函数与分页结合使用:

1
{{ range (.Paginate (.Pages.GroupByDate "2006")).PageGroups }}

构建导航

.Paginator 包含构建分页界面所需的足够信息。

​ 将内置模板(具有与 Bootstrap 兼容的样式)包含到您的页面中是添加此内容的最简单方法:

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

​ 如果使用任何过滤器或排序函数来创建您的 .Paginator,并且您希望在显示页面列表之前显示导航按钮,则必须在使用之前创建 .Paginator

​ 以下示例显示如何在使用 .Paginator 之前创建 .Paginator

1
2
3
4
5
{{ $paginator := .Paginate (where .Pages "Type" "posts") }}
{{ template "_internal/pagination.html" . }}
{{ range $paginator.Pages }}
   {{ .Title }}
{{ end }}

​ 如果没有 where 过滤器,则上面的示例更加简单:

1
2
3
4
{{ template "_internal/pagination.html" . }}
{{ range .Paginator.Pages }}
   {{ .Title }}
{{ end }}

​ 如果您想要构建自定义的导航菜单,您可以使用.Paginator对象,它包括以下属性:

  • PageNumber

    当前页面在页面序列中的页码

  • URL

    当前页面器的相对URL

  • Pages

    当前页面器中的页面

  • NumberOfElements

    此页面中的元素数量

  • HasPrev

    当前页之前是否有页

  • Prev

    前一页的分页器

  • HasNext

    当前页之后是否有页

  • Next

    下一页的分页器

  • First

    第一页的分页器

  • Last

    最后一页的分页器

  • Pagers

    可用于构建分页菜单的分页器列表

  • PageSize

    每个分页器的大小

  • TotalPages

    分页器中的页面数

  • TotalNumberOfElements

    此分页器中所有页面上的元素数

附加信息

​ 页面按以下形式构建(BLANK表示没有值):

1
2
3
4
[SECTION/TAXONOMY/BLANK]/index.html
[SECTION/TAXONOMY/BLANK]/page/1/index.html => redirect to  [SECTION/TAXONOMY/BLANK]/index.html
[SECTION/TAXONOMY/BLANK]/page/2/index.html
....

另请参阅

6.19 - RSS模板

RSS Templates - RSS模板

https://gohugo.io/templates/rss/

​ Hugo 自带 RSS 2.0 模板,几乎不需要配置,或者您可以创建自己的 RSS 模板。

RSS模板查找顺序

​ 有关完整参考,请参见 Template Lookup Order

​ Hugo 自带了 RSS 2.0 模板。嵌入式模板对于大多数用例已经足够了。

​ RSS 页面属于 Page 类型,并且在模板中可以使用所有 页面变量

Section RSS

section 的 RSS 将在 /<SECTION>/index.xml(例如,https://spf13.com/project/index.xml)处被渲染。

​ Hugo 提供了定义任何 RSS 类型的功能,并且可以为每个章节和分类法设置不同的 RSS 文件。

RSS模板查找顺序表

​ 下表显示了不同页面类型的 RSS 模板查找顺序。第一个列表显示了在使用某一主题(demoTheme)运行时的查找顺序。

ExampleOutputFormat后缀Template Lookup Order
RSS homeRSSxml1. layouts/index.rss.xml
2. layouts/home.rss.xml
3. layouts/rss.xml
4. layouts/list.rss.xml
5. layouts/index.xml
6. layouts/home.xml
7. layouts/list.xml
8. layouts/_default/index.rss.xml
9. layouts/_default/home.rss.xml
10. layouts/_default/rss.xml
11. layouts/_default/list.rss.xml
12. layouts/_default/index.xml
13. layouts/_default/home.xml
14. layouts/_default/list.xml
15. layouts/_internal/_default/rss.xml
RSS section postsRSSxml1. layouts/posts/section.rss.xml
2. layouts/posts/rss.xml
3. layouts/posts/list.rss.xml
4. layouts/posts/section.xml
5. layouts/posts/list.xml
6. layouts/section/section.rss.xml
7. layouts/section/rss.xml
8. layouts/section/list.rss.xml
9. layouts/section/section.xml
10. layouts/section/list.xml
11. layouts/_default/section.rss.xml
12. layouts/_default/rss.xml
13. layouts/_default/list.rss.xml
14. layouts/_default/section.xml
15. layouts/_default/list.xml
16. layouts/_internal/_default/rss.xml
Taxonomy in categoriesRSSxml1. layouts/categories/category.terms.rss.xml
2. layouts/categories/terms.rss.xml
3. layouts/categories/taxonomy.rss.xml
4. layouts/categories/rss.xml
5. layouts/categories/list.rss.xml
6. layouts/categories/category.terms.xml
7. layouts/categories/terms.xml
8. layouts/categories/taxonomy.xml
9. layouts/categories/list.xml
10. layouts/category/category.terms.rss.xml
11. layouts/category/terms.rss.xml
12. layouts/category/taxonomy.rss.xml
13. layouts/category/rss.xml
14. layouts/category/list.rss.xml
15. layouts/category/category.terms.xml
16. layouts/category/terms.xml
17. layouts/category/taxonomy.xml
18. layouts/category/list.xml
19. layouts/taxonomy/category.terms.rss.xml
20. layouts/taxonomy/terms.rss.xml
21. layouts/taxonomy/taxonomy.rss.xml
22. layouts/taxonomy/rss.xml
23. layouts/taxonomy/list.rss.xml
24. layouts/taxonomy/category.terms.xml
25. layouts/taxonomy/terms.xml
26. layouts/taxonomy/taxonomy.xml
27. layouts/taxonomy/list.xml
28. layouts/_default/category.terms.rss.xml
29. layouts/_default/terms.rss.xml
30. layouts/_default/taxonomy.rss.xml
31. layouts/_default/rss.xml
32. layouts/_default/list.rss.xml
33. layouts/_default/category.terms.xml
34. layouts/_default/terms.xml
35. layouts/_default/taxonomy.xml
36. layouts/_default/list.xml
37. layouts/_internal/_default/rss.xml
Term in categoriesRSSxml1. layouts/categories/term.rss.xml
2. layouts/categories/category.rss.xml
3. layouts/categories/taxonomy.rss.xml
4. layouts/categories/rss.xml
5. layouts/categories/list.rss.xml
6. layouts/categories/term.xml
7. layouts/categories/category.xml
8. layouts/categories/taxonomy.xml
9. layouts/categories/list.xml
10. layouts/term/term.rss.xml
11. layouts/term/category.rss.xml
12. layouts/term/taxonomy.rss.xml
13. layouts/term/rss.xml
14. layouts/term/list.rss.xml
15. layouts/term/term.xml
16. layouts/term/category.xml
17. layouts/term/taxonomy.xml
18. layouts/term/list.xml
19. layouts/taxonomy/term.rss.xml
20. layouts/taxonomy/category.rss.xml
21. layouts/taxonomy/taxonomy.rss.xml
22. layouts/taxonomy/rss.xml
23. layouts/taxonomy/list.rss.xml
24. layouts/taxonomy/term.xml
25. layouts/taxonomy/category.xml
26. layouts/taxonomy/taxonomy.xml
27. layouts/taxonomy/list.xml
28. layouts/category/term.rss.xml
29. layouts/category/category.rss.xml
30. layouts/category/taxonomy.rss.xml
31. layouts/category/rss.xml
32. layouts/category/list.rss.xml
33. layouts/category/term.xml
34. layouts/category/category.xml
35. layouts/category/taxonomy.xml
36. layouts/category/list.xml
37. layouts/_default/term.rss.xml
38. layouts/_default/category.rss.xml
39. layouts/_default/taxonomy.rss.xml
40. layouts/_default/rss.xml
41. layouts/_default/list.rss.xml
42. layouts/_default/term.xml
43. layouts/_default/category.xml
44. layouts/_default/taxonomy.xml
45. layouts/_default/list.xml
46. layouts/_internal/_default/rss.xml

配置RSS

​ 默认情况下,Hugo 将创建无限数量的 RSS 条目。您可以通过在项目的 config 文件 中分配数值给 rssLimit: 字段来限制内置 RSS 模板中包含的文章数量。

​ 如果指定以下值,它们也将包含在 RSS 输出中:

config.

=== “yaml”

``` yaml
author:
  name: My Name Here
copyright: This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
  International License.
languageCode: en-us
```

=== “toml”

``` toml
copyright = 'This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.'
languageCode = 'en-us'
[author]
  name = 'My Name Here'
```

=== “json”

``` json
{
   "author": {
      "name": "My Name Here"
   },
   "copyright": "This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.",
   "languageCode": "en-us"
}
```

内嵌的rss.xml

​ 以下是 Hugo 自带的默认 RSS 模板:

https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml

<head>中引用RSS 订阅

​ 在您的 header.html 模板中,您可以使用 Hugo 的 输出格式<head></head> 标签中指定您的 RSS 订阅,如下所示:

1
2
3
{{ range .AlternativeOutputFormats -}}
    {{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
{{ end -}}

​ 如果您只想要 RSS 链接,则可以查询该格式:

1
2
3
{{ with .OutputFormats.Get "rss" -}}
    {{ printf `<link rel="%s" type="%s" href="%s" title="%s" />` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
{{ end -}}

​ 上述两个片段中的任何一个都将为站点首页生成以下 link 标记以用于 RSS 输出:

1
<link rel="alternate" type="application/rss+xml" href="https://example.com/index.xml" title="Site Title">

在本示例中,我们假设 BaseURLhttps://example.com/$.Site.Title"Site Title"

另请参阅

6.20 - Sitemap模板

Sitemap Templates - Sitemap模板

https://gohugo.io/templates/sitemap-template/

​ Hugo提供了内置的站点地图(sitemap)模板。

概述

​ Hugo的内置站点地图模板符合v0.9的站点地图协议

​ 对于单语言项目,Hugo将在根目录下使用内置的sitemap.xml模板生成一个sitemap.xml文件,该文件位于publishDir中。

​ 对于多语言项目,Hugo会生成:

  • 使用内置的sitemap.xml模板,在每个站点(语言)的根目录中生成一个sitemap.xml文件。
  • 使用内置的sitemapindex.xml模板,在publishDir的根目录中生成一个sitemap.xml文件。

配置

​ 在您的站点配置中设置更改频率优先级和生成的文件名称的默认值。

config.

=== “yaml”

``` yaml
sitemap:
  changefreq: monthly
  filename: sitemap.xml
  priority: 0.5
```

=== “toml”

``` toml
[sitemap]
  changefreq = 'monthly'
  filename = 'sitemap.xml'
  priority = 0.5
```

=== “json”

``` json
{
   "sitemap": {
      "changefreq": "monthly",
      "filename": "sitemap.xml",
      "priority": 0.5
   }
}
```
  • changefreq

    页面更改频率的可能性有多大。有效的值包括alwayshourlydailyweeklymonthlyyearlynever。默认值为""(从渲染的站点地图中省略更改频率)。

  • filename

    生成的文件名称。默认值为sitemap.xml

  • priority

    相对于站点中的其他页面,该页面的优先级。有效值范围为0.0到1.0。默认值为-1(渲染站点地图时省略优先级)。

覆盖默认值

​ 在前置元数据中覆盖给定页面的默认值。

news.md

=== “yaml”

``` yaml
---
sitemap:
  changefreq: weekly
  priority: 0.8
title: News
---
```

=== “toml”

``` toml
+++
title = 'News'
[sitemap]
  changefreq = 'weekly'
  priority = 0.8
+++
```

=== “json”

``` json
{
   "sitemap": {
      "changefreq": "weekly",
      "priority": 0.8
   },
   "title": "News"
}
```

覆盖内置模板

​ 要覆盖内置的sitemap.xml模板,请在以下任一位置创建一个新文件:

  • layouts/sitemap.xml
  • layouts/_default/sitemap.xml

​ 在对页面集合进行排列时,可以使用.Sitemap.ChangeFreq.Sitemap.Priority分别访问更改频率优先级

​ 要覆盖内置的sitemapindex.xml模板,请在以下任一位置创建一个新文件:

  • layouts/sitemapindex.xml
  • layouts/_default/sitemapindex.xml

禁用Sitemap生成

​ 您可以在站点配置中禁用站点地图生成:

config.

=== “yaml”

``` yaml
disableKinds:
- sitemap
```

=== “toml”

``` toml
disableKinds = ['sitemap']
```

=== “json”

``` json
{
   "disableKinds": [
      "sitemap"
   ]
}
```

另请参阅

6.21 - Robots.txt

Robots.txt File - Robots.txt 文件

https://gohugo.io/templates/robots/

​ Hugo 可以像任何其他模板一样生成自定义的 robots.txt 文件。

​ 要从模板生成 robots.txt 文件,请更改站点配置

config.

=== “yaml”

``` yaml
enableRobotsTXT: true
```

=== “toml”

``` toml
enableRobotsTXT = true
```

=== “json”

``` json
{
   "enableRobotsTXT": true
}
```

​ 默认情况下,Hugo使用内置模板生成 robots.txt。

1
User-agent: *

​ 遵守Robots Exclusion Protocol的搜索引擎将把这个文件解释为允许爬取站点上的所有内容。

Robots.txt 模板查找顺序

​ 您可以使用自定义模板覆盖内置模板。Hugo使用以下查找顺序选择模板:

  1. /layouts/robots.txt
  2. /themes/<THEME>/layouts/robots.txt

Robots.txt 模板示例

layouts/robots.txt

1
2
3
4
User-agent: *
{{ range .Pages }}
Disallow: {{ .RelPermalink }}
{{ end }}

​ 该模板将为站点上的每个页面创建一个 robots.txt 文件,使用Disallow指令。遵守Robots Exclusion Protocol的搜索引擎将不会爬取站点上的任何页面。

​ 要创建一个不使用模板的 robots.txt 文件:

  1. 站点配置中将 enableRobotsTXT 设置为 false
  2. static 目录中创建一个 robots.txt 文件。

​ 请记住,Hugo在构建站点时将 static 目录 中的所有内容复制到 publishDir (通常为 public) 的根目录。

6.22 - 内置模板

Internal Templates - 内置模板

https://gohugo.io/templates/internal/

​ Hugo自带一组样板模板,覆盖了静态站点最常见的用例。

​ 虽然以下内置模板类似于局部模板,但它们不遵循局部模板查找顺序。

Google Analytics

​ Hugo自带内置模板支持Google Analytics,包括Google Analytics 4 (GA4)和Universal Analytics。

注意: Universal Analytics已被弃用。有关详情,请参阅Universal Analytics将被取消

Configure Google Analytics

​ 在配置文件中提供您的跟踪ID:

Google Analytics 4 (gtag.js)

config.

=== “yaml”

``` yaml
googleAnalytics: G-MEASUREMENT_ID
```

=== “toml”

``` toml
googleAnalytics = 'G-MEASUREMENT_ID'
```

=== “json”

``` json
{
   "googleAnalytics": "G-MEASUREMENT_ID"
}
```

Google Universal Analytics (analytics.js)

config.

=== “yaml”

``` yaml
googleAnalytics: UA-PROPERTY_ID
```

=== “toml”

``` toml
googleAnalytics = 'UA-PROPERTY_ID'
```

=== “json”

``` json
{
   "googleAnalytics": "UA-PROPERTY_ID"
}
```

使用Google Analytics模板

​ 然后,您可以包含Google Analytics内置模板:

1
{{ template "_internal/google_analytics_async.html" . }}

注意: 异步模板不适用于Google Analytics 4。

1
{{ template "_internal/google_analytics.html" . }}

​ 如果您想创建自己的模板,可以使用 {{ site.Config.Services.GoogleAnalytics.ID }} 访问已配置的ID。

Disqus

​ Hugo还带有用于Disqus评论的内置模板,这是一种流行的静态和动态站点评论系统。要有效地使用Disqus,您需要通过注册免费服务来获得Disqus “shortname”。

配置Disqus

​ 要使用Hugo的Disqus模板,您首先需要设置一个配置值:

config.

=== “yaml”

``` yaml
disqusShortname: your-disqus-shortname
```

=== “toml”

``` toml
disqusShortname = 'your-disqus-shortname'
```

=== “json”

``` json
{
   "disqusShortname": "your-disqus-shortname"
}
```

​ 您还可以选择在给定篇的内容的前置元数据中设置以下值:

  • disqus_identifier
  • disqus_title
  • disqus_url

使用Disqus模板

​ 要添加Disqus,请在要显示评论的模板中包含以下行:

1
{{ template "_internal/disqus.html" . }}

​ 还有一个暴露在配置中的 .Site.DisqusShortname 变量。

Disqus评论的条件加载

​ 用户已经注意到,在运行Hugo Web服务器(即通过hugo server)时启用Disqus评论会导致在关联的Disqus帐户上创建不必要的讨论。

​ 您可以创建以下 layouts/partials/disqus.html

layouts/partials/disqus.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<div id="disqus_thread"></div>
<script type="text/javascript">

(function() {
    // Don't ever inject Disqus on localhost--it creates unwanted
    // discussions from 'localhost:1313' on your Disqus account...
    if (window.location.hostname == "localhost")
        return;

    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
    var disqus_shortname = '{{ .Site.DisqusShortname }}';
    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="https://disqus.com/" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>

​ 当您在本地主机上运行时,if 语句将跳过Disqus评论注入的初始化。

​ 然后可以按以下方式渲染自定义Disqus局部模板:

1
{{ partial "disqus.html" . }}

Open Graph

​ Hugo提供了一个内置模板用于Open Graph协议,这是一种元数据,可使页面成为社交图中的丰富对象。此格式用于Facebook和其他一些站点。

配置Open Graph

​ Hugo的Open Graph模板使用配置变量和个别页面的front-matter的混合来配置。

config.

=== “yaml”

``` yaml
params:
  description: Text about my cool site
  images:
  - site-feature-image.jpg
  title: My cool site
taxonomies:
  series: series
```

=== “toml”

``` toml
[params]
  description = 'Text about my cool site'
  images = ['site-feature-image.jpg']
  title = 'My cool site'
[taxonomies]
  series = 'series'
```

=== “json”

``` json
{
   "params": {
      "description": "Text about my cool site",
      "images": [
         "site-feature-image.jpg"
      ],
      "title": "My cool site"
   },
   "taxonomies": {
      "series": "series"
   }
}
```

content/blog/my-post.

=== “yaml”

``` yaml
audio: []
date: "2006-01-02"
description: Text about this post
images:
- post-cover.png
series: []
tags: []
title: Post title
videos: []
```

=== “toml”

``` toml
audio = []
date = '2006-01-02'
description = 'Text about this post'
images = ['post-cover.png']
series = []
tags = []
title = 'Post title'
videos = []
```

=== “json”

``` json
{
   "audio": [],
   "date": "2006-01-02",
   "description": "Text about this post",
   "images": [
      "post-cover.png"
   ],
   "series": [],
   "tags": [],
   "title": "Post title",
   "videos": []
}
```

​ Hugo使用页面标题和描述作为标题和描述元数据。从 images 数组中取前6个URL用于图像元数据。如果使用页面 bundles,并且 images 数组为空或未定义,则使用与 *feature**cover*,*thumbnail* 匹配的文件名的图像用于图像元数据。

​ 还可以设置各种可选的元数据:

  • 日期、发布日期和最后修改日期用于设置发布时间元数据(如果指定)。
  • audio and videos are URL arrays like images for the audio and video metadata tags, respectively.
  • audiovideo 是与音频和视频元数据标签对应的(与 images 类似) URL 数组。
  • 该页面上前 6 个 tags 用于标签(tags)元数据。
  • series 分类法用于将相关的 “see also"页面放入同一系列。

​ 如果使用 YouTube,这将生成一个类似于 <meta property="og:video" content="url"> 的 og:video 标签。在 YouTube 视频中使用 https://youtu.be/<id> 格式(例如:https://youtu.be/qtIqKaDlqXo)。

使用 Open Graph 模板

​ 要添加 Open Graph 元数据,请在模板的 <head> 标签之间包含以下行:

1
{{ template "_internal/opengraph.html" . }}

Twitter Cards

​ 一个内置的模板,用于为链接到您的站点的推文附加丰富的媒体的Twitter Cards元数据。

配置 Twitter Cards

​ Hugo 的 Twitter Card 模板使用一些配置变量和个别页面的 front-matter 进行混合配置。

config.

=== “yaml”

``` yaml
params:
  description: Text about my cool site
  images:
  - site-feature-image.jpg
```

=== “toml”

``` toml
[params]
  description = 'Text about my cool site'
  images = ['site-feature-image.jpg']
```

=== “json”

``` json
{
   "params": {
      "description": "Text about my cool site",
      "images": [
         "site-feature-image.jpg"
      ]
   }
}
```

content/blog/my-post.

=== “yaml”

``` yaml
description: Text about this post
images:
- post-cover.png
title: Post title
```

=== “toml”

``` toml
description = 'Text about this post'
images = ['post-cover.png']
title = 'Post title'
```

=== “json”

``` json
{
   "description": "Text about this post",
   "images": [
      "post-cover.png"
   ],
   "title": "Post title"
}
```

​ 如果页面的前置元数据中没有指定 images,则 Hugo 会搜索具有 featurecoverthumbnail 名称的 图像页面资源。如果找不到具有这些名称的图像资源,则使用在 站点配置 中定义的图像。如果根本找不到图像,则使用不带图像的 Twitter summary 卡,而不是 summary_large_image

​ Hugo 使用该页面标题和描述作为卡片的标题和描述字段。如果没有给出描述,则使用该页面摘要。

.Site.Social.twitter 变量从配置中暴露,作为 twitter:site 的值。

config.

=== “yaml”

``` yaml
social:
  twitter: GoHugoIO
```

=== “toml”

``` toml
[social]
  twitter = 'GoHugoIO'
```

=== “json”

``` json
{
   "social": {
      "twitter": "GoHugoIO"
   }
}
```

注意:@ 将会自动为您添加。

1
<meta name="twitter:site" content="@GoHugoIO"/>

使用 Twitter Cards 模板

​ 要添加 Twitter 卡片元数据,请在您的模板的 <head> 元素之后立即包含以下行:

1
{{ template "_internal/twitter_cards.html" . }}

内置模板

​ 这些模板的代码位于这里

  • _internal/disqus.html
  • _internal/google_analytics.html
  • _internal/google_analytics_async.html
  • _internal/opengraph.html
  • _internal/pagination.html
  • _internal/schema.html
  • _internal/twitter_cards.html

另请参阅

6.23 - 模板调试

Template Debugging - 模板调试

https://gohugo.io/templates/template-debugging/

​ 您可以使用 Go 模板的 printf 函数来调试 Hugo 模板。这些代码片段提供了一种快速简便的方式来可视化不同上下文中可用的变量。

​ 以下是一些可以添加到您的模板中以回答一些常见问题的代码片段。

​ 这些代码片段使用 Go 模板中的 printf 函数。这个函数是 Go 函数 fmt.Printf 的别名。

此上下文中有哪些变量可用?

​ 您可以使用模板语法 $. 来获取该模板的顶层上下文。这将打印出.Site下的所有值。

1
{{ printf "%#v" $.Site }}

​ 这将打印出.Permalink的值:

1
{{ printf "%#v" .Permalink }}

​ 这将打印出当前上下文(.,也称为"the dot")的所有变量的列表。

1
{{ printf "%#v" . }}

​ 在开发 homepage 时,您正在遍历的页面之一是什么样子的?

1
2
3
4
{{ range .Pages }}
    {{/* The context, ".", is now each one of the pages as it goes through the loop */}}
    {{ printf "%#v" . }}
{{ end }}

为什么我没有显示定义的变量?

​ 检查是否在 partial 函数中传递了变量:

1
{{ partial "header.html" }}

​ 这个例子将渲染 header partial,但 header partial 将没有访问任何上下文变量的权限。您需要显式地传递变量。例如,注意添加了 “the dot”

1
{{ partial "header.html" . }}

​ 点(.)被认为是理解 Hugo 模板的基础。更多信息,请参见 Introduction to Hugo Templating

7 - 函数

7.1 - 函数快速参考

将以下英文翻译为中文:

Functions Quick Reference

https://gohugo.io/functions/

Go templates are lightweight but extensible. Go itself supplies built-in functions, including comparison operators and other basic tools. These are listed in the Go template documentation. Hugo has added additional functions to the basic template logic.

7.2 - .AddDate

.AddDate

​ 返回将给定的年数、月数和天数添加到给定的 time.Time 值所得到的时间。

语法

.AddDate YEARS MONTHS DAYS
{{ $d := "2022-01-01" | time.AsTime }}

{{ $d.AddDate 0 0 1 | time.Format "2006-01-02" }} --> 2022-01-02
{{ $d.AddDate 0 1 1 | time.Format "2006-01-02" }} --> 2022-02-02
{{ $d.AddDate 1 1 1 | time.Format "2006-01-02" }} --> 2023-02-02

{{ $d.AddDate -1 -1 -1 | time.Format "2006-01-02" }} --> 2020-11-30

​ 当增加月份或年份时,如果所得日期不存在,Hugo会将最终的 time.Time 值规范化。例如,在1月31日后增加一个月,会得到3月2日或3月3日,具体取决于年份。

​ 参见Go团队的解释

1
2
3
4
5
6
7
8
{{ $d := "2023-01-31" | time.AsTime }}
{{ $d.AddDate 0 1 0 | time.Format "2006-01-02" }} --> 2023-03-03

{{ $d := "2024-01-31" | time.AsTime }}
{{ $d.AddDate 0 1 0 | time.Format "2006-01-02" }} --> 2024-03-02

{{ $d := "2024-02-29" | time.AsTime }}
{{ $d.AddDate 1 0 0 | time.Format "2006-01-02" }} --> 2025-03-01

另请参阅

7.3 - .Format

将以下英文翻译为中文:

.Format

https://gohugo.io/functions/format/

​ 根据 Go 的布局字符串格式化内置的 Hugo 日期 —— .Date.PublishDate.Lastmod

语法

.Format FORMAT

.Format 将格式化在前置元数据中定义的日期值,并可用作以下页面变量的属性:

  • .PublishDate
  • .Date
  • .Lastmod

​ 假设内容文件前置元数据中有一个键值对 date: 2017-03-03 ,可以通过 .Format ,后跟期望输出的布局字符串来将日期处理后再构建:

1
{{ .PublishDate.Format "January 2, 2006" }} => March 3, 2017

​ 要格式化您前置元数据中定义的任何日期字符串表示形式,请参见 dateFormat 函数,它仍将利用下面解释的Go 布局字符串,但使用略有不同的语法。

Go 的布局字符串

​ 模板通过布局字符串格式化您的日期,该字符串指向特定的参考时间:

Mon Jan 2 15:04:05 MST 2006

​ 虽然这可能看起来是任意的,但 MST 的数字值为 07 ,因此使布局字符串成为数字序列。

​ 这里有一个可视化解释直接取自 Go 文档

 Jan 2 15:04:05 2006 MST
=> 1 2  3  4  5    6  -7

Hugo 日期和时间模板参考

​ 以下示例显示布局字符串,后跟渲染的输出。

​ 这些示例在CST中进行了渲染和测试,并且都指向内容文件前置元数据中的同一字段:

date: 2017-03-03T14:15:59-06:00
  • .Date (即通过页面变量进行调用)

    返回2017-03-03 14:15:59 -0600 CST

  • "Monday, January 2, 2006"

    返回Friday, March 3, 2017

  • "Mon Jan 2 2006"

    返回Fri Mar 3 2017

  • "January 2006"

    返回March 2017

  • "2006-01-02"

    返回2017-03-03

  • "Monday"

    返回Friday

  • "02 Jan 06 15:04 MST" (RFC822)

    返回03 Mar 17 14:15 CST

  • "02 Jan 06 15:04 -0700" (RFC822Z)

    返回03 Mar 17 14:15 -0600

  • "Mon, 02 Jan 2006 15:04:05 MST" (RFC1123)

    返回Fri, 03 Mar 2017 14:15:59 CST

  • "Mon, 02 Jan 2006 15:04:05 -0700" (RFC1123Z)

    返回Fri, 03 Mar 2017 14:15:59 -0600

​ 有关更多示例,请参见go文档中的time包

基数和序数缩写

​ 目前不支持拼写出的基数(例如"one",“two"和"three”)。

​ 使用 humanize函数将月份的日期渲染为序数:

1
{{ humanize .Date.Day }} of {{ .Date.Format "January 2006" }}

​ 这将输出:

5th of March 2017

使用 .Local.UTC

​ 与 dateFormat 函数一起使用,您还可以将日期转换为 UTC 或本地时区:

  • {{ dateFormat "02 Jan 06 15:04 MST" .Date.UTC }}

    返回03 Mar 17 20:15 UTC

  • {{ dateFormat "02 Jan 06 15:04 MST" .Date.Local }}

    返回03 Mar 17 14:15 CST

另请参阅

7.4 - .Get

将以下英文翻译为中文:

.Get

https://gohugo.io/functions/get/

​ 访问简码声明中的位置参数和有序参数。

语法

.Get INDEX
.Get KEY

.Get 是在创建您自己的 简码模板 时专门用于访问传递给它的 位置和命名 参数。当与数字索引一起使用时,它查询位置参数(从 0 开始)。使用字符串键时,它查询命名参数。

​ 当访问不存在的命名或位置参数时,.Get 返回一个空字符串而不是中断构建。这使您可以将 .Getifwithdefaultcond 链接在一起来检查参数是否存在。例如:

1
{{ $quality := default "100" (.Get 1) }}

另请参阅

7.5 - .GetPage

将以下英文翻译为中文:

.GetPage

https://gohugo.io/functions/getpage/

​ 获取给定 pathPage

语法

.GetPage PATH

.GetPage 返回给定 path 的页面。SitePage 都实现了该方法。如果给定相对路径(即没有前导 / 的路径),Page 变量会尝试查找相对于当前页面的页面。

注意: 在 Hugo 0.45 中我们重新设计和简化了 .GetPage API。在此之前,除了路径,您还需要提供一个 Kind 属性,例如 {{ .Site.GetPage "section" "blog" }}。这仍然可以工作,但是现在是多余的(superfluous)。

1
{{ with .Site.GetPage "/blog" }}{{ .Title }}{{ end }}

​ 当找不到页面时,此方法将返回 nil,因此如果找不到blog章节,则上面的示例不会打印任何内容。

​ 要在blog章节中查找一个常规页面:

1
{{ with .Site.GetPage "/blog/my-post.md" }}{{ .Title }}{{ end }}

​ 由于 Page 还提供了一个 .GetPage 方法,因此上述示例与以下示例相同:

1
2
3
{{ with .Site.GetPage "/blog" }}
{{ with .GetPage "my-post.md" }}{{ .Title }}{{ end }}
{{ end }}

.GetPage 和多语言站点

​ 前面的示例使用了完整的内容文件名来查找帖子。根据您的内容组织方式(文件名中是否有语言代码,例如 my-post.en.md),您可能希望在没有扩展名的情况下进行查找。这将为您获取当前语言版本的页面:

1
{{ with .Site.GetPage "/blog/my-post" }}{{ .Title }}{{ end }}

.GetPage 示例

​ 此代码片段(以局部模板的形式)允许您执行以下操作:

  1. 获取 tags 分类法的索引对象。
  2. 将该对象分配给变量 $t
  3. 按受欢迎程度排序与分类法相关联的条目。
  4. 获取分类法中最受欢迎的两个条目(即分配给内容的两个最受欢迎的标签)。

grab-top-two-tags.html

1
2
3
4
5
6
<ul class="most-popular-tags">
{{ $t := .Site.GetPage "/tags" }}
{{ range first 2 $t.Data.Terms.ByCount }}
    <li>{{ . }}</li>
{{ end }}
</ul>

.GetPage 在页面bundle中

​ 如果通过 .GetPage 检索到的页面是Leaf Bundle,并且您需要获取其中的嵌套page资源,则需要使用 .Resources 中的方法,如Page Resources中所述。

​ 有关示例,请参见Headless Bundle文档。

另请参阅

7.6 - .HasMenuCurrent

将以下英文翻译为中文:

.HasMenuCurrent

https://gohugo.io/functions/hasmenucurrent/

语法

PAGE.HasMenuCurrent MENU MENUENTRY

.HasMenuCurrentPage 对象中的一个方法,返回一个布尔值。如果 PAGE 是给定 MENU 中 MENUENTRY 的一个子菜单选项中 .Page 的相同对象,则返回true。

​ 如果 MENUENTRY 的.Page是一个 section,则从 Hugo 0.86.0 开始,此方法对该章节的任何后代也返回true。

​ 您可以在 菜单模板 中找到其使用示例。

另请参阅

7.7 - .IsMenuCurrent

将以下英文翻译为中文:

.IsMenuCurrent

https://gohugo.io/functions/ismenucurrent/

语法

PAGE.IsMenuCurrent MENU MENUENTRY

.IsMenuCurrentPage 对象的一个方法,返回一个 boolean 值。如果 PAGE 是给定 MENU 中 MENUENTRY 中 .Page 的相同对象,则返回true

​ 您可以在 菜单模板 中找到其使用示例。

另请参阅

7.8 - .Param

将以下英文翻译为中文:

.Param

https://gohugo.io/functions/param/

​ 返回一个页面参数,如果存在站点参数则返回站点参数。

语法

.Param KEY

.Param 方法在 .Page 对象中查找给定的 KEY,并返回对应的值。如果无法在页面参数中找到 KEY,则在站点参数中查找 KEY。如果两个位置都找不到 KEY,则 .Param 方法返回 nil

​ 站点和主题开发人员通常在站点级别设置参数,允许内容作者在页面级别上覆盖这些参数。

​ 例如,要在每个页面上显示目录,但允许作者在需要时隐藏目录:

Configuration

config.

=== “yaml”

``` yaml
params:
  display_toc: true
```

=== “toml”

``` toml
[params]
  display_toc = true
```

=== “json”

``` json
{
   "params": {
      "display_toc": true
   }
}
```

Content

content/example.md

=== “yaml”

``` yaml
---
date: "2023-01-01"
display_toc: false
draft: false
title: Example
---
```

=== “toml”

``` toml
+++
date = 2023-01-01
display_toc = false
draft = false
title = 'Example'
+++
```

=== “json”

``` json
{
   "date": "2023-01-01",
   "display_toc": false,
   "draft": false,
   "title": "Example"
}
```

Template

layouts/_default/single.html

1
2
3
{{ if .Param "display_toc" }}
  {{ .TableOfContents }}
{{ end }}

.Param方法返回与给定KEY关联的值,无论该值是否为真值或假值。如果需要忽略假值,请改用此构造:

layouts/_default/single.html

1
{{ or .Params.foo site.Params.foo }}

另请参阅

7.9 - .Render

将以下英文翻译为中文:

.Render

https://gohugo.io/functions/render/

​ 应用视图来渲染内容。

语法

.Render LAYOUT

​ 该视图是一种替代布局,应该是一个文件名,指向 内容视图 文档中指定位置之一的模板。

​ 此函数仅适用于 列表上下文 中的单个内容。

​ 例如,下面的示例可以使用位于 /layouts/_default/summary.html 中的内容视图来渲染一篇内容:

1
2
3
{{ range .Pages }}
  {{ .Render "summary" }}
{{ end }}

另请参阅

7.10 - .RenderString

将以下英文翻译为中文:

.RenderString

https://gohugo.io/functions/renderstring/

​ 将标记渲染为 HTML。

语法

.RenderString MARKUP

.RenderStringPage 上的方法,它使用为该页面定义的内容渲染器(如果选项中未设置)将一些标记渲染为 HTML。

​ 该方法带有一个可选的 map 参数,其中包含以下选项:

  • display (“inline”)

    inline or block. If inline (default), surrounding <p></p> on short snippets will be trimmed.

    inlineblock 。如果是 inline (默认值),则会在简码片段周围修剪 <p></p>

  • markup (defaults to the Page’s markup)

    请参见内容格式列表中的标识符。

以下是一些示例:

1
2
3
4
5
{{ $optBlock := dict "display" "block" }}
{{ $optOrg := dict "markup" "org" }}
{{ "**Bold Markdown**" | $p.RenderString }}
{{ "**Bold Block Markdown**" | $p.RenderString  $optBlock }}
{{ "/italic org mode/" | $p.RenderString  $optOrg }}

自 v0.93.0 开始使用 注意markdownify 使用此函数以支持 Render Hooks

另请参阅

7.11 - .Scratch

将以下英文翻译为中文:

.Scratch

https://gohugo.io/functions/scratch/

​ 该函数用作 “草稿本”,用于存储和操作数据。

​ Scratch 是 Hugo 的一个功能,旨在方便地在 Go 模板中操纵数据。它是一个 Page 或 简码方法,其结果数据将被附加到给定的上下文中,或者它可以作为存储在变量中的唯一实例。

​ 请注意,Scratch 最初是作为一个解决方案创建的,以解决影响 0.48 版本之前的 Hugo 的Go 模板作用域限制问题。有关.Scratch和上下文用例的详细分析,请参阅这篇博客文章

带有上下文的 .Scratch vs. 本地的 newScratch

​ 自 Hugo 0.43 起,有两种使用 Scratch 的不同方式:

页面的 .Scratch

.Scratch 作为Page 方法或 简码方法可用,并将“草稿”数据附加到给定页面上。使用 .Scratch 必须要在 Page 或 简码上下文中。

1
2
3
4
{{ .Scratch.Set "greeting" "bonjour" }}
{{ range .Pages }}
  {{ .Scratch.Set "greeting" (print "bonjour" .Title) }}
{{ end }}

本地的 newScratch

​ 使用 newScratch 函数,可以将 Scratch 实例分配给任何变量。 在这种情况下,不需要Page 或 简码上下文,而 Scratch 的作用域仅为本地。以下方法可以从已分配 Scratch 实例的变量中使用:

1
2
{{ $data := newScratch }}
{{ $data.Set "greeting" "hola" }}

方法

​ Scratch 具有以下方法:

​ 请注意,以下示例假设已在 $scratch 中存储了 本地 Scratch 实例

.Set

​ 设置给定键的值。

1
{{ $scratch.Set "greeting" "Hello" }}

.Get

​ 获取给定键的值。

1
2
3
{{ $scratch.Set "greeting" "Hello" }}
----
{{ $scratch.Get "greeting" }} > Hello

.Add

​ 将给定值添加到给定键的现有值中。

​ 对于单个值,Add接受支持 Go 的 + 运算符的值。如果某个键的第一个 Add 是一个数组或切片,则后续添加的内容将追加到该列表中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ $scratch.Add "greetings" "Hello" }}
{{ $scratch.Add "greetings" "Welcome" }}
----
{{ $scratch.Get "greetings" }} > HelloWelcome
{{ $scratch.Add "total" 3 }}
{{ $scratch.Add "total" 7 }}
----
{{ $scratch.Get "total" }} > 10
{{ $scratch.Add "greetings" (slice "Hello") }}
{{ $scratch.Add "greetings" (slice "Welcome" "Cheers") }}
----
{{ $scratch.Get "greetings" }} > []interface {}{"Hello", "Welcome", "Cheers"}

.SetInMap

Takes a key, mapKey and value and adds a map of mapKey and value to the given key.

​ 接收一个 keymapKeyvalue ,并将 mapKeyvalue 的映射添加到给定的 key 中。

1
2
3
4
{{ $scratch.SetInMap "greetings" "english" "Hello" }}
{{ $scratch.SetInMap "greetings" "french" "Bonjour" }}
----
{{ $scratch.Get "greetings" }} > map[french:Bonjour english:Hello]

.DeleteInMap

Takes a key and mapKey and removes the map of mapKey from the given key.

​ 接收一个 keymapKey ,并从给定的 key 中删除 mapKey 的映射。

1
2
3
4
5
6
{{ .Scratch.SetInMap "greetings" "english" "Hello" }}
{{ .Scratch.SetInMap "greetings" "french" "Bonjour" }}
----
{{ .Scratch.DeleteInMap "greetings" "english" }}
----
{{ .Scratch.Get "greetings" }} > map[french:Bonjour]

.GetSortedMapValues

Return an array of values from key sorted by mapKey.

​ 按 mapKey 排序,返回 key 中的值数组。

1
2
3
4
{{ $scratch.SetInMap "greetings" "english" "Hello" }}
{{ $scratch.SetInMap "greetings" "french" "Bonjour" }}
----
{{ $scratch.GetSortedMapValues "greetings" }} > [Hello Bonjour]

.Delete

Remove the given key.

​ 删除给定的键。

1
2
3
{{ $scratch.Set "greeting" "Hello" }}
----
{{ $scratch.Delete "greeting" }}

.Values

Return the raw backing map. Note that you should only use this method on the locally scoped Scratch instances you obtain via newScratch, not .Page.Scratch etc., as that will lead to concurrency issues.

​ 返回原始的后备映射。注意,只应在通过 newScratch 获得的局部范围的Scratch实例上使用此方法,而不是 .Page.Scratch 等,因为会导致并发问题。

另请参阅

7.12 - .Store

将以下英文翻译为中文:

.Store

https://gohugo.io/functions/store/

Returns a Scratch that is not reset on server rebuilds.

The .Store method on .Page returns a Scratch to store and manipulate data. In contrast to the .Scratch method, this Scratch is not reset on server rebuilds.

Methods

.Set

Sets the value of a given key.

1
{{ .Store.Set "greeting" "Hello" }}

.Get

Gets the value of a given key.

1
2
3
{{ .Store.Set "greeting" "Hello" }}

{{ .Store.Get "greeting" }} → Hello

.Add

Adds a given value to existing value(s) of the given key.

For single values, Add accepts values that support Go’s + operator. If the first Add for a key is an array or slice, the following adds will be appended to that list.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ .Store.Add "greetings" "Hello" }}
{{ .Store.Add "greetings" "Welcome" }}

{{ .Store.Get "greetings" }} → HelloWelcome
{{ .Store.Add "total" 3 }}
{{ .Store.Add "total" 7 }}

{{ .Store.Get "total" }} → 10
{{ .Store.Add "greetings" (slice "Hello") }}
{{ .Store.Add "greetings" (slice "Welcome" "Cheers") }}

{{ .Store.Get "greetings" }} → []interface {}{"Hello", "Welcome", "Cheers"}

.SetInMap

Takes a key, mapKey and value and adds a map of mapKey and value to the given key.

1
2
3
4
{{ .Store.SetInMap "greetings" "english" "Hello" }}
{{ .Store.SetInMap "greetings" "french" "Bonjour" }}

{{ .Store.Get "greetings" }} → map[french:Bonjour english:Hello]

.DeleteInMap

Takes a key and mapKey and removes the map of mapKey from the given key.

1
2
3
4
5
{{ .Store.SetInMap "greetings" "english" "Hello" }}
{{ .Store.SetInMap "greetings" "french" "Bonjour" }}
{{ .Store.DeleteInMap "greetings" "english" }}

{{ .Store.Get "greetings" }} → map[french:Bonjour]

.GetSortedMapValues

Returns an array of values from key sorted by mapKey.

1
2
3
4
{{ .Store.SetInMap "greetings" "english" "Hello" }}
{{ .Store.SetInMap "greetings" "french" "Bonjour" }}

{{ .Store.GetSortedMapValues "greetings" }} → [Hello Bonjour]

.Delete

Removes the given key.

1
2
3
{{ .Store.Set "greeting" "Hello" }}

{{ .Store.Delete "greeting" }}

另请参阅

7.13 - .Unix

将以下英文翻译为中文:

.Unix

https://gohugo.io/functions/unix/

Converts a time.Time value to the number of seconds elapsed since the Unix epoch, excluding leap seconds. The Unix epoch is 00:00:00 UTC on 1 January 1970.

语法

.Unix
.UnixMilli
.UnixMicro
.UnixNano

The Milli, Micro, and Nano variants return the number of milliseconds, microseconds, and nanoseconds (respectively) elapsed since the Unix epoch.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
.Date.Unix        --> 1637259694
.ExpiryDate.Unix  --> 1672559999
.Lastmod.Unix     --> 1637361786
.PublishDate.Unix --> 1637421261

("1970-01-01T00:00:00-00:00" | time.AsTime).Unix --> 0
("1970-01-01T00:00:42-00:00" | time.AsTime).Unix --> 42
("1970-04-11T01:48:29-08:00" | time.AsTime).Unix --> 8675309
("2026-05-02T20:09:31-07:00" | time.AsTime).Unix --> 1777777771

now.Unix      --> 1637447841
now.UnixMilli --> 1637447841347
now.UnixMicro --> 1637447841347378
now.UnixNano  --> 1637447841347378799

另请参阅

7.14 - absLangURL

将以下英文翻译为中文:

absLangURL

https://gohugo.io/functions/abslangurl/

Returns an absolute URL with a language prefix, if any.

语法

absLangURL INPUT

Use this function with both monolingual and multilingual configurations. The URL returned by this function depends on:

  • Whether the input begins with a slash
  • The baseURL in site configuration
  • The language prefix, if any

In examples that follow, the project is multilingual with content in both Español (es) and English (en). The default language is Español. The returned values are from the English site.

Input does not begin with a slash

If the input does not begin with a slash, the resulting URL will be correct regardless of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ absLangURL "" }}           →   https://example.org/en/
{{ absLangURL "articles" }}   →   https://example.org/en/articles
{{ absLangURL "style.css" }}  →   https://example.org/en/style.css

With baseURL = https://example.org/docs/

1
2
3
{{ absLangURL "" }}           →   https://example.org/docs/en/
{{ absLangURL "articles" }}   →   https://example.org/docs/en/articles
{{ absLangURL "style.css" }}  →   https://example.org/docs/en/style.css

Input begins with a slash

If the input begins with a slash, the resulting URL will be incorrect when the baseURL includes a subdirectory. With a leading slash, the function returns a URL relative to the protocol+host section of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ absLangURL "/" }}          →   https://example.org/en/
{{ absLangURL "/articles" }}  →   https://example.org/en/articles
{{ absLangURL "/style.css" }} →   https://example.org/en/style.css

With baseURL = https://example.org/docs/

1
2
3
{{ absLangURL "/" }}          →   https://example.org/en/
{{ absLangURL "/articles" }}  →   https://example.org/en/articles
{{ absLangURL "/style.css" }} →   https://example.org/en/style.css

The last three examples are not desirable in most situations. As a best practice, never include a leading slash when using this function.

另请参阅

7.15 - absURL

将以下英文翻译为中文:

absURL

https://gohugo.io/functions/absurl/

Returns an absolute URL.

语法

absURL INPUT

With multilingual configurations, use the absLangURL function instead. The URL returned by this function depends on:

  • Whether the input begins with a slash
  • The baseURL in site configuration

Input does not begin with a slash

If the input does not begin with a slash, the resulting URL will be correct regardless of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ absURL "" }}           →   https://example.org/
{{ absURL "articles" }}   →   https://example.org/articles
{{ absURL "style.css" }}  →   https://example.org/style.css

With baseURL = https://example.org/docs/

1
2
3
{{ absURL "" }}           →   https://example.org/docs/
{{ absURL "articles" }}   →   https://example.org/docs/articles
{{ absURL "style.css" }}  →   https://example.org/docs/style.css

Input begins with a slash

If the input begins with a slash, the resulting URL will be incorrect when the baseURL includes a subdirectory. With a leading slash, the function returns a URL relative to the protocol+host section of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ absURL "/" }}          →   https://example.org/
{{ absURL "/articles" }}  →   https://example.org/articles
{{ absURL "/style.css" }} →   https://example.org/style.css

With baseURL = https://example.org/docs/

1
2
3
{{ absURL "/" }}          →   https://example.org/
{{ absURL "/articles" }}  →   https://example.org/articles
{{ absURL "/style.css" }} →   https://example.org/style.css

The last three examples are not desirable in most situations. As a best practice, never include a leading slash when using this function.

另请参阅

7.16 - after

将以下英文翻译为中文:

after

https://gohugo.io/functions/after/

after slices an array to only the items after the Nth item.

语法

after INDEX COLLECTION

The following shows after being used in conjunction with the slice function:

1
2
3
4
5
{{ $data := slice "one" "two" "three" "four" }}
{{ range after 2 $data }}
    {{ . }}
{{ end }}
→ ["three", "four"]

Example of after with first: 2nd–4th Most Recent Articles

You can use after in combination with the first function and Hugo’s powerful sorting methods. Let’s assume you have a list page at example.com/articles. You have 10 articles, but you want your templating for the list/section page to show only two rows:

  1. The top row is titled “Featured” and shows only the most recently published article (i.e. by publishdate in the content files’ front matter).
  2. The second row is titled “Recent Articles” and shows only the 2nd- to 4th-most recently published articles.

layouts/section/articles.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
{{ define "main" }}
<section class="row featured-article">
  <h2>Featured Article</h2>
  {{ range first 1 .Pages.ByPublishDate.Reverse }}
  <header>
      <h3><a href="{{ . Permalink }}">{{ .Title }}</a></h3>
  </header>
  <p>{{ .Description }}</p>
{{ end }}
</section>
<div class="row recent-articles">
  <h2>Recent Articles</h2>
  {{ range first 3 (after 1 .Pages.ByPublishDate.Reverse) }}
    <section class="recent-article">
      <header>
          <h3><a href="{{ .Permalink }}">{{ .Title }}</a></h3>
      </header>
      <p>{{ .Description }}</p>
    </section>
  {{ end }}
</div>
{{ end }}

另请参阅

7.17 - anchorize

将以下英文翻译为中文:

anchorize

https://gohugo.io/functions/anchorize/

Takes a string and sanitizes it the same way as the defaultMarkdownHandler does for markdown headers.

语法

anchorize INPUT

If Goldmark is set as defaultMarkdownHandler, the sanitizing logic adheres to the setting markup.goldmark.parser.autoHeadingIDType.

Since the defaultMarkdownHandler and this template function use the same sanitizing logic, you can use the latter to determine the ID of a header for linking with anchor tags.

1
2
3
4
5
6
{{ anchorize "This is a header" }} --> "this-is-a-header"
{{ anchorize "This is also    a header" }} --> "this-is-also----a-header"
{{ anchorize "main.go" }} --> "maingo"
{{ anchorize "Article 123" }} --> "article-123"
{{ anchorize "<- Let's try this, shall we?" }} --> "--lets-try-this-shall-we"
{{ anchorize "Hello, 世界" }} --> "hello-世界"

另请参阅

7.18 - append

将以下英文翻译为中文:

append

https://gohugo.io/functions/append/

append appends one or more values to a slice and returns the resulting slice.

语法

COLLECTION | append VALUE [VALUE]...
COLLECTION | append COLLECTION

An example appending single values:

1
2
3
{{ $s := slice "a" "b" "c" }}
{{ $s = $s | append "d" "e" }}
{{/* $s now contains a []string with elements "a", "b", "c", "d", and "e" */}}

The same example appending a slice to a slice:

1
2
{{ $s := slice "a" "b" "c" }}
{{ $s = $s | append (slice "d" "e") }}

The append function works for all types, including Pages.

另请参阅

7.19 - apply

将以下英文翻译为中文:

apply

https://gohugo.io/functions/apply/

Given a map, array, or slice, apply returns a new slice with a function applied over it.

语法

apply COLLECTION FUNCTION [PARAM...]

apply expects at least three parameters, depending on the function being applied.

  1. The first parameter is the sequence to operate on.
  2. The second parameter is the name of the function as a string, which must be the name of a valid Hugo function.
  3. After that, the parameters to the applied function are provided, with the string "." standing in for each element of the sequence the function is to be applied against.

Here is an example of a content file with names: as a front matter field:

content/example.md

=== “yaml”

``` yaml
---
names:
- Derek Perkins
- Joe Bergevin
- Tanner Linsley
title: Example
---
```

=== “toml”

``` toml
+++
names = ['Derek Perkins', 'Joe Bergevin', 'Tanner Linsley']
title = 'Example'
+++
```

=== “json”

``` json
{
   "names": [
      "Derek Perkins",
      "Joe Bergevin",
      "Tanner Linsley"
   ],
   "title": "Example"
}
```

You can then use apply as follows:

1
{{ apply .Params.names "urlize" "." }}

Which will result in the following:

"derek-perkins", "joe-bergevin", "tanner-linsley"

This is roughly equivalent to using the following with range:

1
{{ range .Params.names }}{{ . | urlize }}{{ end }}

However, it is not possible to provide the output of a range to the delimit function, so you need to apply it.

If you have post-tag-list.html and post-tag-link.html as partials, you could use the following snippets, respectively:

layouts/partials/post-tag-list.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{{ with .Params.tags }}
  <div class="tags-list">
    Tags:
    {{ $len := len . }}
    {{ if eq $len 1 }}
      {{ partial "post-tag-link.html" (index . 0) }}
    {{ else }}
      {{ $last := sub $len 1 }}
      {{ range first $last . }}
        {{ partial "post-tag-link.html" . }},
      {{ end }}
      {{ partial "post-tag-link.html" (index . $last) }}
    {{ end }}
  </div>
{{ end }}

layouts/partials/post-tag-link.html

1
<a class="post-tag post-tag-{{ . | urlize }}" href="/tags/{{ . | urlize }}">{{ . }}</a>

This works, but the complexity of post-tag-list.html is fairly high. The Hugo template needs to perform special behavior for the case where there’s only one tag, and it has to treat the last tag as special. Additionally, the tag list will be rendered something like Tags: tag1 , tag2 , tag3 because of the way that the HTML is generated and then interpreted by a browser.

This first version of layouts/partials/post-tag-list.html separates all of the operations for ease of reading. The combined and DRYer version is shown next:

1
2
3
4
5
6
7
8
9
{{ with .Params.tags }}
  <div class="tags-list">
    Tags:
    {{ $sort := sort . }}
    {{ $links := apply $sort "partial" "post-tag-link.html" "." }}
    {{ $clean := apply $links "chomp" "." }}
    {{ delimit $clean ", " }}
  </div>
{{ end }}

Now in the completed version, you can sort the tags, convert the tags to links with layouts/partials/post-tag-link.html, chomp off stray newlines, and join the tags together in a delimited list for presentation. Here is an even DRYer version of the preceding example:

layouts/partials/post-tag-list.html

1
2
3
4
5
6
{{ with .Params.tags }}
  <div class="tags-list">
    Tags:
    {{ delimit (apply (apply (sort .) "partial" "post-tag-link.html" ".") "chomp" ".") ", " }}
  </div>
{{ end }}

apply does not work when receiving the sequence as an argument through a pipeline.

7.20 - base64

将以下英文翻译为中文:

base64

https://gohugo.io/functions/base64/

base64Encode and base64Decode let you easily decode content with a base64 encoding and vice versa through pipes.

语法

base64Decode INPUT
base64Encode INPUT
{{ "Hugo" | base64Encode }} → "SHVnbw=="
{{ "SHVnbw==" | base64Decode }} → "Hugo"

base64 with APIs

Using base64 to decode and encode becomes really powerful if we have to handle responses from APIs.

1
2
{{ $resp := getJSON "https://api.github.com/repos/gohugoio/hugo/readme" }}
{{ $resp.content | base64Decode | markdownify }}

The response of the GitHub API contains the base64-encoded version of the README.md in the Hugo repository. Now we can decode it and parse the Markdown. The final output will look similar to the rendered version on GitHub.

7.21 - chomp

将以下英文翻译为中文:

chomp

https://gohugo.io/functions/chomp/

Removes any trailing newline characters.

语法

chomp INPUT
strings.Chomp INPUT

Useful in a pipeline to remove newlines added by other processing (e.g., markdownify).

1
{{ chomp "<p>Blockhead</p>\n" }} → "<p>Blockhead</p>"

7.22 - complement

将以下英文翻译为中文:

complement

https://gohugo.io/functions/complement/

Returns the elements of the last collection that are not in any of the others.

语法

complement COLLECTION [COLLECTION]...
collections.Complement COLLECTION [COLLECTION]...

To find the elements within $c3 that do not exist in $c1 or $c2:

1
2
3
4
5
{{ $c1 := slice 3 }}
{{ $c2 := slice 4 5 }}
{{ $c3 := slice 1 2 3 4 5 }}

{{ complement $c1 $c2 $c3 }} → [1 2]

Make your code simpler to understand by using a chained pipeline:

1
{{ $c3 | complement $c1 $c2 }} → [1 2]

You can also use the complement function with page collections. Let’s say your site has five content types:

1
2
3
4
5
6
content/
├── blog/
├── books/
├── faqs/
├── films/
└── songs/

To list everything except blog articles (blog) and frequently asked questions (faqs):

1
2
3
4
5
{{ $blog := where site.RegularPages "Type" "blog" }}
{{ $faqs := where site.RegularPages "Type" "faqs" }}
{{ range site.RegularPages | complement $blog $faqs }}
  <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
{{ end }}

Although the example above demonstrates the complement function, you could use the where function as well:

1
2
3
{{ range where site.RegularPages "Type" "not in" (slice "blog" "faqs") }}
  <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
{{ end }}

In this example we use the complement function to remove stop words from a sentence:

1
2
3
4
5
{{ $text := "The quick brown fox jumps over the lazy dog" }}
{{ $stopWords := slice "a" "an" "in" "over" "the" "under" }}
{{ $filtered := split $text " " | complement $stopWords }}

{{ delimit $filtered " " }} → The quick brown fox jumps lazy dog

另请参阅

7.23 - cond

将以下英文翻译为中文:

cond

https://gohugo.io/functions/cond/

Return one of two arguments, depending on the value of a third argument.

语法

cond CONTROL VAR1 VAR2

cond returns VAR1 if CONTROL is true, or VAR2 if it is not.

Example:

1
{{ cond (eq (len $geese) 1) "goose" "geese" }}

Would emit “goose” if the $geese array has exactly 1 item, or “geese” otherwise.

Whenever you use a cond function, both variable expressions are always evaluated. This means that a usage like cond false (div 1 0) 27 will throw an error because div 1 0 will be evaluated even though the condition is false.

In other words, the cond function does not provide short-circuit evaluation and does not work like a normal ternary operator that will pass over the first expression if the condition returns false.

7.24 - countrunes

将以下英文翻译为中文:

countrunes

https://gohugo.io/functions/countrunes/

Determines the number of runes in a string excluding any whitespace.

语法

countrunes INPUT
strings.CountRunes INPUT

In contrast with countwords function, which counts every word in a string, the countrunes function determines the number of runes in the content and excludes any whitespace. This has specific utility if you are dealing with CJK-like languages.

1
2
{{ "Hello, 世界" | countrunes }}
<!-- outputs a content length of 8 runes. -->

另请参阅

7.25 - countwords

将以下英文翻译为中文:

countwords

https://gohugo.io/functions/countwords/

Counts the number of words in a string.

语法

countwords INPUT

The template function works similar to the .WordCount page variable.

1
2
{{ "Hugo is a static site generator." | countwords }}
<!-- outputs a content length of 6 words.  -->

另请参阅

7.26 - crypto.FNV32a

将以下英文翻译为中文:

crypto.FNV32a

https://gohugo.io/functions/crypto.fnv32a/

Returns the FNV (Fowler–Noll–Vo) 32 bit hash of a given string.

语法

crypto.FNV32a STRING

This function calculates the 32 bit FNV1a hash of a given string according to the specification:

{{ crypto.FNV32a "Hello world" }} → 1498229191

7.27 - default

将以下英文翻译为中文:

default

https://gohugo.io/functions/default/

default函数用于当第一个值未被设置时,返回可以被返回的默认值。

语法

default DEFAULT INPUT

default函数检查给定值是否被设置,如果没有被设置,则返回默认值。在此上下文中,“设置”意味着不同的事情,具体取决于数据类型:

  • 对于数字类型和时间类型,为非零值
  • 对于字符串、数组、切片和映射,为非零长度
  • 对于布尔或结构体值,为任何值
  • 对于任何其他类型,为非nil值

default函数示例引用以下内容页面:

content/posts/default-function-example.md

1
2
3
4
5
6
7
8
---
title: Sane Defaults
seo_title:
date: 2017-02-18
font:
oldparam: The default function helps make your templating DRYer.
newparam:
---

default可以以多种方式编写:

1
2
{{ .Params.font | default "Roboto" }}
{{ default "Roboto" .Params.font }}

​ 上述两个 default函数调用都返回Roboto

​ 但是,default值不需要像上面的例子一样被硬编码。default值可以是变量或直接使用点符号从前置元数据中提取:

1
2
{{ $old := .Params.oldparam }}
<p>{{ .Params.newparam | default $old }}</p>

它将返回:

1
<p>The default function helps make your templating DRYer.</p>

然后使用点符号:

1
<title>{{ .Params.seo_title | default .Title }}</title>

它将返回:

1
<title>Sane Defaults</title>

​ 以下内容具有等效的返回值,但default更为简洁。这演示了default的实用性:

使用if:

1
2
<title>{{ if .Params.seo_title }}{{ .Params.seo_title }}{{ else }}{{ .Title }}{{ end }}</title>
=> Sane Defaults

使用with:

1
2
<title>{{ with .Params.seo_title }}{{ . }}{{ else }}{{ .Title }}{{ end }}</title>
=> Sane Defaults

7.28 - delimit

将以下英文翻译为中文:

delimit

https://gohugo.io/functions/delimit/

Loops through any array, slice, or map and returns a string of all the values separated by a delimiter.

语法

delimit COLLECTION DELIMITER [LAST]

Delimit a slice:

1
2
3
{{ $s := slice "b" "a" "c" }}
{{ delimit $s ", " }} → "b, a, c"
{{ delimit $s ", " " and "}} → "b, a and c"

Delimit a map:

The delimit function sorts maps by key, returning the values.

1
2
3
{{ $m := dict "b" 2 "a" 1 "c" 3 }}
{{ delimit $m ", " }} → "1, 2, 3"
{{ delimit $m ", " " and "}} → "1, 2 and 3"

另请参阅

7.29 - dict

将以下英文翻译为中文:

dict

https://gohugo.io/functions/dict/

Creates a dictionary from a list of key and value pairs.

语法

dict KEY VALUE [KEY VALUE]...

dict is especially useful for passing more than one value to a partial template.

Note that the key can be either a string or a string slice. The latter is useful to create a deeply nested structure, e.g.:

1
{{ $m := dict (slice "a" "b" "c") "value" }}

Example: Using dict to pass multiple values to a partial

The partial below creates an SVG and expects fill, height and width from the caller:

Partial definition

layouts/partials/svgs/external-links.svg

1
2
3
4
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
fill="{{ .fill }}" width="{{ .width }}" height="{{ .height }}" viewBox="0 0 32 32" aria-label="External Link">
<path d="M25.152 16.576v5.696q0 2.144-1.504 3.648t-3.648 1.504h-14.848q-2.144 0-3.648-1.504t-1.504-3.648v-14.848q0-2.112 1.504-3.616t3.648-1.536h12.576q0.224 0 0.384 0.16t0.16 0.416v1.152q0 0.256-0.16 0.416t-0.384 0.16h-12.576q-1.184 0-2.016 0.832t-0.864 2.016v14.848q0 1.184 0.864 2.016t2.016 0.864h14.848q1.184 0 2.016-0.864t0.832-2.016v-5.696q0-0.256 0.16-0.416t0.416-0.16h1.152q0.256 0 0.416 0.16t0.16 0.416zM32 1.152v9.12q0 0.48-0.352 0.8t-0.8 0.352-0.8-0.352l-3.136-3.136-11.648 11.648q-0.16 0.192-0.416 0.192t-0.384-0.192l-2.048-2.048q-0.192-0.16-0.192-0.384t0.192-0.416l11.648-11.648-3.136-3.136q-0.352-0.352-0.352-0.8t0.352-0.8 0.8-0.352h9.12q0.48 0 0.8 0.352t0.352 0.8z"></path>
</svg>

Partial call

The fill, height and width values can be stored in one object with dict and passed to the partial:

layouts/_default/list.html

1
{{ partial "svgs/external-links.svg" (dict "fill" "#01589B" "width" 10 "height" 20 ) }}

另请参阅

7.30 - duration

将以下英文翻译为中文:

duration

https://gohugo.io/functions/duration/

Returns a time.Duration structure, using the given time unit and duration number.

语法

duration TIME_UNIT DURATION_NUMBER

time.Duration converts a given number into a time.Duration structure so you can access its fields. E.g. you can perform time operations on the returned time.Duration value:

{{ printf "There are %.0f seconds in one day." (duration "hour" 24).Seconds }}
<!-- Output: There are 86400 seconds in one day. -->

Make your code simpler to understand by using a chained pipeline:

{{ mul 7.75 60 | duration "minute" }} → 7h45m0s
{{ mul 120 60 | mul 1000 | duration "millisecond" }} → 2h0m0s

You have to specify a time unit for the number given to the function. Valid time units are:

DurationValid time units
hourshour, h
minutesminute, m
secondssecond, s
millisecondsmillisecond, ms
microsecondsmicrosecond, us, µs
nanosecondsnanosecond, ns

7.31 - echoParam

将以下英文翻译为中文:

echoParam

https://gohugo.io/functions/echoparam/

Prints a parameter if it is set.

语法

echoParam DICTIONARY KEY
{{ echoParam .Params "project_url" }}

7.32 - emojify

将以下英文翻译为中文:

emojify

https://gohugo.io/functions/emojify/

Runs a string through the Emoji emoticons processor.

语法

emojify INPUT

emojify runs a passed string through the Emoji emoticons processor.

See the Emoji cheat sheet for available emoticons.

The emojify function can be called in your templates but not directly in your content files by default. For emojis in content files, set enableEmoji to true in your site’s configuration. Then you can write emoji shorthand directly into your content files; e.g. I :heart: Hugo!:

I ❤️ Hugo!

另请参阅

7.33 - eq

将以下英文翻译为中文:

eq

https://gohugo.io/functions/eq/

Returns the boolean truth of arg1 == arg2.

语法

eq ARG1 ARG2
{{ if eq .Section "blog" }}current{{ end }}

另请参阅

7.34 - errorf 和 warnf

将以下英文翻译为中文:

errorf and warnf

https://gohugo.io/functions/errorf/

Log ERROR or WARNING from the templates.

语法

errorf FORMAT INPUT

errorf or warnf will evaluate a format string, then output the result to the ERROR or WARNING log (and only once per error message to avoid flooding the log).

Any ERROR will also cause the build to fail (the hugo command will exit -1).

Both functions return an empty string, so the messages are only printed to the console.

1
2
{{ errorf "Failed to handle page %q" .Path }}
{{ warnf "You should update the shortcodes in %q" .Path }}

Note that errorf, erroridf, and warnf support all the formatting verbs of the fmt package.

Suppress errors

Sometimes it may make sense to let the user suppress an ERROR and make the build succeed.

You can do this by using the erroridf function. This functions takes an error ID as the first argument.

1
{{ erroridf "my-custom-error" "You should consider fixing this." }}

This will produce:

ERROR 2021/06/07 17:47:38 You should consider fixing this.
If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config:
ignoreErrors = ["my-custom-error"]

另请参阅

7.35 - fileExists

将以下英文翻译为中文:

fileExists

https://gohugo.io/functions/fileexists/

Checks for file or directory existence.

语法

os.FileExists PATH
fileExists PATH

The os.FileExists function attempts to resolve the path relative to the root of your project directory. If a matching file or directory is not found, it will attempt to resolve the path relative to the contentDir. A leading path separator (/) is optional.

With this directory structure:

1
2
3
4
5
6
content/
├── about.md
├── contact.md
└── news/
    ├── article-1.md
    └── article-2.md

The function returns these values:

1
2
3
4
5
6
7
{{ os.FileExists "content" }} --> true
{{ os.FileExists "content/news" }} --> true
{{ os.FileExists "content/news/article-1" }} --> false
{{ os.FileExists "content/news/article-1.md" }} --> true
{{ os.FileExists "news" }} --> true
{{ os.FileExists "news/article-1" }} --> false
{{ os.FileExists "news/article-1.md" }} --> true

7.36 - findRE

将以下英文翻译为中文:

findRE

https://gohugo.io/functions/findre/

Returns a slice of strings that match the regular expression.

语法

findRE PATTERN INPUT [LIMIT]
strings.FindRE PATTERN INPUT [LIMIT]

By default, findRE finds all matches. You can limit the number of matches with an optional LIMIT parameter.

When specifying the regular expression, use a raw string literal (backticks) instead of an interpreted string literal (double quotes) to simplify the syntax. With an interpreted string literal you must escape backslashes.

This function uses the RE2 regular expression library. See the RE2 syntax documentation for details. Note that the RE2 \C escape sequence is not supported.

The RE2 syntax is a subset of that accepted by PCRE, roughly speaking, and with various caveats.

This example returns a slice of all second level headings (h2 elements) within the rendered .Content:

1
{{ findRE `(?s)<h2.*?>.*?</h2>` .Content }}

The s flag causes . to match \n as well, allowing us to find an h2 element that contains newlines.

To limit the number of matches to one:

1
{{ findRE `(?s)<h2.*?>.*?</h2>` .Content 1 }}

You can write and test your regular expression using regex101.com. Be sure to select the Go flavor before you begin.

另请参阅

7.37 - findRESubmatch

将以下英文翻译为中文:

findRESubmatch

https://gohugo.io/functions/findresubmatch/

Returns a slice of all successive matches of the regular expression. Each element is a slice of strings holding the text of the leftmost match of the regular expression and the matches, if any, of its subexpressions.

语法

findRESubmatch PATTERN INPUT [LIMIT]
strings.FindRESubmatch PATTERN INPUT [LIMIT]

By default, findRESubmatch finds all matches. You can limit the number of matches with an optional LIMIT parameter. A return value of nil indicates no match.

When specifying the regular expression, use a raw string literal (backticks) instead of an interpreted string literal (double quotes) to simplify the syntax. With an interpreted string literal you must escape backslashes.

This function uses the RE2 regular expression library. See the RE2 syntax documentation for details. Note that the RE2 \C escape sequence is not supported.

The RE2 syntax is a subset of that accepted by PCRE, roughly speaking, and with various caveats.

Demonstrative examples

1
2
3
4
5
{{ findRESubmatch `a(x*)b` "-ab-" }} → [["ab" ""]]
{{ findRESubmatch `a(x*)b` "-axxb-" }} → [["axxb" "xx"]]
{{ findRESubmatch `a(x*)b` "-ab-axb-" }} → [["ab" ""] ["axb" "x"]]
{{ findRESubmatch `a(x*)b` "-axxb-ab-" }} → [["axxb" "xx"] ["ab" ""]]
{{ findRESubmatch `a(x*)b` "-axxb-ab-" 1 }} → [["axxb" "xx"]]

Practical example

This markdown:

1
2
- [Example](https://example.org)
- [Hugo](https://gohugo.io)

Produces this HTML:

1
2
3
4
<ul>
  <li><a href="https://example.org">Example</a></li>
  <li><a href="https://gohugo.io">Hugo</a></li>
</ul>

To match the anchor elements, capturing the link destination and text:

1
2
{{ $regex := `<a\s*href="(.+?)">(.+?)</a>` }}
{{ $matches := findRESubmatch $regex .Content }}

Viewed as JSON, the data structure of $matches in the code above is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[
  [
    "<a href=\"https://example.org\"></a>Example</a>",
    "https://example.org",
    "Example"
  ],
  [
    "<a href=\"https://gohugo.io\">Hugo</a>",
    "https://gohugo.io",
    "Hugo"
  ]
]

To render the href attributes:

1
2
3
{{ range $matches }}
  {{ index . 1 }}
{{ end }}

Result:

1
2
https://example.org
https://gohugo.io

You can write and test your regular expression using regex101.com. Be sure to select the Go flavor before you begin.

另请参阅

7.38 - first

将以下英文翻译为中文:

first

https://gohugo.io/functions/first/

Slices an array to only the first N elements.

语法

first LIMIT COLLECTION

first works in a similar manner to the limit keyword in SQL. It reduces the array to only the first N elements. It takes the array and number of elements as input.

first takes two arguments:

  1. number of elements
  2. array or slice of maps or structs

layout/_default/section.html

1
2
3
{{ range first 10 .Pages }}
    {{ .Render "summary" }}
{{ end }}

Note: Exclusive to first, LIMIT can be ‘0’ to return an empty array.

first and where Together

Using first and where together can be very powerful. Below snippet gets a list of posts only from main sections, sorts it by the title parameter, and then ranges through only the first 5 posts in that list:

first-and-where-together.html

1
2
3
{{ range first 5 (where site.RegularPages "Type" "in" site.Params.mainSections).ByTitle }}
   {{ .Content }}
{{ end }}

另请参阅

7.39 - float

将以下英文翻译为中文:

float

https://gohugo.io/functions/float/

Casts a value to a decimal (base 10) floating point value.

语法

float INPUT

With a decimal (base 10) input:

1
2
3
4
5
6
7
8
{{ float 11 }} → 11 (float64)
{{ float "11" }} → 11 (float64)

{{ float 11.1 }} → 11.1 (float64)
{{ float "11.1" }} → 11.1 (float64)

{{ float 11.9 }} → 11.9 (float64)
{{ float "11.9" }} → 11.9 (float64)

With a binary (base 2) input:

1
{{ float 0b11 }} → 3 (float64)

With an octal (base 8) input (use either notation):

1
2
3
4
{{ float 011 }} → 9 (float64)
{{ float "011" }} → 11 (float64)

{{ float 0o11 }} → 9 (float64)

With a hexadecimal (base 16) input:

1
{{ float 0x11 }} → 17 (float64)

另请参阅

7.40 - ge

将以下英文翻译为中文:

ge

https://gohugo.io/functions/ge/

Returns the boolean truth of arg1 >= arg2.

语法

ge ARG1 ARG2
{{ if ge 10 5 }}true{{ end }}

另请参阅

7.41 - getenv

将以下英文翻译为中文:

getenv

https://gohugo.io/functions/getenv/

Returns the value of an environment variable, or an empty string if the environment variable is not set.

语法

os.Getenv VARIABLE
getenv VARIABLE

Examples:

1
2
{{ os.Getenv "HOME" }} --> /home/victor
{{ os.Getenv "USER" }} --> victor

You can pass values when building your site:

1
2
3
4
5
6
7
MY_VAR1=foo MY_VAR2=bar hugo

OR

export MY_VAR1=foo
export MY_VAR2=bar
hugo

And then retrieve the values within a template:

1
2
{{ os.Getenv "MY_VAR1" }} --> foo
{{ os.Getenv "MY_VAR2" }} --> bar

With Hugo v0.91.0 and later, you must explicitly allow access to environment variables. For details, review Hugo’s Security Policy. By default, environment variables beginning with HUGO_ are allowed when using the os.Getenv function.

7.42 - group

将以下英文翻译为中文:

group

https://gohugo.io/functions/group/

group groups a list of pages.

语法

PAGES | group KEY

layouts/partials/groups.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{{ $new := .Site.RegularPages | first 10 | group "New" }}
{{ $old := .Site.RegularPages | last 10 | group "Old" }}
{{ $groups := slice $new $old }}
{{ range $groups }}
<h3>{{ .Key }}{{/* Prints "New", "Old" */}}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

The page group you get from group is of the same type you get from the built-in group methods in Hugo. The above example can even be paginated.

另请参阅

7.43 - gt

将以下英文翻译为中文:

gt

https://gohugo.io/functions/gt/

Returns the boolean truth of arg1 > arg2.

语法

gt ARG1 ARG2
{{ if gt 10 5 }}true{{ end }}

另请参阅

7.44 - highlight

将以下英文翻译为中文:

highlight

https://gohugo.io/functions/highlight/

Renders code with a syntax highlighter.

语法

transform.Highlight INPUT LANG [OPTIONS]
highlight INPUT LANG [OPTIONS]

The highlight function uses the Chroma syntax highlighter, supporting over 200 languages with more than 40 available styles.

Parameters

  • INPUT

    The code to highlight.

  • LANG

    The language of the code to highlight. Choose from one of the supported languages. Case-insensitive.

  • OPTIONS

    An optional, comma-separated list of zero or more options. Set default values in site configuration.

Options

  • lineNos

    Boolean. Default is false. Display a number at the beginning of each line.

  • lineNumbersInTable

    Boolean. Default is true. Render the highlighted code in an HTML table with two cells. The left table cell contains the line numbers. The right table cell contains the code, allowing a user to select and copy the code without line numbers. Irrelevant if lineNos is false.

  • anchorLineNos

    Boolean. Default is false. Render each line number as an HTML anchor element, and set the id attribute of the surrounding <span> to the line number. Irrelevant if lineNos is false.

  • lineAnchors

    String. Default is "". When rendering a line number as an HTML anchor element, prepend this value to the id attribute of the surrounding <span>. This provides unique id attributes when a page contains two or more code blocks. Irrelevant if lineNos or anchorLineNos is false.

  • lineNoStart

    Integer. Default is 1. The number to display at the beginning of the first line. Irrelevant if lineNos is false.

  • hl_Lines

    String. Default is "". A space-separated list of lines to emphasize within the highlighted code. To emphasize lines 2, 3, 4, and 7, set this value to 2-4 7. This option is independent of the lineNoStart option.

  • hl_inline

    Boolean. Default is false. Render the highlighted code without a wrapping container.

  • style

    String. Default is monokai. The CSS styles to apply to the highlighted code. See the style gallery for examples. Case-sensitive.

  • noClasses

    Boolean. Default is true. Use inline CSS styles instead of an external CSS file. To use an external CSS file, set this value to false and generate the file with the hugo client.

  • tabWidth

    Integer. Default is 4. Substitute this number of spaces for each tab character in your highlighted code. Irrelevant if noClasses is false.

  • guessSyntax

    Boolean. Default is false. If the LANG parameter is blank or an unrecognized language, auto-detect the language if possible, otherwise use a fallback language.

Instead of specifying both lineNos and lineNumbersInTable, you can use the following shorthand notation:

  • lineNos=inline

    equivalent to lineNos=true and lineNumbersInTable=false

  • lineNos=table

    equivalent to lineNos=true and lineNumbersInTable=true

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{{ $input := `fmt.Println("Hello World!")` }}
{{ transform.Highlight $input "go" }}

{{ $input := `console.log('Hello World!');` }}
{{ $lang := "js" }}
{{ transform.Highlight $input $lang "lineNos=table, style=api" }}

{{ $input := `echo "Hello World!"` }}
{{ $lang := "bash" }}
{{ $options := slice "lineNos=table" "style=dracula" }}
{{ transform.Highlight $input $lang (delimit $options ",") }}

另请参阅

7.45 - hmac

将以下英文翻译为中文:

hmac

https://gohugo.io/functions/hmac/

Returns a cryptographic hash that uses a key to sign a message.

语法

crypto.HMAC HASH_TYPE KEY MESSAGE [ENCODING]
hmac HASH_TYPE KEY MESSAGE [ENCODING]

Set the HASH_TYPE argument to md5, sha1, sha256, or sha512.

Set the optional ENCODING argument to either hex (default) or binary.

1
2
3
4
5
6
7
8
{{ hmac "sha256" "Secret key" "Secret message" }}
5cceb491f45f8b154e20f3b0a30ed3a6ff3027d373f85c78ffe8983180b03c84

{{ hmac "sha256" "Secret key" "Secret message" "hex" }}
5cceb491f45f8b154e20f3b0a30ed3a6ff3027d373f85c78ffe8983180b03c84

{{ hmac "sha256" "Secret key" "Secret message" "binary" | base64Encode }}
XM60kfRfixVOIPOwow7Tpv8wJ9Nz+Fx4/+iYMYCwPIQ=

另请参阅

7.46 - htmlEscape

将以下英文翻译为中文:

htmlEscape

https://gohugo.io/functions/htmlescape/

Returns the given string with the reserved HTML codes escaped.

语法

htmlEscape INPUT

In the result & becomes & and so on. It escapes only: <, >, &, ' and ".

1
{{ htmlEscape "Hugo & Caddy > WordPress & Apache" }} → "Hugo &amp; Caddy &gt; WordPress &amp; Apache"

另请参阅

7.47 - htmlUnescape

将以下英文翻译为中文:

htmlUnescape

https://gohugo.io/functions/htmlunescape/

Returns the given string with HTML escape codes un-escaped.

语法

htmlUnescape INPUT

htmlUnescape returns the given string with HTML escape codes un-escaped.

Remember to pass the output of this to safeHTML if fully un-escaped characters are desired. Otherwise, the output will be escaped again as normal.

1
{{ htmlUnescape "Hugo &amp; Caddy &gt; WordPress &amp; Apache" }} → "Hugo & Caddy > WordPress & Apache"

7.48 - hugo

将以下英文翻译为中文:

hugo

https://gohugo.io/functions/hugo/

The hugo function provides easy access to Hugo-related data.

语法

hugo

hugo returns an instance that contains the following functions:

  • hugo.Generator

    <meta> tag for the version of Hugo that generated the site. hugo.Generator outputs a complete HTML tag; e.g. <meta name="generator" content="Hugo 0.63.2">

  • hugo.Version

    the current version of the Hugo binary you are using e.g. 0.99.1

  • hugo.GoVersion

    returns the version of Go that the Hugo binary was built with. New in v0.101.0

  • hugo.Environment

    the current running environment as defined through the --environment cli tag

  • hugo.CommitHash

    the git commit hash of the current Hugo binary e.g. 0e8bed9ccffba0df554728b46c5bbf6d78ae5247

  • hugo.BuildDate

    the compile date of the current Hugo binary formatted with RFC 3339 e.g. 2002-10-02T10:00:00-05:00

  • hugo.IsExtended

    whether this is the extended Hugo binary.

  • hugo.IsProduction

    returns true if hugo.Environment is set to the production environment

  • hugo.Deps

    See hugo.Deps

hugo.Deps

New in v0.92.0

hugo.Deps returns a list of dependencies for a project (either Hugo Modules or local theme components).

Each dependency contains:

  • Path (string)

    Returns the path to this module. This will either be the module path, e.g. “github.com/gohugoio/myshortcodes”, or the path below your /theme folder, e.g. “mytheme”.

  • Version (string)

    The module version.

  • Vendor (bool)

    Whether this dependency is vendored.

  • Time (time.Time)

    Time version was created.

  • Owner

    In the dependency tree, this is the first module that defines this module as a dependency.

  • Replace (*Dependency)

    Replaced by this dependency.

An example table listing the dependencies:

 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
 <h2>Dependencies</h2>
<table class="table table-dark">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">Owner</th>
      <th scope="col">Path</th>
      <th scope="col">Version</th>
      <th scope="col">Time</th>
      <th scope="col">Vendor</th>
    </tr>
  </thead>
  <tbody>
    {{ range $index, $element := hugo.Deps }}
    <tr>
      <th scope="row">{{ add $index 1 }}</th>
      <td>{{ with $element.Owner }}{{ .Path }}{{ end }}</td>
      <td>
        {{ $element.Path }}
        {{ with $element.Replace }}
        => {{ .Path }}
        {{ end }}
      </td>
      <td>{{ $element.Version }}</td>
      <td>{{ with $element.Time }}{{ . }}{{ end }}</td>
      <td>{{ $element.Vendor }}</td>
    </tr>
    {{ end }}
  </tbody>
</table>

7.49 - humanize

将以下英文翻译为中文:

humanize

https://gohugo.io/functions/humanize/

Returns the humanized version of an argument with the first letter capitalized.

语法

humanize INPUT

If the input is either an int64 value or the string representation of an integer, humanize returns the number with the proper ordinal appended.

1
2
3
4
{{ humanize "my-first-post" }} → "My first post"
{{ humanize "myCamelPost" }} → "My camel post"
{{ humanize "52" }} → "52nd"
{{ humanize 103 }} → "103rd"

另请参阅

7.50 - i18n

将以下英文翻译为中文:

i18n

https://gohugo.io/functions/i18n/

Translates a piece of content based on your i18n configuration files.

语法

i18n KEY
T KEY
lang.Translate KEY

This translates a piece of content based on your i18n/en-US.toml files. You can use the go-i18n tools to manage your translations. The translations can exist in both the theme and at the root of your repository.

1
{{ i18n "translation_id" }}

T is an alias to i18n. E.g. {{ T "translation_id" }}.

Query a flexible translation with variables

Often you will want to use the page variables in the translation strings. To do so, pass the . context when calling i18n:

1
{{ i18n "wordCount" . }}

The function will pass the . context to the "wordCount" id:

i18n/en-US.

=== “yaml”

``` yaml
wordCount:
  other: This article has {{ .WordCount }} words.
```

=== “toml”

``` toml
[wordCount]
  other = 'This article has {{ .WordCount }} words.'
```

=== “json”

``` json
{
   "wordCount": {
      "other": "This article has {{ .WordCount }} words."
   }
}
```

Assume .WordCount in the context has value is 101. The result will be:

This article has 101 words.

For more information about string translations, see Translation of Strings in Multilingual Mode.

另请参阅

7.51 - index

将以下英文翻译为中文:

index

https://gohugo.io/functions/index-function/

Looks up the index(es) or key(s) of the data structure passed into it.

语法

index COLLECTION INDEXES
index COLLECTION KEYS

The index functions returns the result of indexing its first argument by the following arguments. Each indexed item must be a map or a slice, e.g.:

1
2
3
4
{{ $slice := slice "a" "b" "c" }}
{{ index $slice 1 }} => b
{{ $map := dict "a" 100 "b" 200 }}
{{ index $map "b" }} => 200

The function takes multiple indices as arguments, and this can be used to get nested values, e.g.:

1
2
3
4
{{ $map := dict "a" 100 "b" 200 "c" (slice 10 20 30) }}
{{ index $map "c" 1 }} => 20
{{ $map := dict "a" 100 "b" 200 "c" (dict "d" 10 "e" 20) }}
{{ index $map "c" "e" }} => 20

You may write multiple indices as a slice:

1
2
3
{{ $map := dict "a" 100 "b" 200 "c" (dict "d" 10 "e" 20) }}
{{ $slice := slice "c" "e" }}
{{ index $map $slice }} => 20

Example: Load Data from a Path Based on Front Matter Params

Assume you want to add a location = "" field to your front matter for every article written in content/vacations/. You want to use this field to populate information about the location at the bottom of the article in your single.html template. You also have a directory in data/locations/ that looks like the following:

.
└── data
    └── locations
        ├── abilene.toml
        ├── chicago.toml
        ├── oslo.toml
        └── provo.toml

Here is an example:

data/locations/oslo.

=== “yaml”

``` yaml
pop_city: 658390
pop_metro: 1717900
website: https://www.oslo.kommune.no
```

=== “toml”

``` toml
pop_city = 658390
pop_metro = 1717900
website = 'https://www.oslo.kommune.no'
```

=== “json”

``` json
{
   "pop_city": 658390,
   "pop_metro": 1717900,
   "website": "https://www.oslo.kommune.no"
}
```

The example we will use will be an article on Oslo, whose front matter should be set to exactly the same name as the corresponding file name in data/locations/:

content/articles/oslo.md

=== “yaml”

``` yaml
---
location: oslo
title: My Norwegian Vacation
---
```

=== “toml”

``` toml
+++
location = 'oslo'
title = 'My Norwegian Vacation'
+++
```

=== “json”

``` json
{
   "location": "oslo",
   "title": "My Norwegian Vacation"
}
```

The content of oslo.toml can be accessed from your template using the following node path: .Site.Data.locations.oslo. However, the specific file you need is going to change according to the front matter.

This is where the index function is needed. index takes 2 parameters in this use case:

  1. The node path
  2. A string corresponding to the desired data; e.g.—
1
{{ index .Site.Data.locations "oslo" }}

The variable for .Params.location is a string and can therefore replace oslo in the example above:

1
2
{{ index .Site.Data.locations .Params.location }}
=> map[website:https://www.oslo.kommune.no pop_city:658390 pop_metro:1717900]

Now the call will return the specific file according to the location specified in the content’s front matter, but you will likely want to write specific properties to the template. You can do this by continuing down the node path via dot notation (.):

1
2
{{ (index .Site.Data.locations .Params.location).pop_city }}
=> 658390

7.52 - Image Filters

将以下英文翻译为中文:

Image Filters

https://gohugo.io/functions/images/

The images namespace provides a list of filters and other image related functions.

See images.Filter for how to apply these filters to an image.

Overlay

Overlay creates a filter that overlays the source image at position x y, e.g:

1
2
{{ $logoFilter := (images.Overlay $logo 50 50 ) }}
{{ $img := $img | images.Filter $logoFilter }}

A shorter version of the above, if you only need to apply the filter once:

1
{{ $img := $img.Filter (images.Overlay $logo 50 50 )}}

The above will overlay $logo in the upper left corner of $img (at position x=50, y=50).

Text

Using the Text filter, you can add text to an image.

The following example will add the text Hugo rocks! to the image with the specified color, size and position.

1
2
3
4
5
6
7
8
{{ $img := resources.Get "/images/background.png" }}
{{ $img = $img.Filter (images.Text "Hugo rocks!" (dict
    "color" "#ffffff"
    "size" 60
    "linespacing" 2
    "x" 10
    "y" 20
))}}

You can load a custom font if needed. Load the font as a Hugo Resource and set it as an option:

1
2
3
4
5
{{ $font := resources.GetRemote "https://github.com/google/fonts/raw/main/apache/roboto/static/Roboto-Black.ttf" }}
{{ $img := resources.Get "/images/background.png" }}
{{ $img = $img.Filter (images.Text "Hugo rocks!" (dict
    "font" $font
))}}

Brightness

Brightness creates a filter that changes the brightness of an image. The percentage parameter must be in range (-100, 100).

ColorBalance

ColorBalance creates a filter that changes the color balance of an image. The percentage parameters for each color channel (red, green, blue) must be in range (-100, 500).

Colorize

Colorize creates a filter that produces a colorized version of an image. The hue parameter is the angle on the color wheel, typically in range (0, 360). The saturation parameter must be in range (0, 100). The percentage parameter specifies the strength of the effect, it must be in range (0, 100).

Contrast

Contrast creates a filter that changes the contrast of an image. The percentage parameter must be in range (-100, 100).

Gamma

Gamma creates a filter that performs a gamma correction on an image. The gamma parameter must be positive. Gamma = 1 gives the original image. Gamma less than 1 darkens the image and gamma greater than 1 lightens it.

GaussianBlur

GaussianBlur creates a filter that applies a gaussian blur to an image.

Grayscale

Grayscale creates a filter that produces a grayscale version of an image.

Hue

Hue creates a filter that rotates the hue of an image. The hue angle shift is typically in range -180 to 180.

Invert

Invert creates a filter that negates the colors of an image.

Pixelate

Pixelate creates a filter that applies a pixelation effect to an image.

Saturation

Saturation creates a filter that changes the saturation of an image.

Sepia

Sepia creates a filter that produces a sepia-toned version of an image.

Sigmoid

Sigmoid creates a filter that changes the contrast of an image using a sigmoidal function and returns the adjusted image. It’s a non-linear contrast change useful for photo adjustments as it preserves highlight and shadow detail.

UnsharpMask

UnsharpMask creates a filter that sharpens an image. The sigma parameter is used in a gaussian function and affects the radius of effect. Sigma must be positive. Sharpen radius roughly equals 3 * sigma. The amount parameter controls how much darker and how much lighter the edge borders become. Typically between 0.5 and 1.5. The threshold parameter controls the minimum brightness change that will be sharpened. Typically between 0 and 0.05.

Other Functions

Filter

Can be used to apply a set of filters to an image:

1
{{ $img := $img | images.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}

Also see the Filter Method.

ImageConfig

Parses the image and returns the height, width, and color model.

The imageConfig function takes a single parameter, a file path (string) relative to the project’s root directory, with or without a leading slash.

1
2
3
{{ with (imageConfig "favicon.ico") }}
favicon.ico: {{ .Width }} x {{ .Height }}
{{ end }}

另请参阅

7.53 - in

将以下英文翻译为中文:

in

https://gohugo.io/functions/in/

Checks if an element is in an array or slice–or a substring in a string—and returns a boolean.

语法

in SET ITEM

The elements supported are strings, integers and floats, although only float64 will match as expected.

In addition, in can also check if a substring exists in a string.

1
2
{{ if in .Params.tags "Git" }}Follow me on GitHub!{{ end }}
{{ if in "this string contains a substring" "substring" }}Substring found!{{ end }}

另请参阅

7.54 - int

将以下英文翻译为中文:

int

https://gohugo.io/functions/int/

Casts a value to a decimal (base 10) integer.

语法

int INPUT

With a decimal (base 10) input:

1
2
3
4
5
{{ int 11 }} → 11 (int)
{{ int "11" }} → 11 (int)

{{ int 11.1 }} → 11 (int)
{{ int 11.9 }} → 11 (int)

With a binary (base 2) input:

1
2
{{ int 0b11 }} → 3 (int)
{{ int "0b11" }} → 3 (int)

With an octal (base 8) input (use either notation):

1
2
3
4
5
{{ int 011 }} → 9 (int)
{{ int "011" }} → 9 (int)

{{ int 0o11 }} → 9 (int)
{{ int "0o11" }} → 9 (int)

With a hexadecimal (base 16) input:

1
2
{{ int 0x11 }} → 17 (int)
{{ int "0x11" }} → 17 (int)

Values with a leading zero are octal (base 8). When casting a string representation of a decimal (base 10) number, remove leading zeros:

{{ strings.TrimLeft "0" "0011" | int }} → 11

另请参阅

7.55 - intersect

将以下英文翻译为中文:

intersect

https://gohugo.io/functions/intersect/

Returns the common elements of two arrays or slices, in the same order as the first array.

语法

intersect SET1 SET2

A useful example is to use it as AND filters when combined with where:

AND filter in where query

1
2
3
{{ $pages := where .Site.RegularPages "Type" "not in" (slice "page" "about") }}
{{ $pages := $pages | union (where .Site.RegularPages "Params.pinned" true) }}
{{ $pages := $pages | intersect (where .Site.RegularPages "Params.images" "!=" nil) }}

The above fetches regular pages not of page or about type unless they are pinned. And finally, we exclude all pages with no images set in Page params.

See union for OR.

另请参阅

7.56 - isset

将以下英文翻译为中文:

isset

https://gohugo.io/functions/isset/

Returns true if the parameter is set.

语法

isset COLLECTION INDEX
isset COLLECTION KEY

Takes either a slice, array, or channel and an index or a map and a key as input.

1
{{ if isset .Params "project_url" }} {{ index .Params "project_url" }}{{ end }}

All site-level configuration keys are stored as lower case. Therefore, a myParam key-value set in your site configuration file needs to be accessed with {{ if isset .Site.Params "myparam" }} and not with {{ if isset .Site.Params "myParam" }}. Note that you can still access the same config key with .Site.Params.myParam or .Site.Params.myparam, for example, when using with. This restriction also applies when accessing page-level front matter keys from within shortcodes.

7.57 - jsonify

将以下英文翻译为中文:

jsonify

https://gohugo.io/functions/jsonify/

Encodes a given object to JSON.

语法

jsonify INPUT
jsonify OPTIONS INPUT

Jsonify encodes a given object to JSON.

To customize the printing of the JSON, pass a dictionary of options as the first argument. Supported options are “prefix” and “indent”. Each JSON element in the output will begin on a new line beginning with prefix followed by one or more copies of indent according to the indentation nesting.

1
2
3
{{ dict "title" .Title "content" .Plain | jsonify }}
{{ dict "title" .Title "content" .Plain | jsonify (dict "indent" "  ") }}
{{ dict "title" .Title "content" .Plain | jsonify (dict "prefix" " " "indent" "  ") }}

Jsonify options

  • indent ("")

    Indentation to use.

  • prefix ("")

    Indentation prefix.

  • noHTMLEscape (false)

    Disable escaping of problematic HTML characters inside JSON quoted strings. The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e to avoid certain safety problems that can arise when embedding JSON in HTML.

See also the .PlainWords, .Plain, and .RawContent page variables.

另请参阅

7.58 - lang

将以下英文翻译为中文:

lang.FormatAccounting

https://gohugo.io/functions/lang/

FormatAccounting returns the currency representation of number for the given currency and precision for the current language in accounting notation.

The return value is formatted with at least two decimal places.

语法

lang.FormatAccounting PRECISION, CURRENCY, NUMBER

Examples

1
{{ 512.5032 | lang.FormatAccounting 2 "NOK" }} ---> NOK512.50

lang.FormatCurrency

FormatCurrency returns the currency representation of number for the given currency and precision for the current language.

The return value is formatted with at least two decimal places.

语法

lang.FormatCurrency PRECISION, CURRENCY, NUMBER

Examples

1
{{ 512.5032 | lang.FormatCurrency 2 "USD" }} ---> $512.50

lang.FormatNumber

FormatNumber formats number with the given precision for the current language.

语法

lang.FormatNumber PRECISION, NUMBER

Examples

1
{{ 512.5032 | lang.FormatNumber 2 }} ---> 512.50

lang.FormatNumberCustom

FormatNumberCustom formats a number with the given precision using the negative, decimal, and grouping options. The options parameter is a string consisting of <negative> <decimal> <grouping>. The default options value is - . ,.

Note that numbers are rounded up at 5 or greater. So, with precision set to 0, 1.5 becomes 2, and 1.4 becomes 1.

For a simpler function that adapts to the current language, see FormatNumber.

语法

lang.FormatNumberCustom PRECISION, NUMBER, OPTIONS

Examples

1
2
3
4
5
{{ lang.FormatNumberCustom 2 12345.6789 }} ---> 12,345.68
{{ lang.FormatNumberCustom 2 12345.6789 "- , ." }} ---> 12.345,68
{{ lang.FormatNumberCustom 6 -12345.6789 "- ." }} ---> -12345.678900
{{ lang.FormatNumberCustom 0 -12345.6789 "- . ," }} ---> -12,346
{{ -98765.4321 | lang.FormatNumberCustom 2 }} ---> -98,765.43

lang.FormatPercent

FormatPercent formats number with the given precision for the current language. Note that the number is assumed to be a percentage.

语法

lang.FormatPercent PRECISION, NUMBER

Examples

1
{{ 512.5032 | lang.FormatPercent 2 }} ---> 512.50%

lang.Translate

Translate returns a translated string for id.

语法

lang.Translate ID, ARGS

Aliases

i18n, T

7.59 - lang.Merge

将以下英文翻译为中文:

lang.Merge

https://gohugo.io/functions/lang.merge/

Merge missing translations from other languages.

语法

lang.Merge FROM TO

As an example:

1
{{ $pages := .Site.RegularPages | lang.Merge $frSite.RegularPages | lang.Merge $enSite.RegularPages }}

Will “fill in the gaps” in the current site with, from left to right, content from the French site, and lastly the English.

A more practical example is to fill in the missing translations from the other languages:

1
2
3
4
{{ $pages := .Site.RegularPages }}
{{ range .Site.Home.Translations }}
{{ $pages = $pages | lang.Merge .Site.RegularPages }}
{{ end }}

另请参阅

7.60 - last

将以下英文翻译为中文:

last

https://gohugo.io/functions/last/

slices an array to only the last Nth elements.

语法

last INDEX COLLECTION
{{ range last 10 .Pages }}
  {{ .Render "summary" }}
{{ end }}

7.61 - le

将以下英文翻译为中文:

le

https://gohugo.io/functions/le/

Returns the boolean truth of arg1 <= arg2.

语法

le ARG1 ARG2
{{ if le 5 10 }}true{{ end }}

另请参阅

7.62 - len

将以下英文翻译为中文:

len

https://gohugo.io/functions/len/

Returns the length of a string, slice, map, or collection.

语法

len INPUT

With a string:

1
2
{{ "ab" | len }} → 2
{{ "" | len }} → 0

With a slice:

1
2
{{ slice "a" "b" | len }} → 2
{{ slice | len }} → 0

With a map:

1
2
{{ dict "a" 1 "b" 2  | len }} → 2
{{ dict | len }} → 0

With a collection:

1
{{ site.RegularPages | len }} → 42

You may also determine the number of pages in a collection with:

1
{{ site.RegularPages.Len }} → 42

另请参阅

7.63 - lower

将以下英文翻译为中文:

lower

https://gohugo.io/functions/lower/

Converts all characters in the provided string to lowercase.

语法

lower INPUT
strings.ToLower INPUT

Note that lower can be applied in your templates in more than one way:

1
2
{{ lower "BatMan" }} → "batman"
{{ "BatMan" | lower }} → "batman"

另请参阅

7.64 - lt

将以下英文翻译为中文:

lt

https://gohugo.io/functions/lt/

Returns the boolean truth of arg1 < arg2.

语法

lt ARG1 ARG2
{{ if lt 5 10 }}true{{ end }}

另请参阅

7.65 - markdownify

将以下英文翻译为中文:

markdownify

https://gohugo.io/functions/markdownify/

Renders markdown to HTML.

语法

markdownify INPUT
{{ .Title | markdownify }}

If the resulting HTML is a single paragraph, Hugo removes the wrapping p tags to produce inline HTML as required per the example above.

To keep the wrapping p tags for a single paragraph, use the .Page.RenderString method, setting the display option to block.

If the resulting HTML is two or more paragraphs, Hugo leaves the wrapping p tags in place.

Although the markdownify function honors markdown render hooks when rendering markdown to HTML, use the .Page.RenderString method instead of markdownify if a render hook accesses .Page context. See issue #9692 for details.

另请参阅

7.66 - Math

将以下英文翻译为中文:

Math

https://gohugo.io/functions/math/

Hugo provides mathematical operators in templates.

FunctionDescriptionExample
addAdds two or more numbers.{{ add 12 3 2 }}17
If one of the numbers is a float, the result is a float.{{ add 1.1 2 }}3.1
subSubtracts one or more numbers from the first number.{{ sub 12 3 2 }}7
If one of the numbers is a float, the result is a float.{{ sub 3 2.5 }}0.5
mulMultiplies two or more numbers.{{ mul 12 3 2 }}72
If one of the numbers is a float, the result is a float.{{ mul 2 3.1 }}6.2
divDivides the first number by one or more numbers.{{ div 12 3 2 }}2
If one of the numbers is a float, the result is a float.{{ div 6 4.0 }}1.5
modModulus of two integers.{{ mod 15 3 }}0
modBoolBoolean of modulus of two integers. Evaluates to true if result equals 0.{{ modBool 15 3 }}true
math.CeilReturns the least integer value greater than or equal to the given number.{{ math.Ceil 2.1 }}3
math.FloorReturns the greatest integer value less than or equal to the given number.{{ math.Floor 1.9 }}1
math.LogReturns the natural logarithm of the given number.{{ math.Log 42 }}3.737
math.MaxReturns the greater of two or more numbers.{{ math.Max 12 3 2 }}12
math.MinReturns the smaller of two or more numbers.{{ math.Min 12 3 2 }}2
math.PowReturns the first number raised to the power of the second number.{{ math.Pow 2 3 }}8
math.RoundReturns the nearest integer, rounding half away from zero.{{ math.Round 1.5 }}2
math.SqrtReturns the square root of the given number.{{ math.Sqrt 81 }}9

另请参阅

7.67 - md5

将以下英文翻译为中文:

md5

https://gohugo.io/functions/md5/

hashes the given input and returns its MD5 checksum.

语法

md5 INPUT
{{ md5 "Hello world, gophers!" }}
<!-- returns the string "b3029f756f98f79e7f1b7f1d1f0dd53b" -->

This can be useful if you want to use Gravatar for generating a unique avatar:

1
<img src="https://www.gravatar.com/avatar/{{ md5 "your@email.com" }}?s=100&d=identicon">

7.68 - merge

将以下英文翻译为中文:

merge

https://gohugo.io/functions/merge/

Returns the result of merging two or more maps.

语法

collections.Merge MAP MAP...
merge MAP MAP...

Returns the result of merging two or more maps from left to right. If a key already exists, merge updates its value. If a key is absent, merge inserts the value under the new key.

Key handling is case-insensitive.

The following examples use these map definitions:

1
2
3
{{ $m1 := dict "x" "foo" }}
{{ $m2 := dict "x" "bar" "y" "wibble" }}
{{ $m3 := dict "x" "baz" "y" "wobble" "z" (dict "a" "huey") }}

Example 1

1
2
3
4
5
{{ $merged := merge $m1 $m2 $m3 }}

{{ $merged.x }}   --> baz
{{ $merged.y }}   --> wobble
{{ $merged.z.a }} --> huey

Example 2

1
2
3
4
5
{{ $merged := merge $m3 $m2 $m1 }}

{{ $merged.x }}   --> foo
{{ $merged.y }}   --> wibble
{{ $merged.z.a }} --> huey

Example 3

1
2
3
4
5
{{ $merged := merge $m2 $m3 $m1 }}

{{ $merged.x }}   --> foo
{{ $merged.y }}   --> wobble
{{ $merged.z.a }} --> huey

Example 4

1
2
3
4
5
{{ $merged := merge $m1 $m3 $m2 }}

{{ $merged.x }}   --> bar
{{ $merged.y }}   --> wibble
{{ $merged.z.a }} --> huey

Regardless of depth, merging only applies to maps. For slices, use append.

另请参阅

7.69 - ne

将以下英文翻译为中文:

ne

https://gohugo.io/functions/ne/

Returns the boolean truth of arg1 != arg2.

语法

ne ARG1 ARG2
{{ if ne .Section "blog" }}current{{ end }}

另请参阅

7.70 - now

将以下英文翻译为中文:

now

https://gohugo.io/functions/now/

Returns the current local time

语法

now

See time.Time.

For example, building your site on June 24, 2017, with the following templating:

1
2
3
<div>
    <small>&copy; {{ now.Format "2006" }}</small>
</div>

would produce the following:

1
2
3
<div>
    <small>&copy; 2017</small>
</div>

The above example uses the .Format function, which page includes a full listing of date formatting using Go’s layout string.

Older Hugo themes may still be using the obsolete Page’s .Now (uppercase with leading dot), which causes build error that looks like the following:

ERROR ... Error while rendering "..." in "...": ...
executing "..." at <.Now.Format>:
can't evaluate field Now in type *hugolib.PageOutput

Be sure to use now (lowercase with no leading dot) in your templating.

另请参阅

7.71 - os.Stat

将以下英文翻译为中文:

os.Stat

https://gohugo.io/functions/os.stat/

Returns a FileInfo structure describing a file or directory.

语法

os.Stat PATH

The os.Stat function attempts to resolve the path relative to the root of your project directory. If a matching file or directory is not found, it will attempt to resolve the path relative to the contentDir. A leading path separator (/) is optional.

1
2
3
4
5
6
7
8
{{ $f := os.Stat "README.md" }}
{{ $f.IsDir }}    --> false (bool)
{{ $f.ModTime }}  --> 2021-11-25 10:06:49.315429236 -0800 PST (time.Time)
{{ $f.Name }}     --> README.md (string)
{{ $f.Size }}     --> 241 (int64)

{{ $d := os.Stat "content" }}
{{ $d.IsDir }}    --> true (bool)

Details of the FileInfo structure are available in the Go documentation.

另请参阅

7.72 - partialCached

将以下英文翻译为中文:

partialCached

https://gohugo.io/functions/partialcached/

Allows for caching of partials that do not need to be re-rendered on every invocation.

语法

partialCached LAYOUT INPUT [VARIANT...]

The partialCached template function can offer significant performance gains for complex templates that don’t need to be re-rendered on every invocation.

Note: Each Site (or language) has its own partialCached cache, so each site will execute a partial once.

Note: Hugo renders pages in parallel, and will render the partial more than once with concurrent calls to the partialCached function. After Hugo caches the rendered partial, new pages entering the build pipeline will use the cached result.

Here is the simplest usage:

1
{{ partialCached "footer.html" . }}

You can also pass additional parameters to partialCached to create variants of the cached partial. For example, if you have a complex partial that should be identical when rendered for pages within the same section, you could use a variant based upon section so that the partial is only rendered once per section:

partial-cached-example.html

1
{{ partialCached "footer.html" . .Section }}

If you need to pass additional parameters to create unique variants, you can pass as many variant parameters as you need:

1
{{ partialCached "footer.html" . .Params.country .Params.province }}

Note that the variant parameters are not made available to the underlying partial template. They are only use to create a unique cache key. Since Hugo 0.61.0 you can use any object as cache key(s), not just strings.

See also The Full Partial Series Part 1: Caching!.

另请参阅

7.73 - path.Base

将以下英文翻译为中文:

path.Base

https://gohugo.io/functions/path.base/

Base returns the last element of a path.

语法

path.Base PATH

path.Base returns the last element of PATH.

If PATH is empty, . is returned.

Note: On Windows, PATH is converted to slash (/) separators.

1
2
3
4
{{ path.Base "a/news.html" }} → "news.html"
{{ path.Base "news.html" }} → "news.html"
{{ path.Base "a/b/c" }} → "c"
{{ path.Base "/x/y/z/" }} → "z"

另请参阅

7.74 - path.BaseName

将以下英文翻译为中文:

path.BaseName

https://gohugo.io/functions/path.basename/

BaseName returns the last element of a path, removing the extension if present.

语法

path.BaseName PATH

If PATH is empty, . is returned.

Note: On Windows, PATH is converted to slash (/) separators.

1
2
3
4
{{ path.BaseName "a/news.html" }} → "news"
{{ path.BaseName "news.html" }} → "news"
{{ path.BaseName "a/b/c" }} → "c"
{{ path.BaseName "/x/y/z/" }} → "z"

另请参阅

7.75 - path.Clean

将以下英文翻译为中文:

path.Clean

https://gohugo.io/functions/path.clean/

Replaces path separators with slashes (/) and removes extraneous separators.

语法

path.Clean PATH

path.Clean replaces path separators with slashes (/) and removes extraneous separators, including trailing separators.

1
2
{{ path.Clean "foo//bar" }} → "foo/bar"
{{ path.Clean "/foo/bar/" }} → "/foo/bar"

On a Windows system, if .File.Path is foo\bar.md, then:

1
{{ path.Clean .File.Path }} → "foo/bar.md"

另请参阅

7.76 - path.Dir

将以下英文翻译为中文:

path.Dir

https://gohugo.io/functions/path.dir/

Dir returns all but the last element of a path.

语法

path.Dir PATH

path.Dir returns all but the last element of PATH, typically PATH’s directory.

The returned path will never end in a slash. If PATH is empty, . is returned.

Note: On Windows, PATH is converted to slash (/) separators.

1
2
3
4
{{ path.Dir "a/news.html" }} → "a"
{{ path.Dir "news.html" }} → "."
{{ path.Dir "a/b/c" }} → "a/b"
{{ path.Dir "/x/y/z" }} → "/x/y"

另请参阅

7.77 - path.Ext

将以下英文翻译为中文:

path.Ext

https://gohugo.io/functions/path.ext/

Ext returns the file name extension of a path.

语法

path.Ext PATH

path.Ext returns the file name extension PATH.

The extension is the suffix beginning at the final dot in the final slash-separated element PATH; it is empty if there is no dot.

Note: On Windows, PATH is converted to slash (/) separators.

1
{{ path.Ext "a/b/c/news.html" }} → ".html"

另请参阅

7.78 - path.Join

将以下英文翻译为中文:

path.Join

https://gohugo.io/functions/path.join/

Join path elements into a single path.

语法

path.Join ELEMENT...

path.Join joins path elements into a single path, adding a separating slash if necessary. All empty strings are ignored.

Note: All path elements on Windows are converted to slash (’/’) separators.

1
2
3
{{ path.Join "partial" "news.html" }} → "partial/news.html"
{{ path.Join "partial/" "news.html" }} → "partial/news.html"
{{ path.Join "foo/baz" "bar" }} → "foo/baz/bar"

另请参阅

7.79 - path.Split

将以下英文翻译为中文:

path.Split

https://gohugo.io/functions/path.split/

Split path immediately following the final slash.

语法

path.Split PATH

path.Split splits PATH immediately following the final slash, separating it into a directory and a base component.

The returned values have the property that PATH = DIR+BASE. If there is no slash in PATH, it returns an empty directory and the base is set to PATH.

Note: On Windows, PATH is converted to slash (/) separators.

1
2
3
{{ $dirFile := path.Split "a/news.html" }} → $dirFile.Dir → "a/", $dirFile.File → "news.html"
{{ $dirFile := path.Split "news.html" }} → $dirFile.Dir → "", $dirFile.File → "news.html"
{{ $dirFile := path.Split "a/b/c" }} → $dirFile.Dir → "a/b/", $dirFile.File →  "c"

另请参阅

7.80 - plainify

将以下英文翻译为中文:

plainify

https://gohugo.io/functions/plainify/

Strips any HTML and returns the plain text version of the provided string.

语法

plainify INPUT
{{ "<b>BatMan</b>" | plainify }} → "BatMan"

See also the .PlainWords, .Plain, and .RawContent page variables.

另请参阅

7.81 - pluralize

将以下英文翻译为中文:

pluralize

https://gohugo.io/functions/pluralize/

Pluralizes the given word according to a set of common English pluralization rules

语法

pluralize INPUT
{{ "cat" | pluralize }} → "cats"

另请参阅

7.82 - print

将以下英文翻译为中文:

print

https://gohugo.io/functions/print/

Prints the default representation of the given arguments using the standard fmt.Print function.

语法

print INPUT

See the go doc for additional information.

1
2
3
{{ print "foo" }} → "foo"
{{ print "foo" "bar" }} → "foobar"
{{ print (slice 1 2 3) }} → [1 2 3]

另请参阅

7.83 - printf

将以下英文翻译为中文:

printf

https://gohugo.io/functions/printf/

Formats a string using the standard fmt.Sprintf function.

语法

printf FORMAT INPUT

See the go doc for additional information.

1
2
{{ i18n ( printf "combined_%s" $var ) }}
{{ printf "formatted %.2f" 3.1416 }}

另请参阅

7.84 - println

将以下英文翻译为中文:

println

https://gohugo.io/functions/println/

Prints the default representation of the given argument using the standard fmt.Print function and enforces a linebreak.

语法

println INPUT

See the go doc for additional information. \n denotes the linebreak but isn’t printed in the templates as seen below:

1
{{ println "foo" }} → "foo\n"

另请参阅

7.85 - querify

将以下英文翻译为中文:

querify

https://gohugo.io/functions/querify/

Takes a set or slice of key-value pairs and returns a query string to be appended to URLs.

语法

querify KEY VALUE [KEY VALUE]...
querify COLLECTION

querify takes a set or slice of key-value pairs and returns a query string that can be appended to a URL.

The following examples create a link to a search results page on Google.

1
2
3
4
<a href="https://www.google.com?{{ (querify "q" "test" "page" 3) | safeURL }}">Search</a>

{{ $qs := slice "q" "test" "page" 3 }}
<a href="https://www.google.com?{{ (querify $qs) | safeURL }}">Search</a>

Both of these examples render the following HTML:

1
<a href="https://www.google.com?page=3&q=test">Search</a>

另请参阅

7.86 - range

将以下英文翻译为中文:

range

https://gohugo.io/functions/range/

Iterates over a map, array, or slice.

语法

range COLLECTION

Just like in the Go programming language, Go and Hugo templates make heavy use of range to iterate over a map, array or slice. Other templating languages use a foreach for the equivalent functionality.

range is fundamental to templating in Hugo. (See the Introduction to Hugo Templates for more examples.)

另请参阅

7.87 - readDir

将以下英文翻译为中文:

readDir

https://gohugo.io/functions/readdir/

Returns an array of FileInfo structures sorted by filename, one element for each directory entry.

语法

os.ReadDir PATH
readDir PATH

The os.ReadDir function resolves the path relative to the root of your project directory. A leading path separator (/) is optional.

With this directory structure:

1
2
3
4
5
6
content/
├── about.md
├── contact.md
└── news/
    ├── article-1.md
    └── article-2.md

This template code:

1
2
3
{{ range os.ReadDir "content" }}
  {{ .Name }} --> {{ .IsDir }}
{{ end }}

Produces:

1
2
3
about.md --> false
contact.md --> false
news --> true

Note that os.ReadDir is not recursive.

Details of the FileInfo structure are available in the Go documentation.

For more information on using readDir and readFile in your templates, see Local File Templates.

另请参阅

7.88 - readFile

将以下英文翻译为中文:

readFile

https://gohugo.io/functions/readfile/

Returns the contents of a file.

语法

os.ReadFile PATH
readFile PATH

The os.ReadFile function attempts to resolve the path relative to the root of your project directory. If a matching file is not found, it will attempt to resolve the path relative to the contentDir. A leading path separator (/) is optional.

With a file named README.md in the root of your project directory:

1
This is **bold** text.

This template code:

1
{{ os.ReadFile "README.md" }}

Produces:

1
This is **bold** text.

Note that os.ReadFile returns raw (uninterpreted) content.

For more information on using readDir and readFile in your templates, see Local File Templates.

另请参阅

7.89 - ref

将以下英文翻译为中文:

ref

https://gohugo.io/functions/ref/

Returns the absolute permalink to a page.

语法

ref . PAGE

This function takes two parameters:

  • The context of the page from which to resolve relative paths, typically the current page (.)
  • The path to a page, with or without a file extension, with or without an anchor. A path without a leading / is first resolved relative to the given context, then to the remainder of the site.
1
2
3
4
5
6
7
{{ ref . "about" }}
{{ ref . "about#anchor" }}
{{ ref . "about.md" }}
{{ ref . "about.md#anchor" }}
{{ ref . "#anchor" }}
{{ ref . "/blog/my-post" }}
{{ ref . "/blog/my-post.md" }}

To return the absolute permalink to another language version of a page:

1
{{ ref . (dict "path" "about.md" "lang" "fr") }}

To return the absolute permalink to another Output Format of a page:

1
{{ ref . (dict "path" "about.md" "outputFormat" "rss") }}

Hugo emits an error or warning if the page cannot be uniquely resolved. The error behavior is configurable; see Ref and RelRef Configuration.

This function is used by Hugo’s built-in ref shortcode. For a detailed explanation of how to leverage this shortcode for content management, see Links and Cross References.

另请参阅

7.90 - reflect.IsMap

将以下英文翻译为中文:

reflect.IsMap

https://gohugo.io/functions/reflect.ismap/

Reports if a value is a map.

语法

reflect.IsMap INPUT

reflect.IsMap reports if VALUE is a map. Returns a boolean.

1
2
{{ reflect.IsMap (dict "key" "value") }} → true
{{ reflect.IsMap "yo" }} → false

另请参阅

7.91 - reflect.IsSlice

将以下英文翻译为中文:

reflect.IsSlice

https://gohugo.io/functions/reflect.isslice/

Reports if a value is a slice.

语法

reflect.IsSlice INPUT

reflect.IsSlice reports if VALUE is a slice. Returns a boolean.

1
2
{{ reflect.IsSlice (slice 1 2 3) }} → true
{{ reflect.IsSlice "yo" }} → false

另请参阅

7.92 - relLangURL

将以下英文翻译为中文:

relLangURL

https://gohugo.io/functions/rellangurl/

Returns a relative URL with a language prefix, if any.

语法

relLangURL INPUT

Use this function with both monolingual and multilingual configurations. The URL returned by this function depends on:

  • Whether the input begins with a slash
  • The baseURL in site configuration
  • The language prefix, if any

In examples that follow, the project is multilingual with content in both Español (es) and English (en). The default language is Español. The returned values are from the English site.

Input does not begin with a slash

If the input does not begin with a slash, the resulting URL will be correct regardless of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ relLangURL "" }}           →   /en/
{{ relLangURL "articles" }}   →   /en/articles
{{ relLangURL "style.css" }}  →   /en/style.css

With baseURL = https://example.org/docs/

1
2
3
{{ relLangURL "" }}           →   /docs/en/
{{ relLangURL "articles" }}   →   /docs/en/articles
{{ relLangURL "style.css" }}  →   /docs/en/style.css

Input begins with a slash

If the input begins with a slash, the resulting URL will be incorrect when the baseURL includes a subdirectory. With a leading slash, the function returns a URL relative to the protocol+host section of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ relLangURL "/" }}          →   /en/
{{ relLangURL "/articles" }}  →   /en/articles
{{ relLangURL "/style.css" }} →   /en/style.css

With baseURL = https://example.org/docs/

1
2
3
{{ relLangURL "/" }}          →   /en/
{{ relLangURL "/articles" }}  →   /en/articles
{{ relLangURL "/style.css" }} →   /en/style.css

The last three examples are not desirable in most situations. As a best practice, never include a leading slash when using this function.

另请参阅

7.93 - relref

将以下英文翻译为中文:

relref

https://gohugo.io/functions/relref/

Returns the relative permalink to a page.

语法

relref . PAGE

This function takes two parameters:

  • The context of the page from which to resolve relative paths, typically the current page (.)
  • The path to a page, with or without a file extension, with or without an anchor. A path without a leading / is first resolved relative to the given context, then to the remainder of the site.
1
2
3
4
5
6
7
{{ relref . "about" }}
{{ relref . "about#anchor" }}
{{ relref . "about.md" }}
{{ relref . "about.md#anchor" }}
{{ relref . "#anchor" }}
{{ relref . "/blog/my-post" }}
{{ relref . "/blog/my-post.md" }}

The permalink returned is relative to the protocol+host portion of the baseURL specified in the site configuration. For example:

CodebaseURLPermalink
{{ relref . "/about" }}http://example.org//about/
{{ relref . "/about" }}http://example.org/x//x/about/

To return the relative permalink to another language version of a page:

1
{{ relref . (dict "path" "about.md" "lang" "fr") }}

To return the relative permalink to another Output Format of a page:

1
{{ relref . (dict "path" "about.md" "outputFormat" "rss") }}

Hugo emits an error or warning if the page cannot be uniquely resolved. The error behavior is configurable; see Ref and RelRef Configuration.

This function is used by Hugo’s built-in relref shortcode. For a detailed explanation of how to leverage this shortcode for content management, see Links and Cross References.

另请参阅

7.94 - relURL

将以下英文翻译为中文:

relURL

https://gohugo.io/functions/relurl/

Returns a relative URL.

语法

relURL INPUT

With multilingual configurations, use the relLangURL function instead. The URL returned by this function depends on:

  • Whether the input begins with a slash
  • The baseURL in site configuration

Input does not begin with a slash

If the input does not begin with a slash, the resulting URL will be correct regardless of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ relURL "" }}           →   /
{{ relURL "articles" }}   →   /articles
{{ relURL "style.css" }}  →   /style.css

With baseURL = https://example.org/docs/

1
2
3
{{ relURL "" }}           →   /docs/
{{ relURL "articles" }}   →   /docs/articles
{{ relURL "style.css" }}  →   /docs/style.css

Input begins with a slash

If the input begins with a slash, the resulting URL will be incorrect when the baseURL includes a subdirectory. With a leading slash, the function returns a URL relative to the protocol+host section of the baseURL.

With baseURL = https://example.org/

1
2
3
{{ relURL "/" }}          →   /
{{ relURL "/articles" }}  →   /articles
{{ relURL "style.css" }}  →   /style.css

With baseURL = https://example.org/docs/

1
2
3
{{ relURL "/" }}          →   /
{{ relURL "/articles" }}  →   /articles
{{ relURL "/style.css" }} →   /style.css

The last three examples are not desirable in most situations. As a best practice, never include a leading slash when using this function.

另请参阅

7.95 - replace

将以下英文翻译为中文:

replace

https://gohugo.io/functions/replace/

Replaces all occurrences of the search string with the replacement string.

语法

replace INPUT OLD NEW [LIMIT]
strings.Replace INPUT OLD NEW [LIMIT]

Replace returns a copy of INPUT with all occurrences of OLD replaced with NEW. The number of replacements can be limited with an optional LIMIT parameter.

`{{ replace "Batman and Robin" "Robin" "Catwoman" }}`
→ "Batman and Catwoman"

{{ replace "aabbaabb" "a" "z" 2 }} → "zzbbaabb"

7.96 - replaceRE

将以下英文翻译为中文:

replaceRE

https://gohugo.io/functions/replacere/

Returns a string, replacing all occurrences of a regular expression with a replacement pattern.

语法

replaceRE PATTERN REPLACEMENT INPUT [LIMIT]
strings.ReplaceRE PATTERN REPLACEMENT INPUT [LIMIT]

By default, replaceRE replaces all matches. You can limit the number of matches with an optional LIMIT parameter.

When specifying the regular expression, use a raw string literal (backticks) instead of an interpreted string literal (double quotes) to simplify the syntax. With an interpreted string literal you must escape backslashes.

This function uses the RE2 regular expression library. See the RE2 syntax documentation for details. Note that the RE2 \C escape sequence is not supported.

The RE2 syntax is a subset of that accepted by PCRE, roughly speaking, and with various caveats.

This example replaces two or more consecutive hyphens with a single hyphen:

1
2
{{ $s := "a-b--c---d" }}
{{ replaceRE `(-{2,})` "-" $s }} → a-b-c-d

To limit the number of replacements to one:

1
2
{{ $s := "a-b--c---d" }}
{{ replaceRE `(-{2,})` "-" $s 1 }} → a-b-c---d

You can use $1, $2, etc. within the replacement string to insert the groups captured within the regular expression:

1
2
{{ $s := "http://gohugo.io/docs" }}
{{ replaceRE "^https?://([^/]+).*" "$1" $s }} → gohugo.io

You can write and test your regular expression using regex101.com. Be sure to select the Go flavor before you begin.

另请参阅

7.97 - safeCSS

将以下英文翻译为中文:

safeCSS

https://gohugo.io/functions/safecss/

Declares the provided string as a known “safe” CSS string.

语法

safeCSS INPUT

In this context, safe means CSS content that matches any of the following:

  1. The CSS3 stylesheet production, such as p { color: purple }.
  2. The CSS3 rule production, such as a[href=~"https:"].foo#bar.
  3. CSS3 declaration productions, such as color: red; margin: 2px.
  4. The CSS3 value production, such as rgba(0, 0, 255, 127).

Example: Given style = "color: red;" defined in the front matter of your .md file:

  • <p style="{{ .Params.style | safeCSS }}">…</p><p style="color: red;">…</p>
  • <p style="{{ .Params.style }}">…</p><p style="ZgotmplZ">…</p>

“ZgotmplZ” is a special value that indicates that unsafe content reached a CSS or URL context.

另请参阅

7.98 - safeHTML

将以下英文翻译为中文:

safeHTML

https://gohugo.io/functions/safehtml/

Declares a provided string as a “safe” HTML document to avoid escaping by Go templates.

语法

safeHTML INPUT

It should not be used for HTML from a third-party, or HTML with unclosed tags or comments.

Given a site-wide config.toml with the following copyright value:

config.

=== “yaml”

``` yaml
copyright: © 2015 Jane Doe.  <a href="https://creativecommons.org/licenses/by/4.0/">Some
  rights reserved</a>.
```

=== “toml”

``` toml
copyright = '© 2015 Jane Doe.  <a href="https://creativecommons.org/licenses/by/4.0/">Some rights reserved</a>.'
```

=== “json”

``` json
{
   "copyright": "© 2015 Jane Doe.  \u003ca href=\"https://creativecommons.org/licenses/by/4.0/\"\u003eSome rights reserved\u003c/a\u003e."
}
```

{{ .Site.Copyright | safeHTML }} in a template would then output:

1
© 2015 Jane Doe.  <a href="https://creativecommons.org/licenses/by/4.0/">Some rights reserved</a>.

However, without the safeHTML function, html/template assumes .Site.Copyright to be unsafe and therefore escapes all HTML tags and renders the whole string as plain text:

1
<p>© 2015 Jane Doe.  &lt;a href=&#34;https://creativecommons.org/licenses by/4.0/&#34;&gt;Some rights reserved&lt;/a&gt;.</p>

另请参阅

7.99 - safeHTMLAttr

将以下英文翻译为中文:

safeHTMLAttr

https://gohugo.io/functions/safehtmlattr/

Declares the provided string as a safe HTML attribute.

语法

safeHTMLAttr INPUT

Given a site configuration that contains this menu entry:

config.

=== “yaml”

``` yaml
menu:
  main:
  - name: IRC
    url: irc://irc.freenode.net/#golang
```

=== “toml”

``` toml
[menu]
[[menu.main]]
  name = 'IRC'
  url = 'irc://irc.freenode.net/#golang'
```

=== “json”

``` json
{
   "menu": {
      "main": [
         {
            "name": "IRC",
            "url": "irc://irc.freenode.net/#golang"
         }
      ]
   }
}
```

Attempting to use the url value directly in an attribute:

1
2
3
{{ range site.Menus.main }}
  <a href="{{ .URL }}">{{ .Name }}</a>
{{ end }}

Will produce:

1
<a href="#ZgotmplZ">IRC</a>

ZgotmplZ is a special value, inserted by Go’s template/html package, that indicates that unsafe content reached a CSS or URL context.

To override the safety check, use the safeHTMLAttr function:

1
2
3
{{ range site.Menus.main }}
  <a {{ printf "href=%q" .URL | safeHTMLAttr }}>{{ .Name }}</a>
{{ end }}

另请参阅

7.100 - safeJS

将以下英文翻译为中文:

safeJS

https://gohugo.io/functions/safejs/

Declares the provided string as a known safe JavaScript string.

语法

safeJS INPUT

In this context, safe means the string encapsulates a known safe EcmaScript5 Expression (e.g., (x + y * z())).

Template authors are responsible for ensuring that typed expressions do not break the intended precedence and that there is no statement/expression ambiguity as when passing an expression like { foo:bar() }\n['foo'](), which is both a valid expression and a valid program with a very different meaning.

Example: Given hash = "619c16f" defined in the front matter of your .md file:

  • <script>var form_{{ .Params.hash | safeJS }};…</script><script>var form_619c16f;…</script>
  • <script>var form_{{ .Params.hash }};…</script><script>var form_"619c16f";…</script>

另请参阅

7.101 - safeURL

将以下英文翻译为中文:

safeURL

https://gohugo.io/functions/safeurl/

Declares the provided string as a safe URL or URL substring.

语法

safeURL INPUT

safeURL declares the provided string as a “safe” URL or URL substring (see RFC 3986). A URL like javascript:checkThatFormNotEditedBeforeLeavingPage() from a trusted source should go in the page, but by default dynamic javascript: URLs are filtered out since they are a frequently exploited injection vector.

Without safeURL, only the URI schemes http:, https: and mailto: are considered safe by Go templates. If any other URI schemes (e.g., irc: and javascript:) are detected, the whole URL will be replaced with #ZgotmplZ. This is to “defang” any potential attack in the URL by rendering it useless.

The following examples use a site config.toml with the following menu entry:

config.

=== “yaml”

``` yaml
menu:
  main:
  - name: 'IRC: #golang at freenode'
    url: irc://irc.freenode.net/#golang
```

=== “toml”

``` toml
[menu]
[[menu.main]]
  name = 'IRC: #golang at freenode'
  url = 'irc://irc.freenode.net/#golang'
```

=== “json”

``` json
{
   "menu": {
      "main": [
         {
            "name": "IRC: #golang at freenode",
            "url": "irc://irc.freenode.net/#golang"
         }
      ]
   }
}
```

The following is an example of a sidebar partial that may be used in conjunction with the preceding front matter example:

layouts/partials/bad-url-sidebar-menu.html

1
2
3
4
5
6
<!-- This unordered list may be part of a sidebar menu -->
<ul>
  {{ range .Site.Menus.main }}
    <li><a href="{{ .URL }}">{{ .Name }}</a></li>
  {{ end }}
</ul>

This partial would produce the following HTML output:

1
2
3
4
<!-- This unordered list may be part of a sidebar menu -->
<ul>
  <li><a href="#ZgotmplZ">IRC: #golang at freenode</a></li>
</ul>

The odd output can be remedied by adding | safeURL to our .URL page variable:

layouts/partials/correct-url-sidebar-menu.html

1
2
3
4
<!-- This unordered list may be part of a sidebar menu -->
<ul>
    <li><a href="{{ .URL | safeURL }}">{{ .Name }}</a></li>
</ul>

With the .URL page variable piped through safeURL, we get the desired output:

1
2
3
<ul class="sidebar-menu">
  <li><a href="irc://irc.freenode.net/#golang">IRC: #golang at freenode</a></li>
</ul>

另请参阅

7.102 - seq

将以下英文翻译为中文:

seq

https://gohugo.io/functions/seq/

Returns a slice of integers.

语法

seq LAST
seq FIRST LAST
seq FIRST INCREMENT LAST
{{ seq 2 }} → [1 2]
{{ seq 0 2 }} → [0 1 2]
{{ seq -2 2 }} → [-2 -1 0 1 2]
{{ seq -2 2 2 }} → [-2 0 2]

Iterate over a sequence of integers:

1
2
3
4
5
{{ $product := 1 }}
{{ range seq 4 }}
  {{ $product = mul $product . }}
{{ end }}
{{ $product }} → 24

7.103 - sha

将以下英文翻译为中文:

sha

https://gohugo.io/functions/sha/

Hashes the given input and returns either an SHA1 or SHA256 checksum.

语法

sha1 INPUT
sha256 INPUT

sha1 hashes the given input and returns its SHA1 checksum.

1
2
{{ sha1 "Hello world, gophers!" }}
<!-- returns the string "c8b5b0e33d408246e30f53e32b8f7627a7a649d4" -->

sha256 hashes the given input and returns its SHA256 checksum.

1
2
{{ sha256 "Hello world, gophers!" }}
<!-- returns the string "6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46" -->

另请参阅

7.104 - shuffle

将以下英文翻译为中文:

shuffle

https://gohugo.io/functions/shuffle/

Returns a random permutation of a given array or slice.

语法

shuffle COLLECTION
{{ shuffle (seq 1 2 3) }} → [3 1 2] 
{{ shuffle (slice "a" "b" "c") }} → [b a c] 

The result will vary from one build to the next.

另请参阅

7.105 - singularize

将以下英文翻译为中文:

singularize

https://gohugo.io/functions/singularize/

Converts a word according to a set of common English singularization rules.

语法

singularize INPUT

{{ "cats" | singularize }} → “cat”

See also the .Data.Singular taxonomy variable for singularizing taxonomy names.

另请参阅

7.106 - site

将以下英文翻译为中文:

site

https://gohugo.io/functions/site/

The site function provides global access to the same data as the .Site page method.

语法

site

site is a global function which returns the same data as the .Site page method. See: Site Variables.

7.107 - slice

将以下英文翻译为中文:

slice

https://gohugo.io/functions/slice/

Creates a slice (array) of all passed arguments.

语法

slice ITEM...

One use case is the concatenation of elements in combination with the delimit function:

slice.html

1
2
3
4
{{ $sliceOfStrings := slice "foo" "bar" "buzz" }}
<!-- returns the slice [ "foo", "bar", "buzz"] -->
{{ delimit ($sliceOfStrings) ", " }}
<!-- returns the string "foo, bar, buzz" -->

7.108 - slicestr

将以下英文翻译为中文:

slicestr

https://gohugo.io/functions/slicestr/

Creates a slice of a half-open range, including start and end indices.

语法

slicestr STRING START [END]
strings.SliceString STRING START [END]

For example, 1 and 4 creates a slice including elements 1 through 3. The end index can be omitted; it defaults to the string’s length.

  • {{ slicestr "BatMan" 3 }} → “Man”
  • {{ slicestr "BatMan" 0 3 }} → “Bat”

另请参阅

7.109 - sort

将以下英文翻译为中文:

sort

https://gohugo.io/functions/sort/

Sorts slices, maps, and page collections.

语法

sort COLLECTION [KEY] [ORDER]

The KEY is optional when sorting slices in ascending order, otherwise it is required. When sorting slices, use the literal value in place of the KEY. See examples below.

The ORDER may be either asc (ascending) or desc (descending). The default sort order is ascending.

Sort a slice

The examples below assume this site configuration:

config.

=== “yaml”

``` yaml
params:
  grades:
  - b
  - a
  - c
```

=== “toml”

``` toml
[params]
  grades = ['b', 'a', 'c']
```

=== “json”

``` json
{
   "params": {
      "grades": [
         "b",
         "a",
         "c"
      ]
   }
}
```

Ascending order

Sort slice elements in ascending order using either of these constructs:

layouts/_default/single.html

1
2
{{ sort site.Params.grades }} → [a b c]
{{ sort site.Params.grades "value" "asc" }} → [a b c]

In the examples above, value is the KEY representing the value of the slice element.

Descending order

Sort slice elements in descending order:

layouts/_default/single.html

1
{{ sort site.Params.grades "value" "desc" }} → [c b a]

In the example above, value is the KEY representing the value of the slice element.

Sort a map

The examples below assume this site configuration:

config.

=== “yaml”

``` yaml
params:
  authors:
    a:
      firstName: Marius
      lastName: Pontmercy
    b:
      firstName: Victor
      lastName: Hugo
    c:
      firstName: Jean
      lastName: Valjean
```

=== “toml”

``` toml
[params]
  [params.authors]
    [params.authors.a]
      firstName = 'Marius'
      lastName = 'Pontmercy'
    [params.authors.b]
      firstName = 'Victor'
      lastName = 'Hugo'
    [params.authors.c]
      firstName = 'Jean'
      lastName = 'Valjean'
```

=== “json”

``` json
{
   "params": {
      "authors": {
         "a": {
            "firstName": "Marius",
            "lastName": "Pontmercy"
         },
         "b": {
            "firstName": "Victor",
            "lastName": "Hugo"
         },
         "c": {
            "firstName": "Jean",
            "lastName": "Valjean"
         }
      }
   }
}
```

When sorting maps, the KEY argument must be lowercase.

Ascending order

Sort map objects in ascending order using either of these constructs:

layouts/_default/single.html

1
2
3
4
5
6
7
{{ range sort site.Params.authors "firstname" }}
  {{ .firstName }}
{{ end }}

{{ range sort site.Params.authors "firstname" "asc" }}
  {{ .firstName }}
{{ end }}

These produce:

1
Jean Marius Victor

Descending order

Sort map objects in descending order:

layouts/_default/single.html

1
2
3
{{ range sort site.Params.authors "firstname" "desc" }}
  {{ .firstName }}
{{ end }}

This produces:

1
Victor Marius Jean

Sort a page collection

Although you can use the sort function to sort a page collection, Hugo provides built-in methods for sorting page collections by:

  • weight
  • linktitle
  • title
  • front matter parameter
  • date
  • expiration date
  • last modified date
  • publish date
  • length

In this contrived example, sort the site’s regular pages by .Type in descending order:

layouts/_default/home.html

1
2
3
{{ range sort site.RegularPages "Type" "desc" }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}

另请参阅

7.110 - split

将以下英文翻译为中文:

split

https://gohugo.io/functions/split/

Returns a slice of strings by splitting STRING by DELIM.

语法

split STRING DELIM

Examples:

1
2
{{ split "tag1,tag2,tag3" "," }} → ["tag1", "tag2", "tag3"]
{{ split "abc" "" }} → ["a", "b", "c"]

split essentially does the opposite of delimit. While split creates a slice from a string, delimit creates a string from a slice.

另请参阅

7.111 - string

将以下英文翻译为中文:

string

https://gohugo.io/functions/string/

Cast a value to a string.

语法

string INPUT

With a decimal (base 10) input:

1
2
3
4
5
6
7
8
{{ string 11 }} → 11 (string)
{{ string "11" }} → 11 (string)

{{ string 11.1 }} → 11.1 (string)
{{ string "11.1" }} → 11.1 (string)

{{ string 11.9 }} → 11.9 (string)
{{ string "11.9" }} → 11.9 (string)

With a binary (base 2) input:

1
2
{{ string 0b11 }} → 3 (string)
{{ string "0b11" }} → 0b11 (string)

With an octal (base 8) input (use either notation):

1
2
3
4
5
{{ string 011 }} → 9 (string)
{{ string "011" }} → 011 (string)

{{ string 0o11 }} → 9 (string)
{{ string "0o11" }} → 0o11 (string)

With a hexadecimal (base 16) input:

1
2
{{ string 0x11 }} → 17 (string)
{{ string "0x11" }} → 0x11 (string)

另请参阅

7.112 - strings.Contains

将以下英文翻译为中文:

strings.Contains

https://gohugo.io/functions/strings.contains/

Reports whether a string contains a substring.

语法

strings.Contains STRING SUBSTRING
{{ strings.Contains "Hugo" "go" }} → true

The check is case sensitive:

{{ strings.Contains "Hugo" "Go" }} → false

7.113 - strings.ContainsAny

将以下英文翻译为中文:

strings.ContainsAny

https://gohugo.io/functions/strings.containsany/

Reports whether a string contains any character from a given string.

语法

strings.ContainsAny STRING CHARACTERS
{{ strings.ContainsAny "Hugo" "gm" }} → true

The check is case sensitive:

{{ strings.ContainsAny "Hugo" "Gm" }} → false

7.114 - strings.Count

将以下英文翻译为中文:

strings.Count

https://gohugo.io/functions/strings.count/

Returns the number of non-overlapping instances of a substring within a string.

语法

strings.Count SUBSTR STRING

If SUBSTR is an empty string, this function returns 1 plus the number of Unicode code points in STRING.

ExampleResult
`{{ “aaabaab”strings.Count “a” }}`
`{{ “aaabaab”strings.Count “aa” }}`
`{{ “aaabaab”strings.Count “aaa” }}`
`{{ “aaabaab”strings.Count "" }}`

另请参阅

7.115 - strings.FirstUpper

将以下英文翻译为中文:

strings.FirstUpper

https://gohugo.io/functions/strings.firstupper/

Capitalizes the first character of a given string.

语法

strings.FirstUpper STRING
{{ strings.FirstUpper "foo" }} → "Foo"

7.116 - strings.HasPrefix

将以下英文翻译为中文:

strings.HasPrefix

https://gohugo.io/functions/strings.hasprefix/

Tests whether a string begins with prefix.

语法

hasPrefix STRING PREFIX
strings.HasPrefix STRING PREFIX
{{ hasPrefix "Hugo" "Hu" }} → true

另请参阅

7.117 - strings.HasSuffix

将以下英文翻译为中文:

strings.HasSuffix

https://gohugo.io/functions/strings.hassuffix/

Tests whether a string ends with suffix.

语法

hasSuffix STRING SUFFIX
strings.HasSuffix STRING SUFFIX
{{ hasSuffix "Hugo" "go" }} → true

另请参阅

7.118 - strings.Repeat

将以下英文翻译为中文:

strings.Repeat

https://gohugo.io/functions/strings.repeat/

Returns INPUT repeated COUNT times.

语法

strings.Repeat COUNT INPUT
{{ strings.Repeat 3 "yo" }} → "yoyoyo"
{{ "yo" | strings.Repeat 3 }} → "yoyoyo"

另请参阅

7.119 - strings.RuneCount

将以下英文翻译为中文:

strings.RuneCount

https://gohugo.io/functions/strings.runecount/

Determines the number of runes in a string.

语法

strings.RuneCount INPUT

In contrast with strings.CountRunes function, which strips HTML and whitespace before counting runes, strings.RuneCount simply counts all the runes in a string. It relies on the Go [utf8.RuneCountInString] function.

1
2
{{ "Hello, 世界" | strings.RuneCount }}
<!-- outputs a content length of 9 runes. -->

另请参阅

7.120 - strings.TrimLeft

将以下英文翻译为中文:

strings.TrimLeft

https://gohugo.io/functions/strings.trimleft/

Returns a slice of a given string with all leading characters contained in the cutset removed.

语法

strings.TrimLeft CUTSET STRING

Given the string "abba", leading "a"’s can be removed a follows:

{{ strings.TrimLeft "a" "abba" }} → "bba"

Numbers can be handled as well:

{{ strings.TrimLeft 12 1221341221 }} → "341221"

另请参阅

7.121 - strings.TrimPrefix

将以下英文翻译为中文:

strings.TrimPrefix

https://gohugo.io/functions/strings.trimprefix/

Returns a given string s without the provided leading prefix string. If s doesn’t start with prefix, s is returned unchanged.

语法

strings.TrimPrefix PREFIX STRING

Given the string "aabbaa", the specified prefix is only removed if "aabbaa" starts with it:

{{ strings.TrimPrefix "a" "aabbaa" }} → "abbaa"
{{ strings.TrimPrefix "aa" "aabbaa" }} → "bbaa"
{{ strings.TrimPrefix "aaa" "aabbaa" }} → "aabbaa"

另请参阅

7.122 - strings.TrimRight

将以下英文翻译为中文:

strings.TrimRight

https://gohugo.io/functions/strings.trimright/

Returns a slice of a given string with all trailing characters contained in the cutset removed.

语法

strings.TrimRight CUTSET STRING

Given the string "abba", trailing "a"’s can be removed a follows:

{{ strings.TrimRight "a" "abba" }} → "abb"

Numbers can be handled as well:

{{ strings.TrimRight 12 1221341221 }} → "122134"

另请参阅

7.123 - strings.TrimSuffix

将以下英文翻译为中文:

strings.TrimSuffix

https://gohugo.io/functions/strings.trimsuffix/

Returns a given string s without the provided trailing suffix string. If s doesn’t end with suffix, s is returned unchanged.

语法

strings.TrimSuffix SUFFIX STRING

Given the string "aabbaa", the specified suffix is only removed if "aabbaa" ends with it:

{{ strings.TrimSuffix "a" "aabbaa" }} → "aabba"
{{ strings.TrimSuffix "aa" "aabbaa" }} → "aabb"
{{ strings.TrimSuffix "aaa" "aabbaa" }} → "aabbaa"

另请参阅

7.124 - substr

将以下英文翻译为中文:

substr

https://gohugo.io/functions/substr/

Extracts parts of a string from a specified character’s position and returns the specified number of characters.

语法

substr STRING START [LENGTH]
strings.Substr STRING START [LENGTH]

It normally takes two parameters: start and length. It can also take one parameter: start, i.e. length is omitted, in which case the substring starting from start until the end of the string will be returned.

To extract characters from the end of the string, use a negative start number.

If length is given and is negative, that number of characters will be omitted from the end of string.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{{ substr "abcdef" 0 }} → "abcdef"
{{ substr "abcdef" 1 }} → "bcdef"

{{ substr "abcdef" 0 1 }} → "a"
{{ substr "abcdef" 1 1 }} → "b"

{{ substr "abcdef" 0 -1 }} → "abcde"
{{ substr "abcdef" 1 -1 }} → "bcde"

{{ substr "abcdef" -1 }} → "f"
{{ substr "abcdef" -2 }} → "ef"

{{ substr "abcdef" -1 1 }} → "f"
{{ substr "abcdef" -2 1 }} → "e"

{{ substr "abcdef" -3 -1 }} → "de"
{{ substr "abcdef" -3 -2 }} → "d"

另请参阅

7.125 - symdiff

将以下英文翻译为中文:

symdiff

https://gohugo.io/functions/symdiff/

collections.SymDiff (alias symdiff) returns the symmetric difference of two collections.

语法

COLLECTION | symdiff COLLECTION

Example:

1
{{ slice 1 2 3 | symdiff (slice 3 4) }}

The above will print [1 2 4].

Also see https://en.wikipedia.org/wiki/Symmetric_difference

另请参阅

7.126 - templates.Exists

将以下英文翻译为中文:

templates.Exists

https://gohugo.io/functions/templates.exists/

Checks whether a template file exists under the given path relative to the layouts directory.

语法

templates.Exists PATH

A template file is any file living below the layouts directories of either the project or any of its theme components including partials and shortcodes.

The function is particularly handy with dynamic path. The following example ensures the build will not break on a .Type missing its dedicated header partial.

1
2
3
4
5
6
{{ $partialPath := printf "headers/%s.html" .Type }}
{{ if templates.Exists ( printf "partials/%s" $partialPath ) }}
  {{ partial $partialPath . }}
{{ else }}
  {{ partial "headers/default.html" . }}
{{ end }}

另请参阅

7.127 - time

将以下英文翻译为中文:

time

https://gohugo.io/functions/time/

Converts a timestamp string into a time.Time structure.

语法

time INPUT [TIMEZONE]

time converts a timestamp string with an optional default location into a time.Time structure so you can access its fields:

1
2
3
{{ time "2016-05-28" }} → "2016-05-28T00:00:00Z"
{{ (time "2016-05-28").YearDay }} → 149
{{ mul 1000 (time "2016-05-28T10:30:00.00+10:00").Unix }} → 1464395400000, or Unix time in milliseconds

Using Locations

The optional TIMEZONE parameter is a string that sets a default time zone (or more specific, the location, which represents the collection of time offsets in a geographical area) that is associated with the specified time value. If the time value has an explicit timezone or offset specified, it will take precedence over the TIMEZONE parameter.

The list of valid locations may be system dependent, but should include UTC, Local, or any location in the IANA Time Zone database.

If no TIMEZONE is set, the timeZone from site configuration will be used.

1
2
3
{{ time "2020-10-20" }} → 2020-10-20 00:00:00 +0000 UTC
{{ time "2020-10-20" "America/Los_Angeles" }} → 2020-10-20 00:00:00 -0700 PDT
{{ time "2020-01-20" "America/Los_Angeles" }} → 2020-01-20 00:00:00 -0800 PST

Example: Using time to get Month Index

The following example takes a UNIX timestamp—set as utimestamp: "1489276800" in a content’s front matter—converts the timestamp (string) to an integer using the int function, and then uses printf to convert the Month property of time into an index.

The following example may be useful when setting up multilingual sites:

unix-to-month-integer.html

1
2
3
4
5
6
{{ $time := time (int .Params.addDate)}}
=> $time = 1489276800
{{ $time.Month }}
=> "March"
{{ $monthindex := printf "%d" $time.Month }}
=> $monthindex = 3

另请参阅

7.128 - time.Format

将以下英文翻译为中文:

time.Format

https://gohugo.io/functions/dateformat/

Converts a date/time to a localized string.

语法

time.Format LAYOUT INPUT
dateFormat LAYOUT INPUT

time.Format (alias dateFormat) converts either a time.Time object (e.g. .Date) or a timestamp string INPUT into the format specified by the LAYOUT string.

1
{{ time.Format "Monday, Jan 2, 2006" "2015-01-21" }} → "Wednesday, Jan 21, 2015"

time.Format returns a localized string for the current language.

The LAYOUT string can be either:

  • Go’s Layout String to learn about how the LAYOUT string has to be formatted. There are also some useful examples.
  • A custom Hugo layout identifier (see full list below)

See the time function to convert a timestamp string to a Go time.Time type value.

Date/time formatting layouts

Go’s date layout strings can be hard to reason about, especially with multiple languages. You can alternatively use some predefined layout identifiers that will output localized dates or times:

1
{{ .Date | time.Format ":date_long" }}

The full list of custom layouts with examples for English:

  • :date_full => Wednesday, June 6, 2018
  • :date_long => June 6, 2018
  • :date_medium => Jun 6, 2018
  • :date_short => 6/6/18
  • :time_full => 2:09:37 am UTC
  • :time_long => 2:09:37 am UTC
  • :time_medium => 2:09:37 am
  • :time_short => 2:09 am

另请参阅

7.129 - time.ParseDuration

将以下英文翻译为中文:

time.ParseDuration

https://gohugo.io/functions/time.parseduration/

Parses a given duration string into a time.Duration structure.

语法

time.ParseDuration DURATION

time.ParseDuration parses a duration string into a time.Duration structure so you can access its fields. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as 300ms, -1.5h or 2h45m. Valid time units are ns, us (or µs), ms, s, m, h.

You can perform time operations on the returned time.Duration value:

{{ printf "There are %.0f seconds in one day." (time.ParseDuration "24h").Seconds }}
<!-- Output: There are 86400 seconds in one day. -->

7.130 - title

将以下英文翻译为中文:

title

https://gohugo.io/functions/title/

​ 将提供的字符串转换为标题大小写样式。

语法

title STRING
strings.Title STRING
{{ title "table of contents (TOC)" }} → "Table of Contents (TOC)"

​ 默认情况下,Hugo 遵循美联社风格指南(Associated Press (AP) Stylebook)的大写规则。如果您更喜欢遵循芝加哥手册风格(Chicago Manual of Style),或者使用 Go 的惯例将每个单词都大写,请更改您的站点配置

另请参阅

7.131 - transform.Unmarshal

将以下英文翻译为中文:

transform.Unmarshal

https://gohugo.io/functions/transform.unmarshal/

transform.Unmarshal (alias unmarshal) parses the input and converts it into a map or an array. Supported formats are JSON, TOML, YAML, XML and CSV.

语法

RESOURCE or STRING | transform.Unmarshal [OPTIONS]

The function accepts either a Resource created in Hugo Pipes or via Page Bundles, or simply a string. The two examples below will produce the same map:

1
2
{{ $greetings := "hello = \"Hello Hugo\"" | transform.Unmarshal }}`
{{ $greetings := "hello = \"Hello Hugo\"" | resources.FromString "data/greetings.toml" | transform.Unmarshal }}

In both the above examples, you get a map you can work with:

1
{{ $greetings.hello }}

The above prints Hello Hugo.

CSV Options

Unmarshal with CSV as input has some options you can set:

  • delimiter

    The delimiter used, default is ,.

  • comment

    The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.:

Example:

1
{{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }}

XML data

As a convenience, Hugo allows you to access XML data in the same way that you access JSON, TOML, and YAML: you do not need to specify the root node when accessing the data.

To get the contents of <title> in the document below, you use {{ .message.title }}:

1
2
3
4
5
6
<root>
    <message>
        <title>Hugo rocks!</title>
        <description>Thanks for using Hugo</description>
    </message>
</root>

The following example lists the items of an RSS feed:

1
2
3
4
5
6
7
8
9
{{ with resources.Get "https://example.com/rss.xml" | transform.Unmarshal }}
    {{ range .channel.item }}
        <strong>{{ .title | plainify | htmlUnescape }}</strong><br />
        <p>{{ .description | plainify | htmlUnescape }}</p>
        {{ $link := .link | plainify | htmlUnescape }}
        <a href="{{ $link }}">{{ $link }}</a><br />
        <hr>
    {{ end }}
{{ end }}

7.132 - trim

将以下英文翻译为中文:

trim

https://gohugo.io/functions/trim/

Returns a slice of a passed string with all leading and trailing characters from cutset removed.

语法

trim INPUT CUTSET
strings.Trim INPUT CUTSET
{{ trim "++Batman--" "+-" }} → "Batman"

trim requires the second argument, which tells the function specifically what to remove from the first argument. There is no default value for the second argument, so the following usage will not work:

1
{{ trim .Inner }}

Instead, the following example tells trim to remove extra new lines from the content contained in the shortcode .Inner variable:

1
{{ trim .Inner "\n" }}

Go templates also provide a simple method for trimming whitespace from either side of a Go tag by including a hyphen (-).

另请参阅

7.133 - truncate

将以下英文翻译为中文:

truncate

https://gohugo.io/functions/truncate/

Truncates a text to a max length without cutting words or leaving unclosed HTML tags.

语法

truncate SIZE [ELLIPSIS] INPUT
strings.Truncate SIZE [ELLIPSIS] INPUT

Since Go templates are HTML-aware, truncate will intelligently handle normal strings vs HTML strings:

1
{{ "<em>Keep my HTML</em>" | safeHTML | truncate 10 }}` → <em>Keep my …</em>`

If you have a raw string that contains HTML tags you want to remain treated as HTML, you will need to convert the string to HTML using the safeHTML template function before sending the value to truncate. Otherwise, the HTML tags will be escaped when passed through the truncate function.

另请参阅

7.134 - union

将以下英文翻译为中文:

union

https://gohugo.io/functions/union/

Given two arrays or slices, returns a new array that contains the elements or objects that belong to either or both arrays/slices.

语法

union SET1 SET2

Given two arrays (or slices) A and B, this function will return a new array that contains the elements or objects that belong to either A or to B or to both. The elements supported are strings, integers, and floats (only float64).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{{ union (slice 1 2 3) (slice 3 4 5) }}
<!-- returns [1 2 3 4 5] -->

{{ union (slice 1 2 3) nil }}
<!-- returns [1 2 3] -->

{{ union nil (slice 1 2 3) }}
<!-- returns [1 2 3] -->

{{ union nil nil }}
<!-- returns an error because both arrays/slices have to be of the same type -->

OR filter in where query

This is also very useful to use as OR filters when combined with where:

1
2
3
{{ $pages := where .Site.RegularPages "Type" "not in" (slice "page" "about") }}
{{ $pages = $pages | union (where .Site.RegularPages "Params.pinned" true) }}
{{ $pages = $pages | intersect (where .Site.RegularPages "Params.images" "!=" nil) }}

The above fetches regular pages not of page or about type unless they are pinned. And finally, we exclude all pages with no images set in Page params.

See intersect for AND.

另请参阅

7.135 - uniq

将以下英文翻译为中文:

uniq

https://gohugo.io/functions/uniq/

Takes in a slice or array and returns a slice with duplicate elements removed.

语法

uniq SET
{{ slice 1 3 2 1 | uniq }} --> [1 3 2]

另请参阅

7.136 - upper

将以下英文翻译为中文:

upper

https://gohugo.io/functions/upper/

Converts all characters in a string to uppercase

语法

upper INPUT
strings.ToUpper INPUT

Note that upper can be applied in your templates in more than one way:

1
2
{{ upper "BatMan" }} → "BATMAN"
{{ "BatMan" | upper }} → "BATMAN"

7.137 - urlize

将以下英文翻译为中文:

urlize

https://gohugo.io/functions/urlize/

Takes a string, sanitizes it for usage in URLs, and converts spaces to hyphens.

语法

urlize INPUT

The following examples pull from a content file with the following front matter:

xxxxxxxxxx2 1{{ upper “BatMan” }} → “BATMAN"2{{ “BatMan” | upper }} → “BATMAN"go-html-template

=== “yaml”

``` yaml
---
location: Chicago IL
tags:
- pizza
- beer
- hot dogs
title: The World's Greatest City
---
```

=== “toml”

``` toml
+++
location = 'Chicago IL'
tags = ['pizza', 'beer', 'hot dogs']
title = "The World's Greatest City"
+++
```

=== “json”

``` json
{
   "location": "Chicago IL",
   "tags": [
      "pizza",
      "beer",
      "hot dogs"
   ],
   "title": "The World's Greatest City"
}
```

The following might be used as a partial within a single page template:

layouts/partials/content-header.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<header>
    <h1>{{ .Title }}</h1>
    {{ with .Params.location }}
        <div><a href="/locations/{{ . | urlize }}">{{ . }}</a></div>
    {{ end }}
    <!-- Creates a list of tags for the content and links to each of their pages -->
    {{ with .Params.tags }}
    <ul>
        {{ range .}}
            <li>
                <a href="/tags/{{ . | urlize }}">{{ . }}</a>
            </li>
        {{ end }}
    </ul>
    {{ end }}
</header>

The preceding partial would then output to the rendered page as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<header>
  <h1>The World&#39;s Greatest City</h1>
  <div><a href="/locations/chicago-il">Chicago IL</a></div>
  <ul>
    <li>
      <a href="/tags/pizza">pizza</a>
    </li>
    <li>
      <a href="/tags/beer">beer</a>
    </li>
    <li>
      <a href="/tags/hot-dogs">hot dogs</a>
    </li>
  </ul>
</header>

另请参阅

7.138 - urlquery

将以下英文翻译为中文:

urlquery

https://gohugo.io/functions/urlquery/

Returns the escaped value of the textual representation of its arguments in a form suitable for embedding in a URL query.

语法

urlquery INPUT [INPUT]...

This template code:

1
2
{{ $u := urlquery "https://" "example.com" | safeURL }}
<a href="https://example.org?url={{ $u }}">Link</a>

Is rendered to:

1
<a href="https://example.org?url=https%3A%2F%2Fexample.com">Link</a>

另请参阅

7.139 - urls.Parse

将以下英文翻译为中文:

urls.Parse

https://gohugo.io/functions/urls.parse/

Parses a URL into a URL structure.

语法

urls.Parse URL

The urls.Parse function parses a URL into a URL structure. The URL may be relative (a path, without a host) or absolute (starting with a scheme). Hugo throws an error when parsing an invalid URL.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{{ $url := "https://example.org:123/foo?a=6&b=7#bar" }}
{{ $u := urls.Parse $url }}

{{ $u.IsAbs }} → true
{{ $u.Scheme }} → https
{{ $u.Host }} → example.org:123
{{ $u.Hostname }} → example.org
{{ $u.RequestURI }} → /foo?a=6&b=7
{{ $u.Path }} → /foo
{{ $u.Query }} → map[a:[6] b:[7]]
{{ $u.Query.a }} → [6]
{{ $u.Query.Get "a" }} → 6
{{ $u.Query.Has "b" }} → true
{{ $u.Fragment }} → bar

另请参阅

7.140 - where

将以下英文翻译为中文:

where

https://gohugo.io/functions/where/

Filters an array to only the elements containing a matching value for a given field.

语法

where COLLECTION KEY [OPERATOR] MATCH

where filters an array to only the elements containing a matching value for a given field.

It works in a similar manner to the where keyword in SQL.

1
2
3
{{ range where .Pages "Section" "foo" }}
  {{ .Content }}
{{ end }}

It can be used by dot-chaining the second argument to refer to a nested element of a value.

content/example.md

=== “yaml”

``` yaml
---
series: golang
title: Example
---
```

=== “toml”

``` toml
+++
series = 'golang'
title = 'Example'
+++
```

=== “json”

``` json
{
   "series": "golang",
   "title": "Example"
}
```
1
2
3
{{ range where .Site.Pages "Params.series" "golang" }}
   {{ .Content }}
{{ end }}

It can also be used with the logical operators !=, >=, in, etc. Without an operator, where compares a given field with a matching value equivalent to =.

1
2
3
{{ range where .Pages "Section" "!=" "foo" }}
   {{ .Content }}
{{ end }}

The following logical operators are available with where:

  • =, ==, eq

    true if a given field value equals a matching value

  • !=, <>, ne

    true if a given field value doesn’t equal a matching value

  • >=, ge

    true if a given field value is greater than or equal to a matching value

  • >, gt

    true if a given field value is greater than a matching value

  • <=, le

    true if a given field value is lesser than or equal to a matching value

  • <, lt

    true if a given field value is lesser than a matching value

  • in

    true if a given field value is included in a matching value; a matching value must be an array or a slice

  • not in

    true if a given field value isn’t included in a matching value; a matching value must be an array or a slice

  • intersect

    true if a given field value that is a slice/array of strings or integers contains elements in common with the matching value; it follows the same rules as the intersect function.

Use where with Booleans

When using booleans you should not put quotation marks.

1
2
3
{{ range where .Pages "Draft" true }}
        <p>{{ .Title }}</p>
{{ end }}

Use where with intersect

1
2
3
4
5
{{ range where .Site.Pages "Params.tags" "intersect" .Params.tags }}
  {{ if ne .Permalink $.Permalink }}
    {{ .Render "summary" }}
  {{ end }}
{{ end }}

You can also put the returned value of the where clauses into a variable:

where-intersect-variables.html

1
2
3
4
5
{{ $v1 := where .Site.Pages "Params.a" "v1" }}
{{ $v2 := where .Site.Pages "Params.b" "v2" }}
{{ $filtered := $v1 | intersect $v2 }}
{{ range $filtered }}
{{ end }}

Use where with first

Using first and where together can be very powerful. Below snippet gets a list of posts only from main sections, sorts it using the default ordering for lists (i.e., weight => date), and then ranges through only the first 5 posts in that list:

first-and-where-together.html

1
2
3
{{ range first 5 (where site.RegularPages "Type" "in" site.Params.mainSections) }}
   {{ .Content }}
{{ end }}

Nest where Clauses

You can also nest where clauses to drill down on lists of content by more than one parameter. The following first grabs all pages in the “blog” section and then ranges through the result of the first where clause and finds all pages that are not featured:

1
{{ range where (where .Pages "Section" "blog" ) "Params.featured" "!=" true }}

Unset Fields

Filtering only works for set fields. To check whether a field is set or exists, you can use the operand nil.

This can be useful to filter a small amount of pages from a large pool. Instead of setting a field on all pages, you can set that field on required pages only.

Only the following operators are available for nil

  • =, ==, eq: True if the given field is not set.
  • !=, <>, ne: True if the given field is set.
1
2
3
{{ range where .Pages "Params.specialpost" "!=" nil }}
   {{ .Content }}
{{ end }}

Portable where filters – site.Params.mainSections

This is especially important for themes.

To list the most relevant pages on the front page or similar, you should use the site.Params.mainSections list instead of comparing section names to hard-coded values like "posts" or "post".

1
{{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}

If the user has not set this config parameter in their site config, it will default to the section with the most pages.

The user can override the default:

config.

=== “yaml”

``` yaml
params:
  mainSections:
  - blog
  - docs
```

=== “toml”

``` toml
[params]
  mainSections = ['blog', 'docs']
```

=== “json”

``` json
{
   "params": {
      "mainSections": [
         "blog",
         "docs"
      ]
   }
}
```

7.141 - with

将以下英文翻译为中文:

with

https://gohugo.io/functions/with/

Rebinds the context (.) within its scope and skips the block if the variable is absent or empty.

语法

with INPUT

An alternative way of writing an if statement and then referencing the same value is to use with instead. with rebinds the context (.) within its scope and skips the block if the variable is absent, unset or empty.

The set of empty values is defined by the Go templates package. Empty values include false, the number zero, and the empty string.

If you want to render a block if an index or key is present in a slice, array, channel or map, regardless of whether the value is empty, you should use isset instead.

The following example checks for a user-defined site variable called twitteruser. If the key-value is not set, the following will render nothing:

layouts/partials/twitter.html

1
2
3
4
5
{{ with .Site.Params.twitteruser }}<span class="twitter">
<a href="https://twitter.com/{{ . }}" rel="author">
<img src="/images/twitter.png" width="48" height="48" title="Twitter: {{ . }}"
 alt="Twitter"></a>
</span>{{ end }}

8 - 变量

Variables and Params - 变量和参数

https://gohugo.io/variables/

​ Hugo的模板是上下文感知的,并为您在创建站点视图时提供大量的可用值。

8.1 - 站点变量

Site Variables - 站点变量

https://gohugo.io/variables/site/

​ 许多站点范围的变量在站点配置中定义,但是,Hugo提供了许多内置变量,以方便在模板中访问全局值。

​ 以下是站点级别(也称为"全局")变量列表。其中许多变量在站点配置文件中定义,而其他变量则内置于Hugo的核心中,以便在模板中方便使用。

从局部获取Site对象

​ 下面的所有方法,例如.Site.RegularPages也可以通过全局site函数(例如site.RegularPages)访问,这在局部文件中 Page 对象不容易获取时可能会很方便。

站点变量列表

.Site.AllPages

​ 所有页面的数组,不考虑它们的翻译。

.Site.BaseURL

​ 站点配置中定义的站点基本URL。

.Site.BuildDrafts

​ 一个布尔值(默认值为false),用于指示是否按照站点配置构建草稿。

​ 表示您的站点版权的字符串,即在站点配置中所定义的。

.Site.Data

​ 自定义数据,请参阅数据模板

.Site.DisqusShortname

​ 表示Disqus简码的字符串,即在站点配置文件中所定义的。

.Site.GoogleAnalytics

​ 表示Google Analytics追踪代码的字符串,即在站点配置文件中所定义的。

.Site.Home

​ 指向主页页面对象的引用。

.Site.IsMultiLingual

​ 是否在该站点中存在多种语言。有关更多信息,请参见多语言

.Site.IsServer

​ 一个布尔值,指示是否使用Hugo的内置服务器提供站点。有关更多信息,请参见hugo server

.Site.Language.Lang

​ 当前区域设置的语言代码(例如,en)。

.Site.Language.LanguageName

​ 完整的语言名称(例如,English)。

.Site.Language.Weight

​ 定义.Site.Languages列表顺序的权重。

.Site.Language

​ 指示当前用于渲染站点的语言。该对象的属性在站点配置语言定义中设置。

.Site.LanguageCode

​ 表示在站点配置中定义的语言tag的字符串。

.Site.LanguagePrefix

​ 可以用于为URL添加前缀以指向正确的语言。即使只定义了一种语言,它也会起作用。另请参见absLangURLrelLangURL函数。

.Site.Languages

​ 一个按照定义的权重排序的语言列表。

.Site.LastChange

​ 一个表示站点最近更改的日期/时间的字符串。此字符串基于内容页面前置元数据中的date变量。

​ 站点中的所有菜单。

.Site.Pages

​ 按日期排序的所有内容的数组,最新的在前面。此数组仅包含当前语言的页面。请参阅.Site.Pages

.Site.RegularPages

​ 一个常规页面集合的快捷方式。.Site.RegularPages等效于where .Site.Pages "Kind" "page"。请参阅.Site.Pages

.Site.Sections

​ 站点的顶级目录。

.Site.Taxonomies

​ 整个站点的分类法。另请参阅从任何模板访问分类法数据的章节。

.Site.Title

​ 一个表示站点标题的字符串。

.Site.Params变量

.Site.Params是一个容器,它保存了来自站点配置params 部分的值。

示例: .Site.Params

​ 以下config.[yaml|toml|json]定义了一个站点范围的description参数:

config.

=== “yaml”

``` yaml
baseURL: https://yoursite.example.com/
params:
  author: Nikola Tesla
  description: Tesla's Awesome Hugo Site
```

=== “toml”

``` toml
baseURL = 'https://yoursite.example.com/'
[params]
  author = 'Nikola Tesla'
  description = "Tesla's Awesome Hugo Site"
```

=== “json”

``` json
{
   "baseURL": "https://yoursite.example.com/",
   "params": {
      "author": "Nikola Tesla",
      "description": "Tesla's Awesome Hugo Site"
   }
}
```

​ 您可以在局部模板中使用.Site.Params调用默认站点描述:

layouts/partials/head.html

1
<meta name="description" content="{{ if .IsHome }}{{ $.Site.Params.description }}{{ else }}{{ .Description }}{{ end }}" />

.Site.Pages变量

.Site.Pages.Pages比较

  • 常规页面是"post"页面或"content"页面。

    • 叶子bundle是常规页面。
  • 列表页面可以列出常规页面和其他列表页面。一些示例是:主页、章节页面、分类法(/tags/)和条目(/tags/foo/)页面。

    • 分支bundle是列表页面。
  • .Site.Pages

    站点所有页面的集合:常规页面、章节页面、分类法页面等——Superset of everything!

  • .Site.RegularPages

    仅包含常规页面的集合。

​ 上述.Site. ..页面集合可以从模板的任何作用域中访问。

​ 以下变量仅从当前列表页的作用域返回页面集合:

  • .Pages

    Collection of regular pages and only first-level section pages under the current list page.

    在当前列表页面下,包含所有常规页面和只有一级章节页面的集合。

  • .RegularPages

    仅包含当前列表页面下的普通页面的集合。这排除嵌套章节/列表页面中的常规页面(那些是带有 _index.md 文件的子目录)。

  • .RegularPagesRecursive

    包含一个列表页面下的所有普通页面的集合。这包括嵌套章节/列表页面中的常规页面。

    注意

    常规页面的作用域来看,.Pages.RegularPages 返回一个空的 slice。

8.2 - 页面变量

Page Variables - 页面变量

https://gohugo.io/variables/page/

​ 页面级变量定义在内容文件的前置元数据中,从内容文件的位置中派生出来,或从内容本身中提取出来。

​ 以下是页面级变量列表。其中许多将在前置元数据中定义、从文件位置中派生或从内容本身中提取。

页面变量

.AlternativeOutputFormats

包含给定页面的所有备选格式;这个变量在您站点的 <head> 中的 link rel 列表中非常有用。(请参见输出格式(Output Formats)。)

.Aliases

此页面的别名

.Ancestors

​ 获取每个页面的祖先,简化 面包屑导航(breadcrumb navigation) 实现的复杂性。

.BundleType

bundle类型: leaf, branch, 或者如果页面不是bundle,则为空字符串。

.Content

​ 内容本身,在前置元数据下定义。

.Data

​ 特定于此页面类型的数据。

.Date

​ 与页面相关联的日期;.Date从内容的前置元数据中的date字段获取。还请参见.ExpiryDate.PublishDate.Lastmod

.Description

​ 此页面的描述。

.Draft

​ 一个布尔值,如果内容在前置元数据中标记为草稿,则为 true

.ExpiryDate

​ 内容计划过期的日期;.ExpiryDate从内容的前置元数据中的expirydate字段获取。还请参见.PublishDate.Date.Lastmod

.File

此内容文件的文件系统相关数据。另请参见文件变量(File Variables)

.Fragments

​ Fragments返回此页面的片段。请参见页面片段(Page Fragments)

.FuzzyWordCount

​ 此内容中字的大致数量。

.IsHome

​ 在 主页(homepage) 的上下文中为 true

.IsNode

​ 对于常规内容页面始终为 false

.IsPage

​ 对于常规内容页面始终为 true

.IsSection

​ 如果 .Kindsection,则为 true

.IsTranslated

​ 如果有要显示的翻译,则为 true

.Keywords

​ 此内容的元关键字。

.Kind

​ 此页面的 kind。可能的返回值为 pagehomesectiontaxonomyterm。请注意,还有 RSSsitemaprobotsTXT404 类型,但这些仅在每个相应页面类型的渲染期间可用,因此这些不可在任何 Pages 集合中使用。

.Language

​ 一个指向该站点 config 中语言定义的语言对象。.Language.Lang 给出语言代码。

.Lastmod

​ 此内容最后修改日期。.Lastmod 从内容的前置元数据中的 lastmod 字段获取。

  • 如果未设置 lastmod 并且 .GitInfo 特性已禁用,则将使用前置元数据中的 date 字段。
  • 如果未设置 lastmod 并且 .GitInfo 特性已启用,则将使用.GitInfo.AuthorDate

​ 另请参阅 .ExpiryDate.Date.PublishDate.GitInfo

.LinkTitle

​ 创建指向此内容的链接时使用。如果设置了(linktitle),Hugo 将在title之前使用前置元数据中的 linktitle

.Next

​ 指向下一个 常规页面(按 Hugo 的 默认排序 排序)。示例:{{ with .Next }}{{ .Permalink }}{{ end }}。从第一页调用 .Next 将返回 nil

.NextInSection

​ 指向同一顶级章节的下一个 常规页面(例如在 /blog 中)。页面按 Hugo 的 默认排序 排序。示例:{{ with .NextInSection }}{{ .Permalink }}{{ end }}。从第一页调用 .NextInSection 将返回 nil

.OutputFormats

​ 包含给定页面的所有格式,包括当前格式。可以与 .Get 函数 结合使用来获取特定格式(请参阅 输出格式)。

.Pages

​ 相关页面的集合。在常规内容页面的上下文中,此值将为 nil。请参阅 .Pages

​ 此页面的永久链接;请参阅 永久链接

.Plain

​ 此页面内容去掉 HTML 标签后以字符串形式呈现。在使用 HTML 输出格式 渲染此值时,您可能需要通过 htmlUnescape 函数进行结果处理。

.PlainWords

​ 将 .Plain 拆分为字所生成的字符串切片,如 Go 的 strings.Fields 中定义。

.Prev

​ 指向上一个 常规页面(按 Hugo 的 默认排序 排序)。示例:{{ if .Prev }}{{ .Prev.Permalink }}{{ end }}。从最后一页调用 .Prev 将返回 nil

.PrevInSection

​ 指向同一顶级章节的下一个 常规页面(例如 /blog)。页面按 Hugo 的 默认排序 排序。示例:{{ if .PrevInSection }}{{ .PrevInSection.Permalink }}{{ end }}。从最后一页调用 .PrevInSection 将返回 nil

.PublishDate

​ 此内容发布日期或将要发布的日期;.Publishdate 从内容的前置元数据中的 publishdate 字段获取。另请参阅 .ExpiryDate.Date.Lastmod

.RawContent

​ 没有前置元数据的原始Markdown内容。与 remarkjs.com 配合使用很有用。

.ReadingTime

​ 估计阅读此内容需要的时间(以分钟为单位)。

.Resources

​ 与此页面相关联的资源,例如图像和CSS。

.Ref

​ 返回给定引用(例如 .Ref "sample.md")的永久链接。.Ref 无法正确处理页面内部片段。请参阅 交叉引用

​ 此页面的相对永久链接。

.RelRef

​ 返回给定引用(例如 RelRef "sample.md")的相对永久链接。.RelRef 无法正确处理页面内部片段。请参阅 交叉引用

.Site

​ 参见站点变量

.Sites

​ 返回所有站点(语言)。一个典型的用例是链接回主语言:<a href="{{ .Sites.First.Home.RelPermalink }}">...</a>

.Sites.First

​ 返回第一种语言的站点。如果这不是多语言设置,则会返回它本身。

.Summary

​ 此内容的生成摘要,用于在摘要视图中轻松显示片段。可以在内容页中适当位置插入 `

` 来手动设置断点,或者可以独立于页面文本编写摘要。有关详细信息,请参阅 内容摘要

.TableOfContents

​ 此页面的渲染 目录

.Title

​ 此页面的标题。

.Translations

​ 当前页面的翻译版本列表。有关更多信息,请参阅 多语言模式

.TranslationKey

​ 用于映射当前页面的语言翻译的key。有关更多信息,请参阅 多语言模式

.Truncated

​ 一个布尔值,如果 .Summary 被截断,则为 true。仅在必要时显示"Read more…“链接很有用。有关详细信息,请参阅 摘要

.Type

​ 此内容的 内容类型(例如 posts)。

.Weight

​ 分配给此内容的权重(在前置元数据中),用于排序。

.WordCount

​ 此内容中的字数。

可写的页面范围变量

.Scratch

  • .Scratch

    返回一个 Scratch 来存储和操作数据。与 .Store 方法相比,此 Scratch 在服务器重新构建时会被重置。

.Store

  • .Store

    返回一个 Scratch 来存储和操作数据。与 .Scratch 方法相比,此 Scratch 在服务器重新构建时不会被重置。

章节变量和方法

​ 另请参见章节

.CurrentSection

​ 此页面的当前章节。如果它是一个章节或主页,则该值可以是页面本身。

.FirstSection

​ 此页面根目录下的第一个章节,例如 /docs/blog 等等。

.InSection $anotherPage

​ 给定页面是否在当前章节中。

.IsAncestor $anotherPage

​ 当前页面是否是给定页面的祖先页面。

.IsDescendant $anotherPage

​ 当前页面是否是给定页面的后代页面。

.Parent

​ 章节的父级章节或页面所属的章节。

.Section

​ 此内容所属的章节注意: 对于嵌套章节,这是目录中的第一个路径元素,例如 /blog/funny/mypost/ => blog

.Sections

​ 此内容下的章节

.Pages变量

.Pages.Data.Pages 的别名。惯例是使用别名形式 .Pages

.Pages.Site.Pages的比较

  • 常规页面是"post"页面或"content"页面。

    • 叶子bundle是常规页面。
  • 列表页面可以列出常规页面和其他列表页面。一些例子是:主页、章节页面、分类法(/tags/)和条目(/tags/foo/)页面。

    • 分支bundle是一个列表页面。
  • .Site.Pages

    站点中所有页面的集合:常规页面、章节、分类法等等。——Superset of everything!

  • .Site.RegularPages

    仅包含常规页面的集合。

​ 上述.Site. ..页面集合可以从模板的任何作用域中访问。

​ 以下变量仅从当前列表页的作用域返回页面集合:

  • .Pages

    Collection of regular pages and only first-level section pages under the current list page.

    在当前列表页面下,包含所有常规页面和只有一级章节页面的集合。

  • .RegularPages

    仅包括当前列表页面下的常规页面的集合。这不包括嵌套章节/列表页面中的常规页面(那些是带有 _index.md 文件的子目录)。

  • .RegularPagesRecursive

    包含一个列表页面下的所有普通页面的集合。这包括嵌套章节/列表页面中的常规页面。

    注意

    常规页面的作用域来看,.Pages.RegularPages 返回一个空的 slice。

Page Fragments 页面片段

New in v0.111.0

.Fragments 方法返回当前页面的片段列表。

.Headings

​ 当前页面的递归标题列表。可用于生成目录。

.Identifiers

​ 当前页面的标识符的排序列表。可用于检查页面是否包含特定标识符或页面是否包含重复标识符:

1
2
3
4
5
6
7
{{ if .Fragments.Identifiers.Contains "my-identifier" }}
    <p>Page contains identifier "my-identifier"</p>
{{ end }}

{{ if gt (.Fragments.Identifiers.Count "my-identifier")  1 }}
    <p>Page contains duplicate "my-identifier" fragments</p>
{{ end }}

.HeadingsMap

​ 保存了当前页面的一个标题映射。可用于从特定标题开始生成目录。

​ 还请参阅 Go Doc 获取返回类型的信息。

hooks和简码中的Fragments

.Fragments 可以在渲染钩子中安全调用,即使在当前页面(.Page.Fragments)上也可以。对于简码,我们建议所有 .Fragments 的用法都嵌套在 \{\{\<\>\}\} 简码定界符内(\{\{\%\%\}\} 参与 ToC 的创建,所以很容易陷入一种咬尾巴的情况)。

全局页面函数

New in v0.111.1

​ Hugo 几乎总是将 Page 作为数据上下文传递到顶层模板(例如 single.html)中(唯一的例外是多主机(multihost )站点地图模板)。这意味着您可以在模板中使用 . 变量访问当前页面。

​ 但是,在 .Render,partial 等嵌套较深的情况下,访问该 Page 对象并不总是实用或可能的。

​ 因此,Hugo 提供了一个全局的 page 函数,您可以使用它从任何模板中的任何位置访问当前页面。

1
{{ page.Title }}

​ 这里有一个需要注意的地方,这并不是新问题,但是值得在这里提一下:在 Hugo 中,您可能会看到缓存值的情况,例如在 partialCached 或简码中时。

Page-level Params

​ 在内容文件中定义的任何其他值,包括分类法,都将作为 .Params 变量的一部分提供。

content/example.md

=== “yaml”

``` yaml
---
categories:
- one
tags:
- two
- three
- four
title: Example
---
```

=== “toml”

``` toml
+++
categories = ['one']
tags = ['two', 'three', 'four']
title = 'Example'
+++
```

=== “json”

``` json
{
   "categories": [
      "one"
   ],
   "tags": [
      "two",
      "three",
      "four"
   ],
   "title": "Example"
}
```

​ 使用上面的前置元数据,可以通过以下方式访问 tagscategories 分类法:

  • .Params.tags
  • .Params.categories

.Params 变量对于在内容文件中引入用户定义的前置元数据字段特别有用。例如,针对图书评论的 Hugo 站点可以具有以下前置元数据:

content/example.md

=== “yaml”

``` yaml
---
affiliatelink: http://www.my-book-link.here
recommendedby: My Mother
title: Example
---
```

=== “toml”

``` toml
+++
affiliatelink = 'http://www.my-book-link.here'
recommendedby = 'My Mother'
title = 'Example'
+++
```

=== “json”

``` json
{
   "affiliatelink": "http://www.my-book-link.here",
   "recommendedby": "My Mother",
   "title": "Example"
}
```

​ 然后可以通过 .Params.affiliatelink.Params.recommendedby 访问这些字段。

1
2
<h3><a href="{{ .Params.affiliatelink }}">Buy this book</a></h3>
<p>It was recommended by {{ .Params.recommendedby }}.</p>

​ 该模板将被渲染成如下:

1
2
<h3><a href="http://www.my-book-link.here">Buy this book</a></h3>
<p>It was recommended by my Mother.</p>

​ 有关在每篇内容之间保持 Params 的一致性,请参见 Archetypes

.Param方法

​ 在 Hugo 中,您可以针对个别页面和整个站点全局声明参数。一个常见的用例是为站点参数设置一个通用值,为一些页面设置更具体的值(例如,头像图片):

1
{{ $.Param "header_image" }}

.Param 方法提供了一种解析单个值的方式,根据它在页面参数(即内容的前置条件)或站点参数(即您的 config)中的定义。

访问前置元数据中的嵌套字段

​ 当前置元数据包含类似以下的嵌套字段时:

content/example.md

=== “yaml”

` yaml
---
author:
  display_name: John Feminella
  family_name: Feminella
  given_name: John
title: Example
---
```

=== “toml”

``` toml
+++
title = 'Example'
[author]
  display_name = 'John Feminella'
  family_name = 'Feminella'
  given_name = 'John'
+++
```

=== “json”

``` json
{
   "author": {
      "display_name": "John Feminella",
      "family_name": "Feminella",
      "given_name": "John"
   },
   "title": "Example"
}
```

.Param 可以通过连接字段名称并用点号分隔来访问这些字段:

1
{{ $.Param "author.display_name" }}

另请参阅

8.3 - 简码变量

Shortcode Variables- 简码变量

https://gohugo.io/variables/shortcodes/

​ 简码可以访问页面变量,并且有其自己的特定内置变量。

简码通过.Get访问简码声明中分隔的参数、页面级别和站点级别的变量,还可以访问以下简码特定字段:

.Name

​ 简码名称。

.Ordinal

​ 与其父简码相对位置的零基序数。如果父简码是页面本身,则该序数将表示页面内容中此简码的位置。

.Page

​ The owning ´Page`.

​ 拥有此简码的页面。

.Parent

​ 为嵌套简码提供访问父简码上下文的能力。这对于从根继承常见简码参数非常有用。

.Position

​ Contains filename and position for the shortcode in a page. Note that this can be relatively expensive to calculate, and is meant for error reporting. See Error Handling in Shortcodes.

​ 包含页面中此简码的文件名和位置。请注意,这可能是相对昂贵的计算,并且是用于错误报告的。请参见简码错误处理

.IsNamedParams

​ 返回布尔值,当涉及的简码使用命名参数而不是位置参数时返回true

.Inner

​ represents the content between the opening and closing shortcode tags when a closing shortcode is used

​ 表示在使用关闭简码时开放和关闭简码标记之间的内容。

.Scratch

​ 返回一个可写的Scratch,以存储和操作将附加到此简码上下文的数据。此 Scratch 在服务器重新构建时会被重置。

.InnerDeindent New in v0.100.0

​ 获取任何缩进已删除的.Inner。这是内置的\{\{\< highlight \>\}\}简码中使用的内容。

另请参阅

8.4 - 页面方法

Pages Methods - 页面方法

https://gohugo.io/variables/pages/

​ Pages是Hugo中的核心页面集合,具有许多有用的方法。

​ 此外,请参阅列表模板以获取排序方法的概述。

.Next PAGE

​ 在Pages上的.Next.Prev与在.Page上具有相同名称的方法类似,但更加灵活(并且略微慢一些),因为它们可以用于任何页面集合。

.Next指向与作为参数发送的页面相对的下一个页面。例如:{{ with .Site.RegularPages.Next . }}{{ .RelPermalink }}{{ end }}。对集合中的第一个页面调用.Next将返回nil

.Prev PAGE

.Prev指向与作为参数发送的页面相对的上一个页面。例如:{{ with .Site.RegularPages.Prev . }}{{ .RelPermalink }}{{ end }}。对集合中的最后一个页面调用.Prev将返回nil

另请参阅

8.5 - 分类法(Taxonomy)变量

Taxonomy Variables - 分类法(Taxonomy)变量

https://gohugo.io/variables/taxonomy/

​ Hugo 的分类法系统向分类法和条目模板公开了变量。

分类模板

​ 由分类法模板渲染的页面的 .Kind 设置为 taxonomy.Type 设置为分类法名称。

​ 在分类法模板中,您可以访问 .Site.Page.Section.File 变量,以及以下分类法变量:

.Data.Singular

​ 分类法的单数形式名称(例如, tags => tag)。

.Data.Plural

​ 分类法的复数形式名称(例如, tags => tags)。

.Data.Pages

​ 与此分类法相关的条目页面集合。别名为 .Pages

.Data.Terms

​ 一个与此分类法相关的条目和加权页面的映射。

.Data.Terms.Alphabetical

​ 一个与此分类法相关的条目和加权页面的映射,按字母顺序升序排序。使用 .Data.Terms.Alphabetical.Reverse 可以反转排序顺序。

.Data.Terms.ByCount

​ 一个与此分类法相关的条目和加权页面的映射,按计数升序排序。使用 .Data.Terms.ByCount.Reverse 可以反转排序顺序。

Term templates

​ 由条目模板渲染的页面的 .Kind 设置为 term.Type 设置为分类法名称。

In term templates you may access .Site, .Page. .Section, and .File variables, as well as the following term variables:

在分类项模板中,您可以访问 .Site、.Page、.Section 和 .File 变量,以及以下分类项变量:

​ 在分类法条目模板中,您可以访问 .Site.Page.Section.File 变量,以及以下条目变量:

.Data.Singular

​ 分类法的单数形式名称(例如 tags => tag)。

.Data.Plural

​ 分类法的复数形式名称(例如 tags => tags)。

.Data.Pages

​ 与此条目相关的内容页面集合。别名为 .Pages

.Data.Term

​ 条目本身(例如, tag-one)。

从任何模板访问分类法数据

​ 从任何模板中访问整个分类法数据结构,使用 site.Taxonomies。这将返回一个包含分类法、条目和与每个条目相关的加权内容页面集合的映射。例如:

 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
34
{
  "categories": {
    "news": [
      {
        "Weight": 0,
        "Page": {
          "Title": "Post 1",
          "Date": "2022-12-18T15:13:35-08:00"
          ...
          }
      },
      {
        "Weight": 0,
        "Page": {
          "Title": "Post 2",
          "Date": "2022-12-18T15:13:46-08:00",
          ...
        }
      }
    ]
  },
  "tags": {
    "international": [
      {
        "Weight": 0,
        "Page": {
          "Title": "Post 1",
          "Date": "2021-01-01T00:00:00Z"
          ... 
        }
      }
    ]
  }
}

Access a subset of the taxonomy data structure by chaining one or more identifiers, or by using the index function with one or more keys. For example, to access the collection of weighted content pages related to the news category, use either of the following:

​ 通过链接一个或多个标识符,或使用 index 函数加上一个或多个键,可以访问分类法数据结构的子集。例如,要访问与新闻类别相关的加权内容页面集合,请使用以下任一方法:

1
2
{{ $pages := site.Taxonomies.categories.news }}
{{ $pages := index site.Taxonomies "categories" "news" }}

​ 例如,将整个分类法数据结构渲染为嵌套的无序列表:

 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
<ul>
  {{ range $taxonomy, $terms := site.Taxonomies }}
    <li>
      {{ with site.GetPage $taxonomy }}
        <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
      {{ end }}
      <ul>
        {{ range $term, $weightedPages := $terms }}
        <li>
          {{ with site.GetPage (path.Join $taxonomy $term) }}
            <a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a>
          {{ end }}
        </li>
          <ul>
            {{ range $weightedPages }}
              <li>
                <a href="{{ .RelPermalink }}"> {{ .LinkTitle }}</a>
              </li>
            {{ end }}
          </ul>
        {{ end }}
      </ul>
    </li>
  {{ end }}
</ul>

​ 有关更多示例,请参见分类法模板

8.6 - 菜单变量

Menu Variables - 菜单变量

https://gohugo.io/variables/menus/

​ 在您的菜单模板中使用这些变量和方法。

变量

​ 在定义菜单项之后,可以在菜单模板中使用以下变量访问其属性。

.Children

​ (menu)当前菜单项下(如果有)的子菜单项的集合。

.Identifier

(string) 菜单项的 identifier 属性。如果您自动定义菜单项,则为页面的 .Section

.KeyName

(string) 菜单项的 identifier 属性,否则为 name 属性。

​ (string) 包含菜单项的菜单的标识符。

.Name

​ (string) 菜单项的 name 属性。

  • 如果您自动定义菜单项,则为页面的 .LinkTitle,否则为 .Title

  • 如果您在前置元数据站点配置中定义菜单,则先尝试使用页面的 .LinkTitle,然后使用.Title

.Page

​ (page) 与菜单项相关联的页面的引用。

.Params

​ (map) 菜单项的 params 属性。

.Parent

​ (string) 菜单项的 parent 属性。

.Post

(template.HTML) 菜单项的 post 属性。

.Pre

​ (template.HTML) 菜单项的 pre 属性。

.Title

​ (string) 菜单项的 title 属性。

  • 如果您自动定义菜单项,则为页面的 .LinkTitle,否则为 .Title

  • 如果您在前置元数据站点配置中定义菜单,则先尝试使用页面的 .LinkTitle,然后使用 .Title

.URL

​ (string) 与菜单项相关联的页面的 .RelPermalink。对于指向外部资源的菜单项,使用菜单项的 url 属性。

.Weight

​ (int) 菜单项的 weight 属性。

方法

.HasChildren

​ (bool) 如果 .Children 非 nil,则返回 true

.IsEqual

​ (bool) 如果比较的菜单项表示相同的菜单项,则返回 true

.IsSameResource

​ (bool) 如果比较的菜单条目指向同一资源,则返回true

.Page.HasMenuCurrent

​ (bool) 使用此方法确定活动菜单项的祖先。请参阅详细信息

.Page.IsMenuCurrent

​ (bool) 使用此方法确定活动菜单项。请参阅详细信息

另请参阅

8.7 - 文件变量

File Variables - 文件变量

https://gohugo.io/variables/files/

Use File variables to access file-related values for each page that is backed by a file.

使用文件变量来访问由文件支持的每个页面的与文件相关的值。

​ 使用文件变量来访问每个由文件支持的页面的与文件相关的值。

变量

.File.Path.File.Dir.File.Filename 中的路径分隔符(斜杠或反斜杠)取决于操作系统。

.File.Path

​ (string) 文件路径,相对于 content 目录。

.File.Dir

​ (string) 不包括文件名的文件路径,相对于 content 目录。

.File.LogicalName

​ (string) 文件名。

.File.BaseFileName

​ (string) 不包括扩展名的文件名。

.File.TranslationBaseName

​ (string) 不包括扩展名和语言标识符的文件名。

.File.Ext

​ (string) 文件扩展名。

.File.Lang

​ (string) 与给定文件相关联的语言。

.File.ContentBaseName

​ (string) 如果页面是一个分支或叶子 bundle,则为包含该页面的目录名称,否则为 .TranslationBaseName

.File.Filename

​ (string) 绝对文件路径。

.File.UniqueID

​ (string) .File.Path 的 MD5 哈希值。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
content/
├── news/
│   ├── b/
│   │   ├── index.de.md   <-- leaf bundle
│   │   └── index.en.md   <-- leaf bundle
│   ├── a.de.md           <-- regular content
│   ├── a.en.md           <-- regular content
│   ├── _index.de.md      <-- branch bundle
│   └── _index.en.md      <-- branch bundle
├── _index.de.md
└── _index.en.md

​ 使用上述内容结构,英文页面的 .File 对象包含以下属性:

regular contentleaf bundlebranch bundle
Pathnews/a.en.mdnews/b/index.en.mdnews/_index.en.md
Dirnews/news/b/news/
LogicalNamea.en.mdindex.en.md_index.en.md
BaseFileNamea.enindex.en_index.en
TranslationBaseNameaindex_index
Extmdmdmd
Langenenen
ContentBaseabnews
Filename/home/user/…/home/user/…/home/user/…
UniqueID15be14b…186868f…7d9159d…

防御性编程

​ 站点上的某些页面可能没有文件支持。例如:

  • 顶级章节页面
  • 分类法页面
  • 条目页面

​ 如果您尝试访问 .File 属性而没有支持文件,Hugo 将抛出一个警告。例如:

1
WARN .File.ContentBaseName on zero object. Wrap it in if or with...

​ 为了防御性编程:

1
2
3
{{ with .File }}
  {{ .ContentBaseName }}
{{ end }}

另请参阅

8.8 - Git 信息变量

Git Info Variables - Git 信息变量

https://gohugo.io/variables/git/

​ 获取每个内容文件的最后一次 Git 修订信息。

​ Hugo 的 Git 集成应该是相当高效的,但可能会增加构建时间。这取决于您的 Git 历史记录大小。

.GitInfo 先决条件

  1. Hugo 站点必须位于启用 Git 的目录中。
  2. Git 可执行文件必须已安装并在系统 PATH 中。
  3. 必须在 Hugo 项目中启用 .GitInfo 功能,方法是在命令行上传递 --enableGitInfo 标志或在 站点配置文件 中将 enableGitInfo 设置为 true

.GitInfo 对象

GitInfo 对象包含以下字段:

.AbbreviatedHash

​ 缩写的提交哈希(例如 866cbcc

.AuthorName

​ 作者名称,遵循 .mailmap

.AuthorEmail

​ 作者电子邮件地址,遵循 .mailmap

.AuthorDate

​ 作者日期。

.Hash

​ 提交哈希(例如 866cbccdab588b9908887ffd3b4f2667e94090c3

.Subject

​ 提交消息主题(例如, tpl: Add custom index function

.Lastmod

​ 如果启用了 .GitInfo 功能,则 .Lastmod(在 Page 上)从 Git 中获取,即 .GitInfo.AuthorDate。可以通过添加自己的 日期的前置元数据配置 更改此行为。

另请参阅

8.9 - Sitemap变量

Sitemap Variables - Sitemap变量

https://gohugo.io/variables/sitemap/

​ sitemap是一个 Page ,因此具有可用于sitemap模板的所有页面变量。 它们还具有以下专门用于sitemap的变量:

.Sitemap.ChangeFreq

​ 页面更改频率

.Sitemap.Priority

​ 页面的优先级

.Sitemap.Filename

​ Sitemap文件名

另请参阅

9 - Hugo Pipes

Hugo Pipes Overview

https://gohugo.io/hugo-pipes/

9.1 - Hugo Pipes 简介

Hugo Pipes Introduction - Hugo Pipes 简介

https://gohugo.io/hugo-pipes/introduction/

​ Hugo Pipes 是 Hugo 的asset 处理函数集合。

在 /assets 中查找资源

​ 这是关于全局资源(global Resources),它们在 /assets 内部挂载。有关 .Page 作用域内的资源,请参见 Page Resources

​ 请注意,您可以使用 Mount Configuration 将任何目录挂载到 Hugo 的虚拟 assets 文件夹中。

函数描述
resources.GetGet 会查找在 Hugo assets 文件系统中给定的文件名,并创建一个可用于进一步转换的 Resource 对象。请参见 使用 resources.Get 和 resources.GetRemote 获取资源
resources.GetRemoteGet 相同,但它接受远程 URL。请参见 使用 resources.Get 和 resources.GetRemote 获取资源
resources.GetMatchGetMatch 查找第一个与给定模式匹配的资源,如果没有找到,则返回 nil。有关使用的规则的更完整解释,请参见 Match。
resources.MatchMatch 获取与给定基本路径前缀匹配的所有资源,例如 “.png” 将匹配所有 png 文件。 “” 不匹配路径分隔符 (/),因此,如果您将资源组织在子文件夹中,则需要明确指定,例如:“images/*.png”。要匹配包中任何 PNG 图像,您可以使用 “.png”,要匹配 images 文件夹下所有 PNG 图像,请使用 “images/.jpg”。匹配区分大小写。Match 通过使用相对于文件系统根的路径的文件名来匹配,路径使用 Unix 样式斜杠 (/),没有前导斜杠,例如 “images/logo.png”。有关完整规则集,请参见 https://github.com/gobwas/glob

​ 有关此命名空间中所有模板函数的最新概述,请参见 GoDoc Page

使用 resources.Get 和 resources.GetRemote 获取资源

​ 为了使用 Hugo Pipes 处理资源,必须使用 resources.Getresources.GetRemote 获取它作为一个 Resource

​ 对于 resources.Get,第一个参数是相对于 assets 目录/目录的本地路径:

1
{{ $local := resources.Get "sass/main.scss" }}

​ 对于 resources.GetRemote,第一个参数是远程 URL:

1
{{ $remote := resources.GetRemote "https://www.example.com/styles.scss" }}

resources.Get and resources.GetRemote return nil if the resource is not found.

resources.Getresources.GetRemote 如果找不到资源则返回 nil

新版本v0.110.0您可以使用返回的 Resource 中的 .Data 获取有关HTTP响应的信息。这对于没有任何正文的HEAD请求特别有用。数据对象包含:

  • StatusCode

    HTTP状态代码,例如200状态

    HTTP状态文本,例如"200 OK" TransferEncoding

    传输编码,例如"chunked" ContentLength

    内容长度,例如1234 ContentType

    内容类型,例如"text/html"

缓存

​ 默认情况下,Hugo基于给定的 URLoptions (例如,标题)计算缓存键。

新版本v0.97.0您可以通过在选项映射中设置 key 来覆盖此设置。这可用于更精细地控制远程资源的获取频率,例如:

1
2
{{ $cacheKey := print $url (now.Format "2006-01-02") }}
{{ $resource := resource.GetRemote $url (dict "key" $cacheKey) }}

错误处理

​ 从 resources.GetRemote 返回的返回值包括一个 .Err 方法,如果调用失败,则会返回错误。如果您只想将任何错误记录为 WARNING ,则可以使用类似于下面的结构。

1
2
3
4
5
6
7
{{ with resources.GetRemote "https://gohugo.io/images/gohugoio-card-1.png" }}
  {{ with .Err }}
    {{ warnf "%s" . }}
  {{ else }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
  {{ end }}
{{ end }}

​ 请注意,如果您不自己处理 .Err ,Hugo将在您开始使用 Resource 对象的第一次构建时失败。

远程选项

​ 在获取远程 Resource 时, resources.GetRemote 接收一个可选的选项映射作为第二个参数,例如:

1
{{ $resource := resources.GetRemote "https://example.org/api" (dict "headers" (dict "Authorization" "Bearer abcd")) }}

​ 如果您需要同一头键的多个值,请使用切片:

1
{{ $resource := resources.GetRemote "https://example.org/api"  (dict "headers" (dict "X-List" (slice "a" "b" "c"))) }}

​ 您还可以更改请求方法并设置请求正文:

1
2
3
4
5
6
7
{{ $postResponse := resources.GetRemote "https://example.org/api"  (dict 
    "method" "post"
    "body" `{"complete": true}` 
    "headers" (dict 
        "Content-Type" "application/json"
    )
)}}

远程资源的缓存

​ 使用 resources.GetRemote 获取的远程资源将缓存在磁盘上。有关详情,请参见配置文件缓存

复制资源

New in v0.100.0

resources.Copy 使您可以复制几乎任何Hugo Resource(唯一的例外是Page),可能最有用的是重命名:

1
2
{{ $resized := $image.Resize "400x400" |  resources.Copy "images/mynewname.jpg" }}
<img src="{{ $resized.RelPermalink }}">

Asset 目录

​ asset 文件必须存储在asset 目录中。默认为 /assets ,但可以通过配置文件的 assetDir 键进行配置。

Asset 发布

​ 当您调用 .Permalink.RelPermalink.Publish 时,Hugo将assets 发布到 publishDir (通常为 public )。您可以使用 .Content 来内联assets 。

Go 管道

​ 为了提高可读性,本文档的Hugo Pipes示例将使用Go Pipes编写:

1
2
{{ $style := resources.Get "sass/main.scss" | resources.ToCSS | resources.Minify | resources.Fingerprint }}
<link rel="stylesheet" href="{{ $style.Permalink }}">

方法别名

​ 每个 Hugo Pipes 的 resources 转换方法都使用 驼峰式 别名(例如 resources.ToCSS 的别名是 toCSS)。没有这样别名的非转换方法包括 resources.Getresources.FromStringresources.ExecuteAsTemplateresources.Concat

​ 因此,上面的示例也可以写成以下形式:

1
2
{{ $style := resources.Get "sass/main.scss" | toCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $style.Permalink }}">

缓存

​ Hugo 管道调用基于整个管道链进行缓存。

​ 一个管道链的示例是:

1
{{ $mainJs := resources.Get "js/main.js" | js.Build "main.js" | minify | fingerprint }}

​ 管道链仅在站点构建中第一次遇到时调用,否则结果将从缓存中加载。因此,Hugo 管道可以在执行数千或数百万次的模板中使用,而不会对构建性能产生负面影响。

9.2 - Babel

Babel

https://gohugo.io/hugo-pipes/babel/

​ Hugo Pipes 可以使用 Babel 处理 JS 文件。

语法

resources.Babel RESOURCE [OPTIONS]
babel RESOURCE [OPTIONS]

用法

​ 使用 resources.Babel 将任何 JavaScript 资源文件转译为另一种 JavaScript 版本,它接受资源对象和下面列出的可选选项字典作为参数。Babel 使用 babel cli

​ Hugo Pipe 的 Babel 需要安装 @babel/cli@babel/core JavaScript 包在项目中或全局安装 (npm install -g @babel/cli @babel/core),以及使用的任何 Babel 插件或预设 (例如,npm install @babel/preset-env --save-dev)。

​ 如果您使用的是 Hugo Snap 包,则 Babel 和插件需要在您的 Hugo 站点目录中本地安装,例如,不带 -g 标志的 npm install @babel/cli @babel/core --save-dev

配置

​ 当运行 Babel 和类似工具时,我们会将主项目的 node_modules 添加到 NODE_PATH。在这个领域,Babel 存在一些已知问题,因此如果您的 babel.config.js 存在于 Hugo 模块中(而不是项目本身),我们建议使用 require 来加载预设/插件,例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
module.exports = {
  presets: [
    [
      require("@babel/preset-env"),
      {
        useBuiltIns: "entry",
        corejs: 3,
      },
    ],
  ],
};

选项

  • config [string]

    ​ Babel 配置文件的路径。Hugo 默认会在项目中查找 babel.config.js 文件。有关这些配置文件的更多信息,请参见:babel 配置

  • minified [bool]

    Save as many bytes as possible when printing

    在打印时尽可能节省字节。

  • noComments [bool]

    将注释写入生成的输出中(默认为 true)。

  • compact [bool]

    不包括多余的空格字符和行终止符。如果未设置,默认值为auto

  • verbose [bool]

    记录所有日志。

  • sourceMap [string]

    从 Babel 编译输出 inlineexternal sourcemap。外部 sourcemap 将写入目标文件名后带有 “.map” 的目标中。输入 sourcemap 可以从 js.Build 和节点模块中读取,并合并到输出 sourcemap 中。

示例

1
{{- $transpiled := resources.Get "scripts/main.js" | babel  -}}

或使用选项:

1
2
{{ $opts := dict "noComments" true }}
{{- $transpiled := resources.Get "scripts/main.js" | babel $opts -}}

另请参阅

9.3 - Concat

Concat

https://gohugo.io/hugo-pipes/bundling/

​ 将任意数量的assets捆绑成一个资源。

语法

resources.Concat TARGET_PATH SLICE_RESOURCES

用法

​ 相同 MIME 类型的asset文件可以使用 resources.Concat 捆绑成一个资源,该函数需要两个参数,分别为创建资源捆绑的目标路径和要连接的资源对象的切片。

1
2
3
{{ $plugins := resources.Get "js/plugins.js" }}
{{ $global := resources.Get "js/global.js" }}
{{ $js := slice $plugins $global | resources.Concat "js/bundle.js" }}

另请参阅

9.4 - ExecuteAsTemplate

ExecuteAsTemplate

https://gohugo.io/hugo-pipes/resource-from-template/

​ 从模板创建资源。

语法

resources.ExecuteAsTemplate TARGET_PATH CONTEXT RESOURCE

用法

​ 为了在包含 Go 模板的一个asset 文件上使用 Hugo Pipes 函数,必须使用 resources.ExecuteAsTemplate 函数。

​ 该函数需要三个参数:创建资源的目标路径、模板上下文和资源对象。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// assets/sass/template.scss
$backgroundColor: {{ .Param "backgroundColor" }};
$textColor: {{ .Param "textColor" }};
body{
  background-color:$backgroundColor;
  color: $textColor;
}
// [...]
{{ $sassTemplate := resources.Get "sass/template.scss" }}
{{ $style := $sassTemplate | resources.ExecuteAsTemplate "main.scss" . | resources.ToCSS }}

另请参阅

9.5 - Fingerprint

Fingerprint

https://gohugo.io/hugo-pipes/fingerprint/

对给定的资源进行处理,添加资源内容的哈希字符串。  

语法

resources.Fingerprint RESOURCE [ALGORITHM]
fingerprint RESOURCE [ALGORITHM]

用法

可以使用  `resources.Fingerprint`  对任何asset文件应用Fingerprinting和 [SRI](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity),该函数需要两个参数,分别为资源对象和一个可选的 [哈希算法](https://en.wikipedia.org/wiki/Secure_Hash_Algorithms)。 

​ 默认哈希算法为 sha256 ,其他可用算法为 sha384sha512 (自 Hugo 0.55 起),以及 md5

​ 经过处理的任何asset文件都将带有一个 .Data.Integrity 属性,其中包含由哈希算法名称、一个连字号(hyphen )和 base64 编码的哈希值组成的完整性字符串。

1
2
3
{{ $js := resources.Get "js/global.js" }}
{{ $secureJS := $js | resources.Fingerprint "sha512" }}
<script src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}"></script>

另请参阅

9.6 - FromString

FromString

https://gohugo.io/hugo-pipes/resource-from-string/

​ 从字符串创建资源。

语法

resources.FromString TARGET_PATH CONTENT

用法

​ 可以使用 resources.FromString 直接从模板创建资源,该函数需要两个参数,即要创建资源的目标路径和给定的内容字符串。

​ 下面的示例创建一个包含每个项目语言的本地化变量的资源文件。

1
2
3
4
5
6
7
{{ $string := (printf "var rootURL = '%s'; var apiURL = '%s';" (absURL "/") (.Param "API_URL")) }}
{{ $targetPath := "js/vars.js" }}
{{ $vars := $string | resources.FromString $targetPath }}
{{ $global := resources.Get "js/global.js" | resources.Minify }}

<script src="{{ $vars.Permalink }}"></script>
<script src="{{ $global.Permalink }}"></script>

另请参阅

9.7 - js.Build

js.Build

https://gohugo.io/hugo-pipes/js/

​ 使用 ESBuild 处理一个 JavaScript 文件。

语法

js.Build RESOURCE [OPTIONS]

用法

​ 任何 JavaScript 资源文件都可以使用 js.Build 进行转换和 “tree shaken”,其参数可以是文件路径的字符串,也可以是下面列出的选项字典。

选项

  • targetPath [string]

    如果未设置,则使用源路径作为基本目标路径。请注意,如果目标 MIME 类型不同,目标路径的扩展名可能会更改,例如,当源是 TypeScript 时。

  • params [map or slice]

    可以在 JS 文件中作为 JSON 导入的参数,例如:

1
{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}

​ 然后在您的 JS 文件中:

1
import * as params from '@params';

​ 请注意,这适用于小型数据集,例如配置设置。对于较大的数据,请将文件放置/挂载到 /assets 中并直接导入它们。

  • minify [bool]

    js.Build 处理最小化。

  • inject [slice]

    此选项允许您自动将另一个文件中的导入替换为全局变量。路径名必须相对于 assets 。 参考 https://esbuild.github.io/api/#inject

  • shims [map]

    此选项允许将一个组件替换为另一个组件。常见的用例是在生产环境中从 CDN(带有shims)加载依赖项(如 React),但在开发期间使用完全捆绑的 node_modules 依赖项:

1
2
{{ $shims := dict "react" "js/shims/react.js"  "react-dom" "js/shims/react-dom.js" }}
{{ $js = $js | js.Build dict "shims" $shims }}

​ 这些 shim 文件可能是这样的:

1
2
3
4
// js/shims/react.js
module.exports = window.React;
// js/shims/react-dom.js
module.exports = window.ReactDOM;

​ 使用上述方法,以下导入应该在两种情况下都能正常工作:

1
2
import * as React from 'react'
import * as ReactDOM from 'react-dom';
  • target [string]

    语言目标。可选值为: es5es2015es2016es2017es2018es2019es2020esnext 。 默认为 esnext

  • externals [slice]

    外部依赖项。使用此选项来修剪您知道永远不会执行的依赖项。 参考https://esbuild.github.io/api/#external

  • defines [map]

    允许定义(在构建时执行)一组字符串替换。应该是一个 map,其中每个键都将被其值替换。

1
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}
  • format [string]

    输出格式。可选值为: iifecjsesm 。默认为 iife ,一个适合作为标签(tag)包含的自执行函数。

  • sourceMap [string]

    是否从 esbuild 生成 inlineexternal 源映射。外部源映射将写入目标输出文件名 + “.map”。输入源映射可以从 js.Build 和节点模块中读取并合并到输出源映射中。默认情况下,不创建源映射。

从 /assets 导入 JS 代码

js.Build 完全支持 Hugo Modules 中的虚拟并联文件系统。您可以在这个 测试项目 中看到一些简单的示例,但简而言之,您可以这样做:

1
import { hello } from 'my/module';

​ 它将解析为分层文件系统中assets/my/module下最顶层的 index.{js,ts,tsx,jsx} 文件。

1
import { hello3 } from 'my/module/hello3';

​ 将解析为 assets/my/module 中的 hello3.{js,ts,tsx,jsx}

​ 任何以 . 开头的导入都将相对于当前文件进行解析:

1
import { hello4 } from './lib';

​ 对于其他文件(例如 JSONCSS),您需要使用包括任何扩展名在内的相对路径,例如:

1
import * as data from 'my/module/data.json';

​ 在位于 /assets 之外或不能解析为 /assets 内组件的文件中的任何导入都将由 ESBuild 解析,并将 项目目录 作为解析目录(用作查找 node_modules 等的起始点)。另请参见hugo mod npm pack。如果在项目中导入了任何 npm 依赖项,则需要在运行 hugo 之前确保运行 npm install

​ 此外,请注意新的 params 选项,它可以从模板传递到您的 JS 文件中,例如:

1
{{ $js := resources.Get "js/main.js" | js.Build (dict "params" (dict "api" "https://example.org/api")) }}

​ 然后在您的 JS 文件中:

1
import * as params from '@params';

​ Hugo 默认会生成一个 assets/jsconfig.json 文件来映射导入。这对于代码编辑器中的导航/智能感知帮助很有用,但是如果您不需要/不想要它,您可以 关闭它

将依赖项包含在 package.json / node_modules 中

​ 在位于 /assets 之外或不能解析为 /assets 内组件的文件中的任何导入都将由 ESBuild 解析,并将 项目目录 作为解析目录(用作查找 node_modules 等的起始点)。另请参见hugo mod npm pack。如果在项目中导入了任何 npm 依赖项,则需要在运行 hugo 之前确保运行 npm install

​ 解析 npm 包(即位于 node_modules 文件夹中的包)的起始目录始终是主项目文件夹。

**注意:**如果您正在开发应该被导入并且依赖于 package.json 内的依赖项的主题/组件,我们建议了解 hugo mod npm pack,这是一种将项目中所有 npm 依赖项合并的工具。

示例

1
{{ $built := resources.Get "js/index.js" | js.Build "main.js" }}

或者带有选项:

1
2
3
4
5
6
{{ $externals := slice "react" "react-dom" }}
{{ $defines := dict "process.env.NODE_ENV" `"development"` }}

{{ $opts := dict "targetPath" "main.js" "externals" $externals "defines" $defines }}
{{ $built := resources.Get "scripts/main.js" | js.Build $opts }}
<script src="{{ $built.RelPermalink }}" defer></script>

另请参阅

9.8 - PostCSS

PostCSS

https://gohugo.io/hugo-pipes/postcss/

​ 使用任何可用的插件,使用PostCSS处理CSS文件。

语法

resources.PostCSS RESOURCE [OPTIONS]
postCSS RESOURCE [OPTIONS]

设置

​ 按照以下步骤使用任何可用的PostCSS插件来转换CSS。

  • Step 1

    安装 Node.js.

  • Step 2

    在项目的根目录中安装所需的Node.js包。例如,添加vendor 前缀到CSS规则:

1
npm install postcss postcss-cli autoprefixer
  • Step 3

    在项目的根目录中创建PostCSS配置文件。您必须将此文件命名为 postcss.config.js 或其他supported file names之一。例如:

postcss.config.js

1
2
3
4
5
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
};

​ 如果您是Windows用户,且项目路径包含空格,则必须将PostCSS配置放置在package.json文件中。参见此示例和问题#7333

  • Step 4

    将CSS文件放置在 assets 目录中。

  • Step 5

    将CSS文件作为资源捕获,并通过 resources.PostCSS (别名 postCSS )进行管道处理:

layouts/partials/css.html

1
2
3
{{ with resources.Get "css/main.css" | postCSS }}
  <link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}

​ 如果在 assets 目录中使用Sass文件:

layouts/partials/css.html

1
2
3
{{ with resources.Get "sass/main.scss" | toCSS | postCSS }}
  <link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}

选项

`resources.PostCSS`  方法接受一个可选的选项映射。  
  • config

    ( string ) 包含PostCSS配置文件的目录。默认为项目目录的根目录。

  • noMap

    ( bool ) 默认为 false 。如果为 true ,则禁用内联源地图(sourcemaps)。

  • inlineImports

    ( bool ) 默认为 false 。启用@import语句的内联。它会递归执行,但只会导入一次文件。URL导入(例如 @import url('https://fonts.googleapis.com/css?family=Open+Sans&display=swap'); )和带媒体查询的导入将被忽略。请注意,此导入例程不关心CSS规范,因此您可以在文件中的任何地方使用@import。Hugo将查找相对于模块挂载的导入并遵守主题覆盖。

  • skipInlineImportsNotFound New in v0.99.0

    ( bool ) 默认为 false 。在Hugo 0.99.0之前,当启用 inlineImports 并且我们无法解析导入时,我们会将其记录为警告。现在我们将构建失败。如果您的CSS中有常规CSS导入要保留,则可以使用带URL的导入或媒体查询(Hugo不会尝试解决这些导入),或将 skipInlineImportsNotFound 设置为true。

layouts/partials/css.html

1
2
3
4
{{ $opts := dict "config" "config-directory" "noMap" true }}
{{ with resources.Get "css/main.css" | postCSS $opts }}
  <link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}

无配置文件

​ 为了避免使用PostCSS配置文件,可以使用选项映射指定最小的配置。

  • use

    (string) 用于指定要使用的 PostCSS 插件的以空格分隔的列表。

  • parser

    (string) 自定义 PostCSS 解析器。

  • stringifier

    (string) 自定义 PostCSS 字符串化器。

  • syntax

    (string) 自定义 PostCSS 语法。

layouts/partials/css.html

1
2
3
4
{{ $opts := dict "use" "autoprefixer postcss-color-alpha" }}
{{ with resources.Get "css/main.css" | postCSS $opts }}
  <link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}

检查 Hugo 环境

​ 当前的 Hugo 环境名称(通过 --environment 在配置或操作系统环境中设置)在 Node 上下文中可用,这使得可以使用如下结构:

postcss.config.js

1
2
3
4
5
6
7
8
module.exports = {
  plugins: [
    require('autoprefixer'),
    ...process.env.HUGO_ENVIRONMENT === 'production'
      ? [purgecss]
      : []
  ]
}

另请参阅

9.9 - PostProcess

PostProcess

https://gohugo.io/hugo-pipes/postprocess/

Allows delaying of resource transformations to after the build.

语法

resources.PostProcess RESOURCE

用法

Marking a resource with resources.PostProcess delays any transformations to after the build, typically because one or more of the steps in the transformation chain depends on the result of the build (e.g. files in public).

A prime use case for this is CSS purging with PostCSS.

There are currently two limitations to this:

  1. This only works in *.html templates (i.e. templates that produces HTML files).

  2. You cannot manipulate the values returned from the resource’s methods. E.g. the upper in this example will not work as expected:

    1
    2
    3
    
    {{ $css := resources.Get "css/main.css" }}
    {{ $css = $css | resources.PostCSS | minify | fingerprint | resources.PostProcess }}
    {{ $css.RelPermalink | upper }}
    

CSS purging with PostCSS

There are several ways to set up CSS purging with PostCSS in Hugo. If you have a simple project, you should consider going the simpler route and drop the use of resources.PostProcess and just extract keywords from the templates. See the Tailwind documentation for some examples.

The below configuration will write a hugo_stats.json file to the project root as part of the build. If you’re only using this for the production build, you should consider placing it below config/production.

config.

=== “yaml”

``` yaml
build:
  writeStats: true
```

=== “toml”

``` toml
[build]
  writeStats = true
```

=== “json”

``` json
{
   "build": {
      "writeStats": true
   }
}
```

postcss.config.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const purgecss = require('@fullhuman/postcss-purgecss')({
    content: [ './hugo_stats.json' ],
    defaultExtractor: (content) => {
        let els = JSON.parse(content).htmlElements;
        return els.tags.concat(els.classes, els.ids);
    }
});

module.exports = {
     plugins: [
         ...(process.env.HUGO_ENVIRONMENT === 'production' ? [ purgecss ] : [])
     ]
 };

Note that in the example above, the “CSS purge step” will only be applied to the production build. This means that you need to do something like this in your head template to build and include your CSS:

1
2
3
4
5
6
{{ $css := resources.Get "css/main.css" }}
{{ $css = $css | resources.PostCSS }}
{{ if hugo.IsProduction }}
{{ $css = $css | minify | fingerprint | resources.PostProcess }}
{{ end }}
<link href="{{ $css.RelPermalink }}" rel="stylesheet" />

Hugo Environment variables available in PostCSS

These are the environment variables Hugo passes down to PostCSS (and Babel), which allows you do do process.env.HUGO_ENVIRONMENT === 'production' ? [autoprefixer] : [] and similar:

  • PWD

    The absolute path to the project working directory. HUGO_ENVIRONMENT (and the alias HUGO_ENV)

    The value e.g. set with hugo -e production (defaults to production for hugo and development for hugo server).

  • HUGO_PUBLISHDIR

    {{ new-in “0.109.0” }} The absolute path to the publish directory (the public directory). Note that the value will always point to a directory on disk even when running hugo server in memory mode. If you write to this folder from PostCSS when running the server, you could run the server with one of these flags:

hugo server --renderToDisk
hugo server --renderStaticToDisk

Also, Hugo will add environment variables for all files mounted below assets/_jsconfig. A default mount will be set up with files in the project root matching this regexp: (babel|postcss|tailwind)\.config\.js.

These will get environment variables named on the form HUGO_FILE_:filename: where :filename: is all upper case with periods replaced with underscore. This allows you to do this and similar:

1
let tailwindConfig = process.env.HUGO_FILE_TAILWIND_CONFIG_JS || './tailwind.config.js';

另请参阅

9.10 - ToCSS

ToCSS

https://gohugo.io/hugo-pipes/transform-to-css/

​ 将 Sass 转译为 CSS。

语法

resources.ToCSS RESOURCE [OPTIONS]
toCSS RESOURCE [OPTIONS]

用法

​ 可以使用 resources.ToCSS 将任何 Sass 或 SCSS 文件转换为 CSS 文件,其中需要两个参数:资源对象和下面列出的一个选项映射。

1
2
{{ $sass := resources.Get "sass/main.scss" }}
{{ $style := $sass | resources.ToCSS }}

选项

  • transpiler [string]

    使用的 transpiler ,有效值为 libsass (默认)和 dartsass 。如果您想使用 Hugo 与 Dart Sass,请从 Embedded Dart Sass 下载发布二进制文件,并确保它在您的 PC 的 $PATH (或 Windows 上的 %PATH% )中。

  • targetPath [string]

    如果未设置,则转换后的资源的目标路径将是asset文件原始路径,其扩展名将替换为 .css

  • vars [map]

    键/值对的映射,将在 hugo:vars 命名空间中可用,例如:使用 @use "hugo:vars" as v; 或(全局)使用 @import "hugo:vars";自 v0.109.0 起新增

  • outputStyle [string]

    默认值为 nested (LibSass)和 expanded (Dart Sass)。LibSass 的其他可用输出样式为 expandedcompactcompressed 。Dart Sass 仅支持 expandedcompressed

  • precision [int]

    浮点数精度。注意:Dart Sass 不支持此选项。

  • enableSourceMap [bool]

    启用时,将生成源映射。

  • sourceMapIncludeSources [bool]

    启用时,源将嵌入到生成的源映射中。(仅在 Dart Sass 中)。自 v0.108.0 起新增

  • includePaths [string slice]

    额外的 SCSS/Sass 包含路径。路径必须相对于项目目录。

1
2
{{ $options := (dict "targetPath" "style.css" "outputStyle" "compressed" "enableSourceMap" (not hugo.IsProduction) "includePaths" (slice "node_modules/myscss")) }}
{{ $style := resources.Get "sass/main.scss" | resources.ToCSS $options }}

​ 将 outputStyle 设置为 compressed 将比更通用的 resources.Minify 更好地处理 Sass/SCSS 文件的压缩。

另请参阅

9.11 - 压缩

Minify - 压缩

https://gohugo.io/hugo-pipes/minification/

​ 压缩给定的资源。

语法

resources.Minify RESOURCE
minify RESOURCE

用法

​ 任何 CSS、JS、JSON、HTML、SVG 或 XML 资源都可以使用 resources.Minify 进行压缩,该函数需要资源对象作为参数。

1
2
{{ $css := resources.Get "css/main.css" }}
{{ $style := $css | resources.Minify }}

​ 请注意,您也可以通过运行 hugo --minify 压缩最终的 HTML 输出到 /public

另请参阅

10 - 命令

Commands - 命令

https://gohugo.io/commands/

10.1 - hugo

hugo

https://gohugo.io/commands/hugo/

hugo

​ hugo 构建您的站点

概要

​ hugo 是主要命令,用于构建您的Hugo站点。

​ Hugo 是一个用 Go 语言编写的快速且灵活的静态站点生成器,由 spf13 和朋友们倾情打造。

​ 完整文档请访问 https://gohugo.io/

hugo [flags]

选项

  -b, --baseURL string             主机名(和根路径),例如https://spf13.com/
  -D, --buildDrafts                包含标记为草稿的内容
  -E, --buildExpired               包含已过期的内容
  -F, --buildFuture                包含将来发布日期的内容
      --cacheDir string            缓存目录的文件系统路径。默认值:$TMPDIR/hugo_cache/
      --cleanDestinationDir        从目标目录中删除未在静态目录中找到的文件
      --clock string               设置Hugo使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
  -c, --contentDir string          内容目录的文件系统路径
      --debug                      调试输出
  -d, --destination string         写入文件的文件系统路径
      --disableKinds strings       禁用不同类型的页面(首页、RSS 等)
      --enableGitInfo              将 Git 修订、日期、作者和 CODEOWNERS 信息添加到页面
  -e, --environment string         构建环境
      --forceSyncStatic            当静态内容发生更改时,复制所有文件。
      --gc                         启用在构建后运行一些清理任务(删除未使用的缓存文件)
  -h, --help                       hugo 的帮助
      --ignoreCache                忽略缓存目录
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径中的任何 _vendor
  -l, --layoutDir string           布局目录的文件系统路径
      --log                        启用日志
      --logFile string             日志文件路径(如果设置,日志自动启用)
      --minify                     最小化任何支持的输出格式(HTML、XML 等)
      --noBuildLock                不创建.hugo_build.lock文件
      --noChmod                    不同步文件的权限模式
      --noTimes                    不同步文件的修改时间
      --panicOnWarning             在第一个警告日志上发生恐慌
      --poll string                将其设置为轮询间隔,例如 --poll 700ms,以使用基于轮询的方法来监视文件系统更改
      --printI18nWarnings          打印缺失的翻译
      --printMemoryUsage           在间隔期内将内存使用情况打印到屏幕上
      --printPathWarnings          打印关于重复目标路径等的警告
      --printUnusedTemplates       打印未使用的模板的警告。
      --quiet                      安静模式构建
      --renderToMemory             将渲染结果存储到内存中(仅对基准测试有用)
  -s, --source string              从中读取文件的文件系统路径
      --templateMetrics            显示关于模板执行的指标
      --templateMetricsHints       在与 --templateMetrics 结合使用时,计算一些改进提示
  -t, --theme strings              要使用的主题(位于/themes/THEMENAME/)
      --themesDir string           主题目录的文件系统路径
      --trace file                 将跟踪写入文件(通常没有用处)
  -v, --verbose                    详细输出
      --verboseLog                 详细日志
  -w, --watch                      观察文件系统变化,并根据需要重新创建

另请参阅

另请参阅

10.2 - hugo completion

hugo completion

https://gohugo.io/commands/hugo_completion/

hugo 自动补全

​ 生成指定 shell 的 hugo 自动补全脚本。

概要

​ 生成指定 shell 的 hugo 自动补全脚本。有关如何使用生成的脚本的详细信息,请参阅每个子命令的帮助。

选项

  -h, --help   help for completion

从父命令继承的选项

	 --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
     --config string              配置文件 (默认为 hugo.yaml|json|toml)
     --configDir string           配置目录 (默认 "config")
     --debug                      调试输出
 -e, --environment string         构建环境
     --ignoreVendorPaths string   忽略任何与给定 Glob 模式匹配的模块路径的 _vendor
     --log                        启用日志记录
     --logFile string             日志文件路径(如果设置,自动启用日志记录)
     --quiet                      安静模式下构建
 -s, --source string              文件系统路径,从中读取相对文件
     --themesDir string           主题目录的文件系统路径
 -v, --verbose                    冗长的输出
     --verboseLog                 冗长的日志记录

另请参阅

另请参阅

10.3 - hugo completion bash

hugo completion bash

https://gohugo.io/commands/hugo_completion_bash/

hugo completion bash

​ 生成bash shell的自动补全脚本。

概要

​ 生成bash shell的自动补全脚本。

​ 此脚本依赖于bash-completion软件包。如果尚未安装,则可以通过操作系统的包管理器安装它。

​ 要在当前shell会话中加载自动补全:

source <(hugo completion bash)

​ 要为每个新会话加载自动补全,请执行以下操作一次:

Linux:

hugo completion bash > /etc/bash_completion.d/hugo

macOS:

hugo completion bash > $(brew --prefix)/etc/bash_completion.d/hugo

​ 您需要启动一个新的shell才能使此设置生效。

hugo completion bash

选项

  -h, --help              help for bash
      --no-descriptions   禁用completion说明

从父命令继承的选项

	 --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
     --config string              配置文件 (默认为 hugo.yaml|json|toml)
     --configDir string           配置目录 (默认 "config")
     --debug                      调试输出
 -e, --environment string         构建环境
     --ignoreVendorPaths string   忽略任何与给定 Glob 模式匹配的模块路径的 _vendor
     --log                        启用日志记录
     --logFile string             日志文件路径(如果设置,自动启用日志记录)
     --quiet                      安静模式下构建
 -s, --source string              文件系统路径,从中读取相对文件
     --themesDir string           主题目录的文件系统路径
 -v, --verbose                    冗长的输出
     --verboseLog                 冗长的日志记录

另请参阅

另请参阅

10.4 - hugo completion fish

hugo completion fish

https://gohugo.io/commands/hugo_completion_fish/

hugo completion fish

​ 生成fish shell的自动补全脚本。

概要

​ 生成fish shell的自动补全脚本。

​ 要在当前的shell会话中加载自动补全:

hugo completion fish | source

​ 要为每个新会话加载自动补全,请执行以下操作一次:

hugo completion fish > ~/.config/fish/completions/hugo.fish

​ 您需要启动一个新的shell才能使此设置生效。

hugo completion fish [flags]

选项

  -h, --help              help for fish
      --no-descriptions   禁用completion说明

从父命令继承的选项

	 --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
     --config string              配置文件 (默认为 hugo.yaml|json|toml)
     --configDir string           配置目录 (默认 "config")
     --debug                      调试输出
 -e, --environment string         构建环境
     --ignoreVendorPaths string   忽略任何与给定 Glob 模式匹配的模块路径的 _vendor
     --log                        启用日志记录
     --logFile string             日志文件路径(如果设置,自动启用日志记录)
     --quiet                      安静模式下构建
 -s, --source string              文件系统路径,从中读取相对文件
     --themesDir string           主题目录的文件系统路径
 -v, --verbose                    冗长的输出
     --verboseLog                 冗长的日志记录

另请参阅

另请参阅

10.5 - hugo completion powershell

hugo completion powershell

hugo completion powershell

​ 生成powershell shell的自动补全脚本。

概要

​ 生成powershell shell的自动补全脚本。

​ 要在当前的shell会话中加载自动补全:

hugo completion powershell | Out-String | Invoke-Expression

​ 要在每个新会话中加载自动补全,请将上述命令的输出添加到您的 powershell 配置文件中。

hugo completion powershell [flags]

选项

  -h, --help              help for powershell
      --no-descriptions   disable completion descriptions

从父命令继承的选项

	 --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
     --config string              配置文件 (默认为 hugo.yaml|json|toml)
     --configDir string           配置目录 (默认 "config")
     --debug                      调试输出
 -e, --environment string         构建环境
     --ignoreVendorPaths string   忽略任何与给定 Glob 模式匹配的模块路径的 _vendor
     --log                        启用日志记录
     --logFile string             日志文件路径(如果设置,自动启用日志记录)
     --quiet                      安静模式下构建
 -s, --source string              文件系统路径,从中读取相对文件
     --themesDir string           主题目录的文件系统路径
 -v, --verbose                    冗长的输出
     --verboseLog                 冗长的日志记录

另请参阅

另请参阅

10.6 - hugo completion zsh

hugo completion zsh

https://gohugo.io/commands/hugo_completion_zsh/

hugo completion zsh

​ 生成zsh shell的自动补全脚本。

概要

​ 生成zsh shell的自动补全脚本。

​ 如果您的环境中没有启用 shell 自动补全,您需要启用它。您可以执行以下命令:

echo "autoload -U compinit; compinit" >> ~/.zshrc

​ 为了在当前的 shell 会话中载入自动补全:

source <(hugo completion zsh); compdef _hugo hugo

​ 要为每个新会话加载自动补全,请执行以下操作一次:

Linux:

hugo completion zsh > "${fpath[1]}/_hugo"

macOS:

hugo completion zsh > $(brew --prefix)/share/zsh/site-functions/_hugo

​ 您需要启动一个新的shell才能使此设置生效。

hugo completion zsh [flags]

选项

  -h, --help              help for zsh
      --no-descriptions   禁用completion说明

从父命令继承的选项

	 --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
     --config string              配置文件 (默认为 hugo.yaml|json|toml)
     --configDir string           配置目录 (默认 "config")
     --debug                      调试输出
 -e, --environment string         构建环境
     --ignoreVendorPaths string   忽略任何与给定 Glob 模式匹配的模块路径的 _vendor
     --log                        启用日志记录
     --logFile string             日志文件路径(如果设置,自动启用日志记录)
     --quiet                      安静模式下构建
 -s, --source string              文件系统路径,从中读取相对文件
     --themesDir string           主题目录的文件系统路径
 -v, --verbose                    冗长的输出
     --verboseLog                 冗长的日志记录

另请参阅

另请参阅

10.7 - hugo config

hugo config

https://gohugo.io/commands/hugo_config/

hugo config

​ 打印站点配置

概要

​ 打印站点配置,包括默认和自定义设置。

hugo config [flags]

选项

      --clock string               set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
  -e, --environment string         build environment
  -h, --help                       help for config
      --ignoreVendorPaths string   ignores any _vendor for module paths matching the given Glob pattern
  -s, --source string              filesystem path to read files relative from
      --themesDir string           filesystem path to themes directory
      
      --clock string               设置Hugo使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
  -e, --environment string         构建环境
  -h, --help                       帮助配置
      --ignoreVendorPaths string   忽略任何与给定Glob模式匹配的模块路径的_vendor
  -s, --source string              相对于读取文件的文件系统路径
      --themesDir string           文件系统路径到主题目录

从父命令继承的选项

      --config string      配置文件(默认为hugo.yaml | json | toml)
      --configDir string   配置目录(默认值为“config”)
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置,则自动启用日志记录)
      --quiet              静默模式下构建
  -v, --verbose            详细输出
      --verboseLog         详细日志记录

另请参阅

另请参阅

10.8 - hugo config mounts

hugo config mounts

https://gohugo.io/commands/hugo_config_mounts/

hugo config mounts

​ 打印已配置的文件挂载

hugo config mounts [flags]

选项

  -h, --help   help for mounts

从父命令继承的选项

	  --clock string               设置Hugo使用的时钟,例如--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略任何与给定Glob模式匹配的模块路径的_vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式下构建
  -s, --source string              从文件系统中读取文件的相对路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.9 - hugo convert

hugo convert

https://gohugo.io/commands/hugo_convert/

hugo convert

​ 将您的内容转换为不同的格式

概要

​ 将您的内容(例如前置元数据)转换为不同的格式。

​ 有关更多信息,请参见转换的子命令 toJSON、toTOML 和 toYAML。

选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
  -e, --environment string         构建环境
  -h, --help                       convert 的帮助信息
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
  -o, --output string              要将文件写入的文件系统路径
  -s, --source string              从中读取文件的文件系统路径相对路径
      --themesDir string           主题目录的文件系统路径
      --unsafe                     启用不安全的操作,请先备份

从父命令继承的选项

	  --config string      配置文件(默认为 hugo.yaml|json|toml)
      --configDir string   配置目录(默认为“config”)
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置,将自动启用日志记录)
      --quiet              安静模式构建
  -v, --verbose            详细输出
      --verboseLog         详细日志记录

另请参阅

另请参阅

10.10 - hugo convert toJSON

hugo convert toJSON

https://gohugo.io/commands/hugo_convert_tojson/

hugo convert toJSON

​ 将前置元数据转换为 JSON 格式。

概要

​ toJSON 将内容目录中的所有前置元数据转换为使用 JSON 格式的前置元数据。

hugo convert toJSON [flags]

选项

  -h, --help   help for toJSON

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略所有与给定 Glob 模式匹配的模块路径的 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,将自动启用日志记录)
  -o, --output string              写入文件的文件系统路径
      --quiet                      静默模式构建
  -s, --source string              相对读取文件的文件系统路径
      --themesDir string           主题目录的文件系统路径
      --unsafe                     启用不太安全的操作,请先备份
  -v, --verbose                    输出详细信息
      --verboseLog                 输出详细日志记录

另请参阅

另请参阅

10.11 - hugo convert toTOML

hugo convert toTOML

https://gohugo.io/commands/hugo_convert_totoml/

hugo convert toTOML

​ 将前置元数据转换为 TOML格式。

概要

​ toTOML 将内容目录中的所有前置元数据转换为使用 TOML 格式的前置元数据。

hugo convert toTOML [flags]

选项

  -h, --help   help for toTOML

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,将自动启用日志记录)
  -o, --output string              写入文件的文件系统路径
      --quiet                      静音模式下进行构建
  -s, --source string              从文件系统路径读取与文件相关的文件
      --themesDir string           主题目录的文件系统路径
      --unsafe                     启用更少安全的操作,请先备份
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.12 - hugo convert toYAML

hugo convert toYAML

https://gohugo.io/commands/hugo_convert_toyaml/

hugo convert toYAML

​ 将前置元数据转换为 YAML格式。

概要

​ toYAML 将内容目录中的所有前置元数据转换为使用 YAML 格式的前置元数据。

hugo convert toYAML [flags]

选项

  -h, --help   help for toYAML

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 匹配的模块路径的 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,日志记录将自动启用)
  -o, --output string              用于写入文件的文件系统路径
      --quiet                      安静模式构建
  -s, --source string              文件系统路径,从中读取文件相对路径
      --themesDir string           文件系统路径,主题目录
      --unsafe                     启用更少安全操作,请首先备份
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.13 - hugo deploy

hugo deploy

https://gohugo.io/commands/hugo_deploy/

hugo deploy

​ 将您的站点部署到云提供商。

概要

​ 将您的站点部署到云提供商。

​ 请参阅 https://gohugo.io/hosting-and-deployment/hugo-deploy/ 以获取详细的文档。

hugo deploy [flags]

选项

	  --clock string               设置Hugo使用的时钟,例如--clock 2021-11-06T22:30:00.00+09:00
      --confirm                    在对目标进行更改之前要求确认
      --dryRun                     干况运行
  -e, --environment string         构建环境
      --force                      强制上传所有文件
  -h, --help                       deploy的帮助信息
      --ignoreVendorPaths string   忽略匹配给定Glob模式的模块路径中的任何_vendor
      --invalidateCDN              使部署目标中列出的CDN缓存失效(默认值为true)
      --maxDeletes int             要删除的文件的最大数量,或-1禁用(默认值为256)
      --workers int                传输文件的工作者数。(默认值为10)
  -s, --source string              从其中读取文件的文件系统路径
      --target string              部署目标中的目标部署在配置文件中;默认为第一个
      --themesDir string           主题目录的文件系统路径

从父命令继承的选项

	  --config string      配置文件(默认为hugo.yaml|json|toml)
      --configDir string   配置目录(默认为“config”)
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置,将自动启用日志记录)
      --quiet              静默模式下构建
  -v, --verbose            冗长输出
      --verboseLog         冗长日志记录

另请参阅

  • hugo - 构建您的站点

另请参阅

10.14 - hugo env

hugo env

https://gohugo.io/commands/hugo_env/

hugo env

​ 输出Hugo版本和环境信息

概要

​ 输出Hugo版本和环境信息。这在Hugo错误报告中非常有用。

​ 如果加上-v标志,您将得到一个完整的依赖项列表。

hugo env [flags]

选项

  -h, --help   help for env

从父命令继承的选项

	  --clock string               设置Hugo使用的时钟,例如--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略任何与给定Glob模式匹配的模块路径的_vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,自动启用日志记录)
      --quiet                      静默模式下构建
  -s, --source string              从文件系统路径读取相对文件
      --themesDir string           文件系统路径到主题目录
  -v, --verbose                    详细输出
      --verboseLog                 详细记录日志

另请参阅

  • hugo - 构建您的站点

另请参阅

10.15 - hugo gen

hugo gen

https://gohugo.io/commands/hugo_gen/

hugo gen

​ 一个包含多个有用生成器的集合。

选项

  -h, --help   help for gen

从父命令继承的选项

      --clock string               设置 Hugo 使用的时钟,例如:--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略任何与给定 Glob 模式匹配的模块路径的 _vendor 目录
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      安静模式下构建
  -s, --source string              读取文件的文件系统路径(相对路径)
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.16 - hugo gen chromastyles

hugo gen chromastyles

https://gohugo.io/commands/hugo_gen_chromastyles/

hugo gen chromastyles

​ 为 Chroma 代码高亮器生成 CSS 样式表

概要

​ 为给定样式的 Chroma 代码高亮器生成 CSS 样式表。如果在配置中禁用了 markup.highlight.noClasses,则需要此样式表。

​ 请参阅 https://xyproto.github.io/splash/docs/all.html 以预览可用的样式。

hugo gen chromastyles [flags]

选项

	-h, --help                    帮助信息
        --highlightStyle string   用于突出显示行的样式(请参阅 https://github.com/alecthomas/chroma)(默认值为“bg:#ffffcc”)
        --linesStyle string       用于行号的样式(请参阅 https://github.com/alecthomas/chroma)
        --style string            高亮器样式(请参阅 https://xyproto.github.io/splash/docs/)(默认值为“friendly”)

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径中的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,将自动启用日志记录)
      --quiet                      在安静模式下构建
  -s, --source string              从文件系统路径读取相对文件
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    冗长输出
      --verboseLog                 冗长的日志记录

另请参阅

  • hugo gen - 一个包含多个有用生成器的集合。

另请参阅

10.17 - hugo gen doc

hugo gen doc

https://gohugo.io/commands/hugo_gen_doc/

hugo gen doc

Generate Markdown documentation for the Hu CLI.

​ 为 Hugo CLI 生成 Markdown 文档。

概要

​ 为 Hugo CLI 生成 Markdown 文档。

​ 这个命令主要用于为 https://gohugo.io/ 的 Hugo 命令行接口创建最新的文档。

​ 它为每个命令创建一个带有适合在 Hugo 中渲染的前置元数据的 Markdown 文件。

hugo gen doc [flags]

选项

      --dir string   要写入文档的目录。(默认值为 "/tmp/hugodoc/")
  -h, --help         help for doc

从父命令继承的选项

--clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认值为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,日志记录将自动启用)
      --quiet                      静默模式构建
  -s, --source string              从中读取文件的文件系统路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    冗长输出
      --verboseLog                 冗长日志

另请参阅

  • hugo gen - 一个包含多个有用生成器的集合。

另请参阅

10.18 - hugo gen man

hugo gen man

https://gohugo.io/commands/hugo_gen_man/

hugo gen man

​ 为 Hugo CLI 生成 man 页面

概要

​ 该命令可以自动生成最新版本的Hugo CLI 的man页。默认情况下,它会在当前目录下的"man"目录中创建man页文件。

hugo gen man [flags]

选项

      --dir string   写入man页的目录 (默认值为 "man/")
  -h, --help         help for man

从父命令继承的选项

      --clock string               设置Hugo使用的时钟,例如--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件 (默认为 hugo.yaml|json|toml)
      --configDir string           配置目录 (默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略匹配给定Glob模式的模块路径中的任何_vendor
      --log                        启用日志记录
      --logFile string             日志文件路径 (如果设置,则自动启用日志记录)
      --quiet                      静默模式构建
  -s, --source string              读取文件的文件系统路径相对于哪里
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

  • hugo gen - 一个包含多个有用生成器的集合。

另请参阅

10.19 - hugo import

hugo import

https://gohugo.io/commands/hugo_import/

hugo import

​ 从其他站点生成器导入您的站点。

概要

​ 从其他站点生成器(如Jekyll)导入您的站点。

​ 导入需要一个子命令,例如 hugo import jekyll jekyll_root_path target_path

选项

  -h, --help   help for import

从父命令继承的选项

	 --clock string               设置Hugo使用的时钟,例如:--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为hugo.yaml | json | toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定Glob模式匹配的模块路径的任何_vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置了,则自动启用日志记录)
      --quiet                      在静默模式下构建
  -s, --source string              用于读取文件的文件系统路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    冗长输出
      --verboseLog                 冗长日志记录

另请参阅

另请参阅

10.20 - hugo import jekyll

hugo import jekyll

https://gohugo.io/commands/hugo_import_jekyll/

hugo import jekyll

hugo import from Jekyll

概要

hugo import from Jekyll.

​ 从 Jekyll 导入需要两个路径,例如: hugo import jekyll jekyll_root_path target_path.

hugo import jekyll [flags]

选项

      --force   允许导入到非空目标目录中
  -h, --help    help for jekyll

从父命令继承的选项

      --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略匹配给定 Glob 模式的模块路径下的任何 _vendor
      --log                        启用日志
      --logFile string             日志文件路径(如果设置,自动启用日志记录)
      --quiet                      安静模式下构建
  -s, --source string              从文件系统路径中相对读取文件
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    显示详细输出

另请参阅

  • hugo import - 从其他站点生成器导入您的站点。

另请参阅

10.21 - hugo list

hugo list

https://gohugo.io/commands/hugo_list/

hugo list

​ 列出各种类型的内容

概要

​ 列出各种类型的内容。

​ List 命令需要一个子命令,例如 hugo list drafts

选项

      --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
  -e, --environment string         构建环境
  -h, --help                       列出帮助信息
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径中的任何 _vendor 文件夹
  -s, --source string              从文件系统路径读取文件的相对路径
      --themesDir string           主题目录的文件系统路径

从父命令继承的选项

      --config string      配置文件(默认为 hugo.yaml|json|toml)
      --configDir string   配置目录(默认为“config”)
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置了该选项,则会自动启用日志记录)
      --quiet              静默模式下构建
  -v, --verbose            输出详细信息
      --verboseLog         输出详细日志记录

另请参阅

另请参阅

10.22 - hugo list all

hugo list all

https://gohugo.io/commands/hugo_list_all/

hugo list all

​ 列出所有文章

概要

​ 列出您内容目录中的所有文章,包括草稿、未来和过期的页面。

hugo list all [flags]

选项

  -h, --help   help for all

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略匹配给定 Glob 模式的模块路径中的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,将自动启用日志记录)
      --quiet                      静默模式下构建
  -s, --source string              文件系统路径,相对于该路径读取文件
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    冗长输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.23 - hugo list drafts

hugo list drafts

https://gohugo.io/commands/hugo_list_drafts/

hugo list drafts

​ 列出所有草稿

概要

列出您内容目录中的所有草稿。

hugo list drafts [flags]

选项

  -h, --help   help for drafts

从父命令继承的选项

	  --clock string               设置Hugo使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为hugo.yaml | json | toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定通配符匹配的模块路径中的任何_vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则会自动启用日志记录)
      --quiet                      以安静模式构建
  -s, --source string              从中读取文件的文件系统路径
      --themesDir string           进入主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细记录日志

另请参阅

另请参阅

10.24 - hugo list expired

hugo list expired

https://gohugo.io/commands/hugo_list_expired/

hugo list expired

​ 列出已过期的所有文章

概要

​ 列出您内容目录中所有已过期的文章。

hugo list expired [flags]

选项

  -h, --help   help for expired

从父命令继承的选项

      --clock string               设置 Hugo 使用的时钟,例如:--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式构建
  -s, --source string              从文件系统路径读取相对文件
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    冗长输出
      --verboseLog                 冗长日志记录

另请参阅

另请参阅

10.25 - hugo list future

hugo list future

https://gohugo.io/commands/hugo_list_future/

hugo list future

​ 列出所有日期为将来的文章

概要

​ 列出您内容目录中所有将来发布的文章。

hugo list future [flags]

选项

  -h, --help   help for future

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,比如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置了,则自动启用日志记录)
      --quiet                      静默模式构建
  -s, --source string              从文件系统路径读取文件的相对路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.26 - hugo mod

hugo mod

https://gohugo.io/commands/hugo_mod/

hugo mod

​ 各种 Hugo 模块的辅助工具。

概要

​ 提供各种辅助工具,以帮助管理项目依赖图中的模块。

​ 大多数操作需要在您的系统上安装 Go 版本(>= Go 1.12)和相关的版本控制系统客户端(通常是 Git)。如果您仅在 /themes 内操作模块或通过 “hugo mod vendor” 将它们标记为供应商,则不需要安装它们。

​ 这里的大多数操作需要在您的系统上安装了Go版本(>= Go 1.12)和相关的VCS客户端(通常是Git)。如果您只操作/themes中的模块,或者通过 “hugo mod vendor” 将它们打包到_vendor目录,那么不需要这些依赖。

​ 请注意,Hugo将始终首先解析站点配置中定义的组件,这些组件由_vendor目录(如果没有提供-ignoreVendorPaths标志)、Go模块或主题目录内的文件夹提供,按照此顺序解析。

​ 有关更多信息,请参见 https://gohugo.io/hugo-modules/

选项

  -b, --baseURL string             根目录的主机名(和路径),例如 https://spf13.com/
  -D, --buildDrafts                包括被标记为草稿的内容
  -E, --buildExpired               包括已过期的内容
  -F, --buildFuture                包括未来发布日期的内容
      --cacheDir string            缓存目录的文件系统路径。默认为:$TMPDIR/hugo_cache/
      --cleanDestinationDir        删除目标中未在静态目录中找到的文件
      --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
  -c, --contentDir string          内容目录的文件系统路径
  -d, --destination string         要写入文件的文件系统路径
      --disableKinds strings       禁用不同类型的页面(主页、RSS 等)
      --enableGitInfo              将 Git 版本、日期、作者和 CODEOWNERS 信息添加到页面中
  -e, --environment string         构建环境
      --forceSyncStatic            当静态文件更改时复制所有文件。
      --gc                         启用以运行一些清理任务(删除未使用的缓存文件)。
  -h, --help                       查看 mod 帮助
      --ignoreCache                忽略缓存目录
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
  -l, --layoutDir string           布局目录的文件系统路径
      --minify                     最小化任何支持的输出格式(HTML、XML 等)
      --noBuildLock                不创建 .hugo_build.lock 文件
      --noChmod                    不同步文件的权限模式
      --noTimes                    不同步文件的修改时间
      --panicOnWarning             在第一个 WARNING 日志上引发 panic
      --poll string                将其设置为轮询

从父命令继承的选项

	  --config string      配置文件(默认为hugo.yaml|json|toml)
      --configDir string   配置目录(默认为 "config")
      --debug              调试输出
      --log                启用日志
      --logFile string     日志文件路径(如果设置,自动启用日志)
      --quiet              安静模式构建
  -v, --verbose            详细输出
      --verboseLog         详细日志记录

另请参阅

另请参阅

10.27 - hugo mod clean

hugo mod clean

https://gohugo.io/commands/hugo_mod_clean/

hugo mod clean

​ 删除当前项目的Hugo模块缓存。

概要

​ 删除当前项目的Hugo模块缓存。

​ 请注意,运行此命令后,所有依赖项将在下次运行"hugo"时重新下载。

​ 还要注意,如果为"modules"文件缓存配置了正的maxAge,则也将在"hugo –gc"中清除它。

hugo mod clean [flags]

选项

      --all              清除整个模块缓存
  -h, --help             清除帮助
      --pattern string   匹配要清除的模块路径的模式(如果未设置,则为全部),例如“**hugo*”	

从父命令继承的选项

	  --clock string               设置Hugo使用的时钟,例如--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略匹配给定Glob模式的模块路径的任何_vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,自动启用日志记录)
      --quiet                      安静模式构建
  -s, --source string              从文件系统路径读取文件的相对路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    冗长输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.28 - hugo mod get

hugo mod get

https://gohugo.io/commands/hugo_mod_get/

hugo mod get

​ 解析您当前 Hugo 项目的依赖项。

概要

​ 解析您当前 Hugo 项目的依赖项。

​ 以下是一些示例:

​ 安装给定模块的最新版本:

hugo mod get github.com/gohugoio/testshortcodes

​ 安装特定版本:

hugo mod get github.com/gohugoio/testshortcodes@v0.3.0

​ 安装所有模块依赖的最新版本:

hugo mod get -u
hugo mod get -u ./... (recursive)

​ 运行 “go help get” 以获取更多信息。所有 “go get” 可用的标志在此处也是相关的。

​ 请注意,Hugo将始终首先解析站点配置中定义的组件,这些组件由_vendor目录(如果没有提供-ignoreVendorPaths标志)、Go模块或主题目录内的文件夹提供,按照此顺序解析。

​ 有关详细信息,请参阅 https://gohugo.io/hugo-modules/

hugo mod get [flags]

选项

  -h, --help   help for get

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e,--environment string         构建环境
      --ignoreVendorPaths string   忽略匹配给定 Glob 模式的模块路径的任何 _vendor 
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,自动启用日志记录)
      --quiet                      安静模式下构建
  -s,--source string              从文件系统路径读取文件,相对路径
      --themesDir string           主题目录的文件系统路径
  -v,--verbose                    输出详细信息
      --verboseLog                 输出详细日志

另请参阅

另请参阅

10.29 - hugo mod graph

hugo mod graph

https://gohugo.io/commands/hugo_mod_graph/

hugo mod graph

​ 打印模块依赖图。

概要

​ 打印包含有关模块状态(禁用、供应商)信息的模块依赖图。请注意,对于供应商模块,将列出版本而不是来自 go.mod 的版本。

hugo mod graph [flags]

选项

  -h, --help   help for graph

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径中的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      安静模式构建
  -s, --source string              文件系统路径,以相对路径读取文件
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.30 - hugo mod init

hugo mod init

https://gohugo.io/commands/hugo_mod_init/

hugo mod init

​ 将此项目初始化为 Hugo 模块。

概要

​ 将该项目初始化为 Hugo 模块。它会尝试猜测模块路径,但您也可以通过参数来指定,例如:

hugo mod init github.com/gohugoio/testshortcodes

​ 请注意,Hugo 模块支持多模块项目,因此您可以在 GitHub 的子文件夹中初始化 Hugo 模块,作为一个示例。

hugo mod init [flags]

选项

  -h, --help   help for init

从父命令继承的选项

      --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略任何 _vendor 目录,以匹配给定的 Glob 模式的模块路径
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,将自动启用日志记录)
      --quiet                      在安静模式下构建
  -s, --source string              从文件系统路径读取文件的相对路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    输出详细信息
      --verboseLog                 输出详细的日志记录

另请参阅

另请参阅

10.31 - hugo mod npm

hugo mod npm

https://gohugo.io/commands/hugo_mod_npm/

hugo mod npm

​ 各种npm助手。

概要

​ 各种npm(Node包管理器)助手。

hugo mod npm [flags]

选项

  -h, --help   help for npm

从父命令继承的选项

	  --clock string               设置Hugo使用的时钟,例如 --clock 2021-11-06T22: 30: 00.00 + 09: 00
      --config string              配置文件(默认为hugo.yaml| json | toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略匹配给定Glob模式的模块路径中的任何_vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式构建
  -s, --source string              相对于该文件系统路径读取文件的路径
      --themesDir string           主题目录所在的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

  • hugo mod - 各种 Hugo 模块助手。
  • hugo mod npm pack - 实验性功能:为您的项目准备并编写一个组合的package.json文件。

另请参阅

10.32 - hugo mod npm pack

hugo mod npm pack

https://gohugo.io/commands/hugo_mod_npm_pack/

hugo mod npm pack

​ 实验性功能:准备并写入项目的组合 package.json 文件。

概要

​ 准备并写入项目的组合 package.json 文件。

​ 第一次运行时,如果项目根目录中没有"package.hugo.json"文件,则会创建该文件。此文件将用作具有基本依赖项集合的模板文件。

​ 该集合将与在依赖树中找到的所有"package.hugo.json"文件合并,选择最接近项目的版本。

​ 此命令标记为 Experimental。我们认为这是一个很好的想法,因此不太可能从 Hugo 中删除,但我们需要在"real life"中进行测试以了解它的感觉,因此在未来的Hugo版本中它可能会/将更改。

hugo mod npm pack [flags]

选项

  -h, --help   help for pack

从父命令继承的选项

      --clock string               设置 Hugo 使用的时钟,例如--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认值为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径中的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式下构建
  -s, --source string              从文件系统路径读取相对文件
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.33 - hugo mod tidy

hugo mod tidy

https://gohugo.io/commands/hugo_mod_tidy/

hugo mod tidy

​ 删除 go.mod 和 go.sum 中未使用的条目。

hugo mod tidy [flags]

选项

  -h, --help   help for tidy

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式下进行构建
  -s, --source string              读取相对文件的文件系统路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.34 - hugo mod vendor

hugo mod vendor

https://gohugo.io/commands/hugo_mod_vendor/

hugo mod vendor

​ 将所有模块依赖项打包到 _vendor 目录中。

概要

​ 将所有模块依赖项打包到 _vendor 目录中。

​ 如果一个模块被打包了,Hugo 将在 _vendor 目录中查找它的依赖项。

hugo mod vendor [flags]

选项

  -h, --help   help for vendor

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式下进行构建
  -s, --source string              读取相对文件的文件系统路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.35 - hugo mod verify

hugo mod verify

https://gohugo.io/commands/hugo_mod_verify/

hugo mod verify

​ 验证依赖项。

概要

​ verify 检查当前模块的依赖项是否已被下载到本地源缓存中,在下载后是否已被修改。

hugo mod verify [flags]

选项

      --clean   如果验证失败则删除依赖项的模块缓存
  -h, --help    help for verify

从父命令继承的选项

	  --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为 hugo.yaml|json|toml)
      --configDir string           配置目录(默认为 "config")
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式下进行构建
  -s, --source string              读取相对文件的文件系统路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    详细输出
      --verboseLog                 详细日志记录

另请参阅

另请参阅

10.36 - hugo new

hugo new

https://gohugo.io/commands/hugo_new/

hugo new

​ 为您的站点创建新内容

概要

​ 创建一个新的内容文件并自动设置日期和标题。它将根据提供的路径猜测要创建哪种类型的文件。

​ 您还可以使用-k KIND指定种类。

​ 如果您的主题或站点中提供了原型模板,它们将被使用。

​ 请确保在站点的根目录中运行此命令。

hugo new [path] [flags]

选项

  -b, --baseURL string             站点根目录的主机名(和路径),例如 https://spf13.com/
  -D, --buildDrafts                包括标记为草稿的内容
  -E, --buildExpired               包括过期内容
  -F, --buildFuture                包括发布日期在未来的内容
      --cacheDir string            缓存目录的文件系统路径。默认值:$TMPDIR/hugo_cache/。
      --cleanDestinationDir        删除目标文件夹中未在静态目录中找到的文件
      --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
  -c, --contentDir string          内容文件夹的文件系统路径
  -d, --destination string         写入文件的文件系统路径
      --disableKinds strings       禁用不同种类的页面(主页、RSS 等)
      --editor string              使用此编辑器编辑新内容(如果提供)
      --enableGitInfo              添加 Git 版本、日期、作者和 CODEOWNERS 信息到页面中
  -e, --environment string         构建环境
  -f, --force                      如果文件已经存在,则覆盖文件
      --forceSyncStatic            当静态文件发生更改时复制所有文件。
      --gc                         构建后启用以运行一些清理任务(删除未使用的缓存文件)
  -h, --help                       hugo new 的帮助信息
      --ignoreCache                忽略缓存目录
      --ignoreVendorPaths string   忽略匹配给定 Glob 模式的模块路径下的 _vendor。
  -k, --kind string                要创建的内容类型
  -l, --layoutDir string           布局文件夹的文件系统路径
      --minify                     缩小任何受支持的输出格式(HTML、XML 等)
      --noBuildLock                不创建 .hugo_build.lock 文件
      --noChmod                    不同步文件的权限模式
      --noTimes                    不同步文件的修改时间
      --panicOnWarning             在第一个 WARNING 日志上发生崩溃
      --poll string                将其设置为轮询间隔,例如 --poll 700ms,使其使用基于轮询的方法来监视文件系统更改
      --printI18nWarnings          打印缺少的翻译
      --printMemoryUsage           定期在屏幕上打印内存使用情况
      --printPathWarnings          打印有关重复目标路径的警告等
      --printUnusedTemplates       打印未使用模板的警告。
  -s, --source string              从中读取文件的文件系统路径
      --templateMetrics            显示有关模板执行的指标
      --templateMetricsHints       与 --templateMetrics 结合使用时,计算某些改进提示
  -t, --theme strings              要使用的主题(位于 /themes/THEMENAME/ 中)
      --themesDir string           主题文件夹的文件系统路径
      --trace file                 将跟踪写入文件(通常不会有用)

从父命令继承的选项

      --config string      配置文件(默认为 hugo.yaml|json|toml)
      --configDir string   配置目录(默认为 "config")
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置,自动启用日志记录)
      --quiet              安静模式下构建
  -v, --verbose            冗长的输出
      --verboseLog         冗长的日志记录

另请参阅

另请参阅

10.37 - hugo new site

hugo new site

https://gohugo.io/commands/hugo_new_site/

hugo new site

​ 创建新站点(框架)

概要

​ 在指定的目录中创建新站点。新站点将具有正确的结构,但尚未包含任何内容或主题。使用 hugo new [contentPath] 创建新的内容。

hugo new site [path] [flags]

选项

      --clock string               设置 Hugo 使用的时钟,例如:--clock 2021-11-06T22:30:00.00+09:00
  -e, --environment string         构建环境
      --force                      在非空目录中初始化
  -f, --format string              配置文件格式(默认为 "toml")
  -h, --help                       site 的帮助信息
      --ignoreVendorPaths string   忽略匹配给定 Glob 模式的模块路径中的任何 _vendor
  -s, --source string              从文件系统路径中读取相对文件的路径
      --themesDir string           主题目录的文件系统路径

从父命令继承的选项

      --config string      配置文件(默认为 hugo.yaml|json|toml)
      --configDir string   配置目录(默认为 "config")
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置,则自动启用日志记录)
      --quiet              静默模式下构建
  -v, --verbose            冗长输出
      --verboseLog         冗长的日志记录

另请参阅

  • hugo new - 为您的站点创建新内容

另请参阅

10.38 - hugo new theme

hugo new theme

https://gohugo.io/commands/hugo_new_theme/

hugo new theme

​ 创建一个新的主题

概要

​ 在./themes中创建一个名为[name]的新主题(框架)。新主题是一个框架,请在相关文件中添加内容。在许可证的版权行中添加您的名字,并根据需要调整theme.toml文件。

hugo new theme [name] [flags]

选项

	  --clock string               设置Hugo使用的时钟,例如:--clock 2021-11-06T22:30:00.00+09:00
  -e, --environment string         构建环境
  -h, --help                       帮助主题
      --ignoreVendorPaths string   忽略与给定Glob模式匹配的模块路径中的任何_vendor
  -s, --source string              从文件系统路径读取文件的路径
      --themesDir string           主题目录的文件系统路径

从父命令继承的选项

      --config string      配置文件 (默认为hugo.yaml|json|toml)
      --configDir string   配置目录 (默认为“config”)
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置,自动启用日志记录)
      --quiet              静默模式构建
  -v, --verbose            详细输出
      --verboseLog         详细日志记录

另请参阅

  • hugo new - 为您的站点创建新内容

另请参阅

10.39 - hugo server

hugo server

https://gohugo.io/commands/hugo_server/

hugo server

​ 一个高性能的 Web 服务器

概要

​ Hugo 提供了自己的 Web 服务器,可以构建和提供站点。虽然 hugo server 性能很高,但它是一个选项有限的 Web 服务器。许多人在生产中运行它,但标准行为是在开发中使用它,(在生成中)使用更全面的服务器,例如 Nginx 或 Caddy。

​ ‘hugo server’ 将避免将渲染和提供的内容写入磁盘,而是将其存储在内存中。

​ 默认情况下,hugo 也会监视您所做的任何更改并自动重新构建站点。然后它将实时重新加载任何打开的浏览器页面并将最新内容推送到它们。由于大多数 Hugo 站点只需要几秒钟就可以构建完毕,因此您几乎可以立即保存和查看更改。

hugo server [flags]

选项

	  --appendPort                 将端口附加到 baseURL 上(默认为 true)
  -b, --baseURL string             主机名(和路径)到根目录,例如 https://spf13.com/
      --bind string                服务器将绑定的接口(默认为 "127.0.0.1")
  -D, --buildDrafts                包括标记为草稿的内容
  -E, --buildExpired               包括过期的内容
  -F, --buildFuture                包括发布日期在未来的内容
      --cacheDir string            缓存目录的文件系统路径。默认值:$TMPDIR/hugo_cache/
      --cleanDestinationDir        删除在静态目录中找不到的目标文件
      --clock string               设置 Hugo 使用的时钟,例如 --clock 2021-11-06T22:30:00.00+09:00
  -c, --contentDir string          内容目录的文件系统路径
  -d, --destination string         写入文件的文件系统路径
      --disableBrowserError        不要在浏览器中显示构建错误
      --disableFastRender          启用完全重渲染以响应更改
      --disableKinds strings       禁用不同类型的页面(主页、RSS 等)
      --disableLiveReload          在重建时不启用实时浏览器重新加载
      --enableGitInfo              向页面添加 Git 修订版、日期、作者和 CODEOWNERS 信息
  -e, --environment string         构建环境
      --forceSyncStatic            当静态文件发生更改时复制所有文件。
      --gc                         启用后可在构建后运行一些清理任务(删除未使用的缓存文件)
  -h, --help                       server 的帮助信息
      --ignoreCache                忽略缓存目录
      --ignoreVendorPaths string   忽略与给定 Glob 模式匹配的模块路径的 _vendor
  -l, --layoutDir string           布局目录的文件系统路径
      --liveReloadPort int         实时重新加载端口(例如 HTTPS 代理情况下的 443)(默认为 -1)
      --meminterval string         每隔一段时间轮询内存使用情况(需要 --memstats),有效的时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。(默认为 "100ms")
      --memstats string            将内存使用情况记录到这个文件中
      --minify                     缩小任何受支持的输出格式(HTML、XML 等)
      --navigateToChanged          在实时浏览器重新加载时导航到更改的内容文件
      --noBuildLock                不创建 .hugo_build.lock 文件
      --noChmod                    不同步文件的权限模式
      --noHTTPCache                防止 HTTP 缓存
      --noTimes                    不同步文件的修改时间
      --panicOnWarning             在第一个 WARNING 日志时 panic
      --poll string                将此设置为轮询间隔,例如 --poll 700ms,以使用基于轮询的方法来监视文件系统更改
  -p, --port int                   服务器将监听的端口(默认为 1313)
      --printI18nWarnings          打印缺少的翻译
      --printMemoryUsage           在一定间隔内将内存使用情况打印到屏幕上
      --printPathWarnings          打印有关重复目标路径等的警告
      --printUnusedTemplates       打印有关未使用模板的警告。
      --renderStaticToDisk         从磁盘提供静态文件,从内存提供动态文件
      --renderToDisk               从磁盘提供所有文件(默认情况下从内存提供)
  -s, --source string              相对于读取文件的文件系统路径
      --templateMetrics            显示有关模板执行的指标
      --templateMetricsHints       与 --templateMetrics 结合使用时计算一些改进提示
  -t, --theme strings              要使用的主题(位于 /themes/THEMENAME/ 中)
      --themesDir string           主题目录的文件系统路径
      --trace file                 将跟踪写入文件(通常不太有用)
  -w, --watch                      监视文件系统以进行更改,并根据需要重新创建(默认情况下为 true)

从父命令继承的选项

      --config string      配置文件(默认为 hugo.yaml|json|toml)
      --configDir string   配置目录(默认为 "config")
      --debug              调试输出
      --log                启用日志记录
      --logFile string     日志文件路径(如果设置,自动启用日志记录)
      --quiet              静默模式下构建
  -v, --verbose            冗长输出
      --verboseLog         冗长日志记录

另请参阅

  • hugo - hugo 构建您的站点

另请参阅

10.40 - hugo version

hugo version

https://gohugo.io/commands/hugo_version/

hugo version

​ 打印 Hugo 的版本号。

概要

​ 所有软件都有版本号。这是 Hugo 的版本号。

hugo version [flags]

选项

  -h, --help   help for version

从父命令继承的选项

     --clock string               设置 Hugo 使用的时钟,例如:--clock 2021-11-06T22:30:00.00+09:00
      --config string              配置文件(默认为hugo.yaml|json|toml)
      --configDir string           配置目录(默认为“config”)
      --debug                      调试输出
  -e, --environment string         构建环境
      --ignoreVendorPaths string   忽略匹配给定 Glob 模式的模块路径中的任何 _vendor
      --log                        启用日志记录
      --logFile string             日志文件路径(如果设置,则自动启用日志记录)
      --quiet                      静默模式下构建
  -s, --source string              从文件系统读取文件的相对路径
      --themesDir string           主题目录的文件系统路径
  -v, --verbose                    冗长输出
      --verboseLog                 冗长日志记录

另请参阅

  • hugo - hugo 构建您的站点

另请参阅

11 - Troubleshooting

Troubleshoot

https://gohugo.io/troubleshooting/

The Troubleshooting section includes known issues, recent workarounds, and FAQs pulled from the Hugo Discussion Forum.

11.1 - BuildPerformance

Build Performance

https://gohugo.io/troubleshooting/build-performance/

An overview of features used for diagnosing and improving performance issues in site builds.

Template Metrics

Hugo is a very fast static site generator, but it is possible to write inefficient templates. Hugo’s template metrics feature is extremely helpful in pinpointing which templates are executed most often and how long those executions take in terms of CPU time.

Metric NameDescription
cumulative durationThe cumulative time spent executing a given template.
average durationThe average time spent executing a given template.
maximum durationThe maximum time a single execution took for a given template.
countThe number of times a template was executed.
templateThe template name.
 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
34
35
36
▶ hugo --templateMetrics
Started building sites ...

Built site for language en:
0 draft content
0 future content
0 expired content
2 regular pages created
22 other pages created
0 non-page files copied
0 paginator pages created
4 tags created
3 categories created
total in 18 ms

Template Metrics:

     cumulative       average       maximum
       duration      duration      duration  count  template
     ----------      --------      --------  -----  --------
     6.419663ms     583.605µs     994.374µs     11  _internal/_default/rss.xml
     4.718511ms    1.572837ms    3.880742ms      3  indexes/category.html
     4.642666ms    2.321333ms    3.282842ms      2  posts/single.html
     4.364445ms     396.767µs    2.451372ms     11  partials/header.html
     2.346069ms     586.517µs     903.343µs      4  indexes/tag.html
     2.330919ms     211.901µs    2.281342ms     11  partials/header.includes.html
     1.238976ms     103.248µs     446.084µs     12  posts/li.html
       972.16µs      972.16µs      972.16µs      1  _internal/_default/sitemap.xml
      953.597µs     953.597µs     953.597µs      1  index.html
      822.263µs     822.263µs     822.263µs      1  indexes/post.html
      567.498µs       51.59µs     112.205µs     11  partials/navbar.html
       348.22µs      31.656µs      88.249µs     11  partials/meta.html
      346.782µs     173.391µs     276.176µs      2  posts/summary.html
      235.184µs       21.38µs     124.383µs     11  partials/footer.copyright.html
      132.003µs          12µs     117.999µs     11  partials/menu.html
       72.547µs       6.595µs      63.764µs     11  partials/footer.html

A Note About Parallelism

Hugo builds pages in parallel where multiple pages are generated simultaneously. Because of this parallelism, the sum of “cumulative duration” values is usually greater than the actual time it takes to build a site.

Cached Partials

Some partial templates such as sidebars or menus are executed many times during a site build. Depending on the content within the partial template and the desired output, the template may benefit from caching to reduce the number of executions. The partialCached template function provides caching capabilities for partial templates.

Note that you can create cached variants of each partial by passing additional parameters to partialCached beyond the initial context. See the partialCached documentation for more details.

另请参阅

11.2 - FAQ

Frequently Asked Questions

https://gohugo.io/troubleshooting/faq/

Solutions to some common Hugo problems.

Note: The answers/solutions presented below are short, and may not be enough to solve your problem. Visit Hugo Discourse and use the search. It that does not help, start a new topic and ask your questions.

I can’t see my content!

Is your Markdown file in draft mode? When testing, run hugo server with the -D or --buildDrafts switch.

Is your Markdown file part of a leaf bundle? If there is an index.md file in the same or any parent directory then other Markdown files will not be rendered as individual pages.

Can I set configuration variables via OS environment?

Yes you can! See Configure with Environment Variables.

How do I schedule posts?

  1. Set publishDate in the page Front Matter to a datetime in the future. If you want the creation and publication datetime to be the same, it’s also sufficient to only set date1.
  2. Build and publish at intervals.

How to automate the “publish at intervals” part depends on your situation:

  • If you deploy from your own PC/server, you can automate with Cron or similar.

  • If your site is hosted on a service similar to

    Netlify

    you can:

    • Use a service such as ifttt to schedule the updates
    • Set up a deploy hook which you can run with a cron service to deploy your site at intervals, such as cron-job.org (both Netlify and Cloudflare Pages support deploy hooks)

Also see this Twitter thread:

@GoHugoIO Converted https://t.co/icCzS7Ha7q from @Medium to Hugo yesterday. Once I figure out how to do scheduled posts I will be ecstatic.

— Chris Short 🇺🇸🇺🇦 (@ChrisShort)

February 10, 2018

Can I use the latest Hugo version on Netlify?

Yes you can! Read this.

I get “… this feature is not available in your current Hugo version”

If you process SCSS or Sass to CSS in your Hugo project with libsass as the transpiler or if you convert images to the webp format, you need the Hugo extended version, or else you may see an error message similar to the below:

1
error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version

We release two set of binaries for technical reasons. The extended version is not what you get by default for some installation methods. On the release page, look for archives with extended in the name. To build hugo-extended, use go install --tags extended

To confirm, run hugo version and look for the word extended.


  1. See Configure Dates for the order in which the different date variables are complemented by each other when not explicitly set. ↩︎

12 - 工具

Developer Tools

https://gohugo.io/tools/

One of Hugo’s greatest strengths is its passionate—and always evolving—developer community. With the exception of the highlight shortcode mentioned in Syntax Highlighting, the tools and other projects featured in this section are offerings from both commercial services and open-source projects, many of which are developed by Hugo developers just like you.

See the popularity of Hugo compared with other static site generators.

12.1 - EditorPlug-ins

Editor Plug-ins for Hugo

https://gohugo.io/tools/editors/

The Hugo community uses a wide range of preferred tools and has developed plug-ins for some of the most popular text editors to help automate parts of your workflow.

The Hugo community uses a wide range of preferred tools and has developed plug-ins for some of the most popular text editors to help automate parts of your workflow.

Sublime Text

  • Hugofy. Hugofy is a plugin for Sublime Text 3 to make life easier to use Hugo static site generator.
  • [Hugo Snippets](https://packagecontrol.io/packages/Hugo Snippets). Hugo Snippets is a useful plugin for adding automatic snippets to Sublime Text 3.

Visual Studio Code

  • Hugofy. Hugofy is a plugin for Visual Studio Code to “make life easier” when developing with Hugo. The source code can be found here.
  • Hugo Helper. Hugo Helper is a plugin for Visual Studio Code that has some useful commands for Hugo. The source code can be found here.
  • Hugo Language and Syntax Support. Hugo Language and Syntax Support is a Visual Studio Code plugin for Hugo syntax highlighting and snippets. The source code can be found here.
  • Hugo Themer. Hugo Themer is an extension to help you while developing themes. It allows you to easily navigate through your theme files.
  • Front Matter. Once you go for a static site, you need to think about how you are going to manage your articles. Front matter is a tool that helps you maintain the metadata/front matter of your articles like: creation date, modified date, slug, tile, SEO check, and many more…
  • Syntax Highlighting for Hugo Shortcodes. This extension add some syntax highlighting for Shortcodes, making visual identification of individual pieces easier.

Emacs

  • emacs-easy-hugo. Emacs major mode for managing hugo blogs. Note that Hugo also supports Org-mode.
  • ox-hugo.el. Native Org-mode exporter that exports to Blackfriday Markdown with Hugo front-matter. ox-hugo supports two common Org blogging flows — exporting multiple Org subtrees in a single file to multiple Hugo posts, and exporting a single Org file to a single Hugo post. It also leverages the Org tag and property inheritance features. See Why ox-hugo? for more.

Vim

  • Vim Hugo Helper. A small Vim plugin to help me with writing posts with Hugo.

Atom

  • Hugofy. A Hugo Static Website Generator package for Atom.
  • language-hugo. Adds syntax highlighting to Hugo files.

12.2 - Frontends

Frontend Interfaces with Hugo

https://gohugo.io/tools/frontends/

Do you prefer a graphical user interface over a text editor? Give these frontends a try.

  • enwrite. Enwrite enables evernote-powered, statically generated blogs and websites. Now posting to your blog or updating your website is as easy as writing a new note in Evernote!
  • Lipi. Lipi is a native GUI frontend written in Java to manage your Hugo websites.
  • Netlify CMS. Netlify CMS is an open source, serverless solution for managing Git based content in static sites, and it works on any platform that can host static sites. A Hugo/Netlify CMS starter is available to get new projects running quickly.
  • Hokus CMS. Hokus CMS is an open source, multi-platform, easy to use, desktop application for Hugo. Build from simple to complex user interfaces for Hugo websites by choosing from a dozen ready-to-use components — all for free, with no vendor lock-in.

Commercial Services

  • DATOCMS DatoCMS is a fully customizable administrative area for your static websites. Use your favorite website generator, let your clients publish new content independently, and the host the site anywhere you like.
  • CloudCannon. The intuitive Git-based CMS for your Hugo website. CloudCannon syncs changes from your Git repository and pushes content changes back, so your development and content teams are always in sync. Edit all of your content on the page with visual editing, build entire pages with reusable custom components and then publish confidently.

另请参阅

12.3 - Migrations

Migrate to Hugo

https://gohugo.io/tools/migrations/

A list of community-developed tools for migrating from your existing static site generator or content management system to Hugo.

This section highlights some projects around Hugo that are independently developed. These tools try to extend the functionality of our static site generator or help you to get started.

Do you know or maintain a similar project around Hugo? Feel free to open a pull request on GitHub if you think it should be added.

Take a look at this list of migration tools if you currently use other blogging tools like Jekyll or WordPress but intend to switch to Hugo instead. They’ll take care to export your content into Hugo-friendly formats.

Jekyll

Alternatively, you can use the new Jekyll import command.

  • JekyllToHugo - A Small script for converting Jekyll blog posts to a Hugo site.
  • ConvertToHugo - Convert your blog from Jekyll to Hugo.

Ghost

  • ghostToHugo - Convert Ghost blog posts and export them to Hugo.

Octopress

  • octohug - Octopress to Hugo migrator.

DokuWiki

  • dokuwiki-to-hugo - Migrates your DokuWiki source pages from DokuWiki syntax to Hugo Markdown syntax. Includes extra’s like the TODO plugin. Written with extensibility in mind using python 3. Also generates a TOML header for each page. Designed to copypaste the wiki directory into your /content directory.

WordPress

  • wordpress-to-hugo-exporter - A one-click WordPress plugin that converts all posts, pages, taxonomies, metadata, and settings to Markdown and YAML which can be dropped into Hugo. (Note: If you have trouble using this plugin, you can export your site for Jekyll and use Hugo’s built in Jekyll converter listed above.)
  • blog2md - Works with exported xml file of your free YOUR-TLD.wordpress.com website. It also saves approved comments to YOUR-POST-NAME-comments.md file along with posts.
  • wordhugopress - A small utility written in Java, exports the entire WordPress site from the database and resource (e.g. images) files stored locally or remotely. Therefore, migration from the backup files is possible. Supports merging of the multiple WordPress sites into a single Hugo one.

Medium

  • medium2md - A simple Medium to Hugo exporter able to import stories in one command, including Front Matter.
  • medium-to-hugo - CLI tool written in Go to export medium posts into a Hugo compatible Markdown format. Tags and images are included. All images will be downloaded locally and linked appropriately.

Tumblr

  • tumblr-importr - An importer that uses the Tumblr API to create a Hugo static site.
  • tumblr2hugomarkdown - Export all your Tumblr content to Hugo Markdown files with preserved original formatting.
  • Tumblr to Hugo - A migration tool that converts each of your Tumblr posts to a content file with a proper title and path. Furthermore, “Tumblr to Hugo” creates a CSV file with the original URL and the new path on Hugo, to help you setup the redirections.

Drupal

Joomla

  • hugojoomla - This utility written in Java takes a Joomla database and converts all the content into Markdown files. It changes any URLs that are in Joomla’s internal format and converts them to a suitable form.

Blogger

  • blogimport - A tool to import from Blogger posts to Hugo.
  • blogger-to-hugo - Another tool to import Blogger posts to Hugo. It also downloads embedded images so they will be stored locally.
  • blog2md - Works with exported xml file of your YOUR-TLD.blogspot.com website. It also saves comments to YOUR-POST-NAME-comments.md file along with posts.
  • BloggerToHugo - Yet another tool to import Blogger posts to Hugo. For Windows platform only, and .NET Framework 4.5 is required. See README.md before using this tool.

Contentful

BlogML

  • BlogML2Hugo - A tool that helps you convert BlogML xml file to Hugo Markdown files. Users need to take care of links to attachments and images by themselves. This helps the blogs that export BlogML files (e.g. BlogEngine.NET) transform to hugo sites easily.

12.4 - OtherProjects

Other Hugo Community Projects

https://gohugo.io/tools/other/

Some interesting projects developed by the Hugo community that don’t quite fit into our other developer tool categories.

And for all the other small things around Hugo:

  • hugo-gallery lets you create an image gallery for Hugo sites.
  • flickr-hugo-embed prints shortcodes to embed a set of images from an album on Flickr into Hugo.
  • hugo-openapispec-shortcode A shortcode that allows you to include Open API Spec (formerly known as Swagger Spec) in a page.
  • HugoPhotoSwipe makes it easy to create image galleries using PhotoSwipe.
  • Hugo SFTP Upload Syncs the local build of your Hugo website with your remote webserver via SFTP.
  • Emacs Easy Hugo Emacs package for writing blog posts in markdown or org-mode and building your site with Hugo.
  • JAMStack Themes. JAMStack themes is a collection of site themes filterable by static site generator and supported CMS to help build CMS-connected sites using Hugo (linking to Hugo-specific themes).
  • plausible-hugo. Easy Hugo integration for Plausible Analytics, a simple, open-source, lightweight and privacy-friendly web analytics alternative to Google Analytics.

另请参阅

12.5 - Search

Search for your Hugo Website

https://gohugo.io/tools/search/

See some of the open-source and commercial search options for your newly created Hugo website.

A static website with a dynamic search function? Yes, Hugo provides an alternative to embeddable scripts from Google or other search engines for static websites. Hugo allows you to provide your visitors with a custom search function by indexing your content files directly.

  • GitHub Gist for Hugo Workflow. This gist contains a simple workflow to create a search index for your static website. It uses a simple Grunt script to index all your content files and lunr.js to serve the search results.
  • hugo-lunr. A simple way to add site search to your static Hugo site using lunr.js. Hugo-lunr will create an index file of any HTML and Markdown documents in your Hugo project.
  • hugo-lunr-zh. A bit like Hugo-lunr, but Hugo-lunr-zh can help you separate the Chinese keywords.
  • GitHub Gist for Fuse.js integration. This gist demonstrates how to leverage Hugo’s existing build time processing to generate a searchable JSON index used by Fuse.js on the client-side. Although this gist uses Fuse.js for fuzzy matching, any client-side search tool capable of reading JSON indexes will work. Does not require npm, grunt or other build-time tools except Hugo!
  • hugo-search-index. A library containing Gulp tasks and a prebuilt browser script that implements search. Gulp generates a search index from project markdown files.
  • hugofastsearch. A usability and speed update to “GitHub Gist for Fuse.js integration” — global, keyboard-optimized search.
  • JS & Fuse.js tutorial A simple client-side search solution, using FuseJS (does not require jQuery).
  • Pagefind. A fully static search library that aims to perform well on large sites, while using as little of your users’ bandwidth as possible.
  • Hugo Lyra. Hugo-Lyra is a JavaScript module to integrate Lyra into a Hugo website. It contains the server-side part to generate the index and the client-side library (optional) to bootstrap the search engine easily.

Commercial Search Services

  • Algolia’s Search API makes it easy to deliver a great search experience in your apps and websites. Algolia Search provides hosted full-text, numerical, faceted, and geolocalized search.
  • Bonsai is a fully-managed hosted Elasticsearch service that is fast, reliable, and simple to set up. Easily ingest your docs from Hugo into Elasticsearch following this guide from the docs.
  • ExpertRec is a hosted search-as-a-service solution that is fast and scalable. Set-up and integration is extremely easy and takes only a few minutes. The search settings can be modified without coding using a dashboard.

12.6 - StarterKits

Starter Kits

https://gohugo.io/tools/starter-kits/

A list of community-developed projects designed to help you get up and running with Hugo.

Know of a Hugo-related starter kit that isn’t mentioned here? Please add it to the list.

The following starter kits are developed by active members of the Hugo community. If you find yourself having issues with any of the projects, it’s best to file an issue directly with the project’s maintainer(s).

  • Wowchemy. Wowchemy is the 5,500+ star open source Hugo starter kit and website builder trusted by 750,000+ sites since 2016. Create any kind of site with 50+ templates, widgets, and extensions. Translated into 35+ languages and backed by a large, active community of 150+ contributors.
  • Hugo Wrapper. Hugo Wrapper is a POSIX-style shell script which acts as a wrapper to download and run Hugo binary for your platform. It can be executed in variety of Operating Systems and Command Shells.
  • GOHUGO AMP. GoHugo AMP is a starter theme that aims to make it easy to adopt Google’s AMP Project. The starter kit comes with 40+ shortcodes and partials plus automatic structured data. The project also includes a separate site with extensive documentation.
  • Hyas. Hyas is a Hugo starter helping you build modern websites that are secure, fast, and SEO-ready — by default. It is Netlify-ready (functions, redirects, headers) and comes with documentation to easily make it your own.

13 - Hosting & 部署

Hosting & Deployment

https://gohugo.io/hosting-and-deployment/

Because Hugo renders static websites, you can host your new Hugo website virtually anywhere. The following represent only a few of the more popular hosting and automated deployment solutions used by the Hugo community.

13.1 - Deployment with Rclone

Deployment with Rclone

https://gohugo.io/hosting-and-deployment/deployment-with-rclone/

If you have access to your web host with SFTP/FTP/SSH/HTTP(DAV), you can use rclone to incrementally deploy your entire Hugo website.

Assumptions

  • A web host running a web server. This could be a shared hosting environment or a VPS.
  • Access to your web host with any of the protocols supported by rclone, such as SFTP.
  • A functional static website built with Hugo
  • Deploying from an Rclone compatible operating system
  • You have installed Rclone.

NB: You can remove --interactive in the commands below once you are comfortable with rclone, if you wish. Also, --gc and --minify are optional in the hugo commands below.

Getting Started

The spoiler is that you can even deploy your entire website from any compatible OS with no configuration. Using SFTP for example:

1
2
hugo --gc --minify
rclone sync --interactive --sftp-host sftp.example.com --sftp-user www-data --sftp-ask-password public/ :sftp:www/

Configure Rclone for Even Easier Usage

The easiest way is simply to run rclone config.

The Rclone docs provide an example of configuring Rclone to use SFTP.

For the next commands, we will assume you configured a remote you named hugo-www

The above ‘spoiler’ commands could become:

1
2
hugo --gc --minify
rclone sync --interactive public/ hugo-www:www/

After you issue the above commands (and respond to any prompts), check your website and you will see that it is deployed.

另请参阅

13.2 - Deployment with Rsync

Deployment with Rsync

https://gohugo.io/hosting-and-deployment/deployment-with-rsync/

If you have access to your web host with SSH, you can use a simple rsync one-liner to incrementally deploy your entire Hugo website.

Assumptions

  • A web host running a web server. This could be a shared hosting environment or a VPS.
  • Access to your web host with SSH
  • A functional static website built with Hugo

The spoiler is that you can deploy your entire website with a command that looks like the following:

1
hugo && rsync -avz --delete public/ www-data@ftp.topologix.fr:~/www/

As you will see, we’ll put this command in a shell script file, which makes building and deployment as easy as executing ./deploy.

Copy Your SSH Key to your Host

To make logging in to your server more secure and less interactive, you can upload your SSH key. If you have already installed your SSH key to your server, you can move on to the next section.

First, install the ssh client. On Debian distributions, use the following command:

install-openssh.sh

1
sudo apt-get install openssh-client

Then generate your ssh key. First, create the .ssh directory in your home directory if it doesn’t exist:

1
~$ cd && mkdir .ssh & cd .ssh

Next, execute this command to generate a new keypair called rsa_id:

1
~/.ssh/$ ssh-keygen -t rsa -q -C "For SSH" -f rsa_id

You’ll be prompted for a passphrase, which is an extra layer of protection. Enter the passphrase you’d like to use, and then enter it again when prompted, or leave it blank if you don’t want to have a passphrase. Not using a passphrase will let you transfer files non-interactively, as you won’t be prompted for a password when you log in, but it is slightly less secure.

To make logging in easier, add a definition for your web host to the file ~/.ssh/config with the following command, replacing HOST with the IP address or hostname of your web host, and USER with the username you use to log in to your web host when transferring files:

1
2
3
4
5
6
7
~/.ssh/$ cat >> config <<EOF
Host HOST
     Hostname HOST
     Port 22
     User USER
     IdentityFile ~/.ssh/rsa_id
EOF

Then copy your ssh public key to the remote server with the ssh-copy-id command:

1
~/.ssh/$ ssh-copy-id -i rsa_id.pub USER@HOST.com

Now you can easily connect to the remote server:

1
2
~$ ssh user@host
Enter passphrase for key '/home/mylogin/.ssh/rsa_id':

Now that you can log in with your SSH key, let’s create a script to automate deployment of your Hugo site.

Shell Script

Create a new script called deploy the root of your Hugo tree:

1
~/websites/topologix.fr$ editor deploy

Add the following content. Replace the USER, HOST, and DIR values with your own values:

1
2
3
4
5
6
7
8
#!/bin/sh
USER=my-user
HOST=my-server.com
DIR=my/directory/to/topologix.fr/   # the directory where your web site files should go

hugo && rsync -avz --delete public/ ${USER}@${HOST}:~/${DIR} # this will delete everything on the server that's not in the local public folder 

exit 0

Note that DIR is the relative path from the remote user’s home. If you have to specify a full path (for instance /var/www/mysite/) you must change ~/${DIR} to ${DIR} inside the command-line. For most cases you should not have to.

Save and close, and make the deploy file executable:

1
~/websites/topologix.fr$ chmod +x deploy

Now you only have to enter the following command to deploy and update your website:

1
~/websites/topologix.fr$ ./deploy

Your site builds and deploys:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
Started building sites ...
Built site for language en:
0 draft content
0 future content
0 expired content
5 pages created
0 non-page files copied
0 paginator pages created
0 tags created
0 categories created
total in 56 ms
sending incremental file list
404.html
index.html
index.xml
sitemap.xml
posts/
posts/index.html

sent 9,550 bytes  received 1,708 bytes  7,505.33 bytes/sec
total size is 966,557  speedup is 85.86

You can incorporate other proprocessing tasks into this deployment script as well.

另请参阅

13.3 - Host on 21YunBox

Host on 21YunBox

https://gohugo.io/hosting-and-deployment/hosting-on-21yunbox/

Host your Hugo site with 21YunBox’s blazing fast Chinese CDN, fully-managed SSL and auto deploys from Gitee.

21YunBox is a fully-managed cloud platform dedicated to make web deployment easy within the Chinese Great Firewall where you can host static sites, backend APIs, databases, cron jobs, and all your other apps in one place. It provides blazing fast Chinese CDN, continuous deployment, one-click HTTPS and other services like managed databases and backend web services, providing an avenue to launch web projects in China.

21YunBox includes the following features:

  • Continuous, automatic builds & deploys from GitHub and Gitee
  • Automatic SSL certificates through Let’s Encrypt
  • Instant cache invalidation with a blazing fast, Chinese CDN
  • Unlimited custom domains
  • Automatic Brotli compression for faster sites
  • Native HTTP/2 support
  • Automatic HTTP → HTTPS redirects
  • Custom URL redirects and rewrites

Prerequisites

This guide assumes you already have a Hugo project to deploy. If you need a project, use the Quick Start to get started or fork 21YunBox’s Hugo Example before continuing.

Setup

You can set up a Hugo site on 21YunBox in two quick steps:

  1. Create a new web service on 21YunBox, and give 21YunBox permission to access your GitHub or Gitee repo.

  2. Use the following values during creation:

    FieldValue
    EnvironmentStatic Site
    Build Commandhugo --gc --minify (or your own build command)
    Publish Directory./public (or your own output directory)

That’s it! Your site will be live on your 21YunBox URL (which looks like yoursite.21yunbox.com) as soon as the build is done.

Continuous deploys

Now that 21YunBox is connected to your repo, it will automatically build and publish your site any time you push to GitHub.

Every deploy automatically and instantly invalidates the CDN cache, so your users can always access the latest content on your site.

Custom domains

Add your own domains to your site easily using 21YunBox’s custom domains guide.

Support

Click here to contact with 21YunBox’ experts if you need help.

另请参阅

13.4 - Host on AWS Amplify

Host on AWS Amplify

https://gohugo.io/hosting-and-deployment/hosting-on-aws-amplify/

Develop and deploy a cloud-powered web app with AWS Amplify.

In this guide we’ll walk through how to deploy and host your Hugo site using the AWS Amplify Console.

AWS Amplify is a combination of client library, CLI toolchain, and a Console for continuous deployment and hosting. The Amplify CLI and library allow developers to get up & running with full-stack cloud-powered applications with features like authentication, storage, serverless GraphQL or REST APIs, analytics, Lambda functions, & more. The Amplify Console provides continuous deployment and hosting for modern web apps (single page apps and static site generators). Continuous deployment allows developers to deploy updates to their web app on every code commit to their Git repository. Hosting includes features such as globally available CDNs, easy custom domain setup + HTTPS, feature branch deployments, and password protection.

Pre-requisites

  • Sign up for an AWS Account. There are no upfront charges or any term commitments to create an AWS account and signing up gives you immediate access to the AWS Free Tier.
  • You have an account with GitHub, GitLab, or Bitbucket.
  • You have completed the Quick Start or have a Hugo website you are ready to deploy and share with the world.

Hosting

  1. Log in to the AWS Amplify Console and choose Get Started under Deploy. Hugo Amplify
  2. Connect a branch from your GitHub, Bitbucket, GitLab, or AWS CodeCommit repository. Connecting your repository allows Amplify to deploy updates on every code commit to a branch. Hugo Amplify
  3. Accept the default build settings. The Amplify Console automatically detects your Hugo build settings and output directory. Hugo Amplify
  4. Review your changes and then choose Save and deploy. The Amplify Console will pull code from your repository, build changes to the backend and frontend, and deploy your build artifacts at https://master.unique-id.amplifyapp.com. Bonus: Screenshots of your app on different devices to find layout issues.

Using a newer version of Hugo

If you need to use a different, perhaps newer, version of Hugo than the version currently supported by AWS Amplify:

  1. Visit the AWS Amplify Console, and click the app you would like to modify
  2. In the side navigation bar, Under App Settings, click Build settings
  3. On the Build settings page, near the bottom, there is a section called Build image settings. Click Edit
  4. Under Live package updates, click Add package version override
  5. From the selection, click Hugo and ensure the version field says latest
  6. Click Save to save the changes.

另请参阅

13.5 - Host on Azure Static Web Apps

Host on Azure Static Web Apps

https://gohugo.io/hosting-and-deployment/hosting-on-azure/

Deploy Hugo to Azure Static Web Apps and automate the whole process with Github Action Workflow

Azure Static Web Apps is a service that automatically builds and deploys full stack web apps to Azure from a Git repository, using GitHub Actions or Azure DevOps.

The following documentation covers how to use GitHub Actions for the deployment. If you are using Azure DevOps, follow the Microsoft documentation.

Assumptions

  1. You have Git 2.8 or greater installed on your machine.
  2. You have a GitHub account. Signing up for GitHub is free.
  3. You have an Azure account. You can sign up for a Free Trail.
  4. You have a ready-to-publish Hugo website or have at least completed the Quick Start.

Deploy Hugo to Azure Static Web Apps

  1. Navigate to the Azure Portal
  2. Click Create a Resource
  3. Search for Static Web Apps
  4. Click Static Web Apps
  5. Click Create

Create in Azure Portal

  1. For Subscription, accept the subscription that is listed or select a new one from the drop-down list.
  2. In Resource group, select New. In New resource group name, enter hugo-static-app and select OK.
  3. Next, a name for your app in the Name box. Valid characters include a-z, A-Z, 0-9 and -.
  4. For Region, select an available region close to you.
  5. For SKU, select Free.

Basic app details

  1. Click the Sign in with GitHub button.
  2. Select the Organization under which your repo exists.
  3. Select the Hugo app you wish to deploy as the Repository .
  4. For the Branch select the branch you want to deploy (eg: main).
  5. Select Hugo under the Build Presets, which will populate the configuration files with the standard Hugo build options
  • App Location is the path in the Git repo where Hugo’s config file is
  • Api Location is the path where the Serverless API is (or left blank if there is no API)
  • Artifact Location is the path where Hugo publishes to
  1. Click Review + Create to review the details and then Create to start the creation of the Azure Static Web Apps and create the GitHub Action workflow for deployment.

A GitHub Action workflow will immediately start a build using Hugo and deployment to Azure. The website can be accessed via the URL shown on the Overview page of the Azure Static Web Apps resource in Azure.

Using A Custom Hugo Version

When you create a Static Web App, a workflow file is generated which contains the deployment settings for the site. You can configure a specific Hugo version in the workflow file by providing a value for HUGO_VERSION in the env section of the Azure/static-web-apps-deploy GitHub Action.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
jobs:
  build_and_deploy_job:
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
    runs-on: ubuntu-latest
    name: Build and Deploy Job
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: true
      - name: Build And Deploy
        id: builddeploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          action: "upload"
          app_location: "/" # App source code path
          api_location: "api" # Api source code path - optional
          output_location: "public" # Built app content directory - optional
        env:
          HUGO_VERSION: 0.100.2

Use a Custom Domain

Azure Static Web Apps supports custom domains as a CNAME or APEX domain mapping. You can configure the custom domains via the Azure Portal. Refer to the official documentation for custom domains for more information.

另请参阅

13.6 - Host on Cloudflare Pages

Host on Cloudflare Pages

https://gohugo.io/hosting-and-deployment/hosting-on-cloudflare-pages/

Cloudflare Pages can host your Hugo site with CDN, continuous deployment, 1-click HTTPS, an admin GUI, and its own environment variables.

Cloudflare Pages are super fast, always up-to-date, and deployed directly from your Git provider (currently supports only GitHub and GitLab).

Cloudflare Pages docs have a detailed tutorial on how to deploy a Hugo site.

13.7 - Host on Firebase

Host on Firebase

https://gohugo.io/hosting-and-deployment/hosting-on-firebase/

You can use Firebase’s free tier to host your static website; this also gives you access to Firebase’s NOSQL API.

Assumptions

  1. You have an account with Firebase. (If you don’t, you can sign up for free using your Google account.)
  2. You have completed the Quick Start or have a completed Hugo website ready for deployment.

Initial setup

Go to the Firebase console and create a new project (unless you already have a project). You will need to globally install firebase-tools (node.js):

1
npm install -g firebase-tools

Log in to Firebase (setup on your local machine) using firebase login, which opens a browser where you can select your account. Use firebase logout in case you are already logged in but to the wrong account.

1
firebase login

In the root of your Hugo project, initialize the Firebase project with the firebase init command:

1
firebase init

From here:

  1. Choose Hosting in the feature question
  2. Choose the project you just set up
  3. Accept the default for your database rules file
  4. Accept the default for the publish directory, which is public
  5. Choose “No” in the question if you are deploying a single-page app

Using Firebase & Github CI/CD

In new versions of Firebase, some other questions apply:

  1. Set up automatic builds and deploys with GitHub?

Here you will be redirected to login in your GitHub account to get permissions. Confirm.

  1. For which GitHub repository would you like to set up a GitHub workflow? (format: user/repository)

Include the repository you will use in the format above (Account/Repo) Firebase script with retrive credentials, create a service account you can later manage in your github settings.

  1. Set up the workflow to run a build script before every deploy?

Here is your opportunity to include some commands before you run the deploy.

  1. Set up automatic deployment to your site’s live channel when a PR is merged?

You can let in the default option (main)

After that Firebase has been set in your project with CI/CD. After that run:

hugo && firebase deploy

With this you will have the app initialized manually. After that you can manage and fix your github workflow from: https://github.com/your-account/your-repo/actions

Don’t forget to update your static pages before push!

Manual Deploy

To deploy your Hugo site, execute the firebase deploy command, and your site will be up in no time:

1
hugo && firebase deploy

CI Setup (Other tools)

You can generate a deploy token using

1
firebase login:ci

You can also set up your CI and add the token to a private variable like $FIREBASE_DEPLOY_TOKEN.

This is a private secret and it should not appear in a public repository. Make sure you understand your chosen CI and that it’s not visible to others.

You can then add a step in your build to do the deployment using the token:

1
firebase deploy --token $FIREBASE_DEPLOY_TOKEN

另请参阅

13.8 - Host on GitHub

Host on GitHub

https://gohugo.io/hosting-and-deployment/hosting-on-github/

Deploy Hugo as a GitHub Pages project or personal/organizational site and automate the whole process with Github Actions

GitHub provides free and fast static hosting over SSL for personal, organization, or project pages directly from a GitHub repository via its GitHub Pages service and automating development workflows and build with GitHub Actions.

Prerequisites

  1. Create a GitHub account
  2. Install Git
  3. Create a Hugo site and test it locally with hugo server.

Types of sites

There are three types of GitHub Pages sites: project, user, and organization. Project sites are connected to a specific project hosted on GitHub. User and organization sites are connected to a specific account on GitHub.com.

See the GitHub Pages documentation to understand the requirements for repository ownership and naming.

Procedure

  • Step 1

    Create a GitHub repository.

  • Step 2

    Push your local repository to GitHub.

  • Step 3

    Visit your GitHub repository. From the main menu choose Settings > Pages. In then center of your screen you will see this:

screen capture

  • Step 4

    Change the Source to GitHub Actions. The change is immediate; you do not have to press a Save button.

screen capture

  • Step 5

    Create an empty file in your local repository.

1
.github/workflows/hugo.yaml
  • Step 6

    Copy and paste the YAML below into the file you created. Change the branch name and Hugo version as needed.

.github/workflows/hugo.yaml

 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# Sample workflow for building and deploying a Hugo site to GitHub Pages
name: Deploy Hugo site to Pages

on:
  # Runs on pushes targeting the default branch
  push:
    branches:
      - main

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

# Default to bash
defaults:
  run:
    shell: bash

jobs:
  # Build job
  build:
    runs-on: ubuntu-latest
    env:
      HUGO_VERSION: 0.111.3
    steps:
      - name: Install Hugo CLI
        run: |
          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
          && sudo dpkg -i ${{ runner.temp }}/hugo.deb                    
      - name: Install Dart Sass Embedded
        run: sudo snap install dart-sass-embedded
      - name: Checkout
        uses: actions/checkout@v3
        with:
          submodules: recursive
          fetch-depth: 0
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v3
      - name: Install Node.js dependencies
        run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
      - name: Build with Hugo
        env:
          # For maximum backward compatibility with Hugo modules
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production
        run: |
          hugo \
            --gc \
            --minify \
            --baseURL "${{ steps.pages.outputs.base_url }}/"                    
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path: ./public

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2
  • Step 7

    Commit the change to your local repository with a commit message of something like “Add workflow”, and push to GitHub.

  • Step 8

    From GitHub’s main menu, choose Actions. You will see something like this:

screen capture

  • Step 9

    When GitHub has finished building and deploying your site, the color of the status indicator will change to green.

screen capture

  • Step 10

    Click on the commit message as shown above. You will see this:

screen capture

Under the deploy step, you will see a link to your live site.

In the future, whenever you push a change from your local repository, GitHub will rebuild your site and deploy the changes.

Additional resources

另请参阅

13.9 - Host on GitLab

Host on GitLab

https://gohugo.io/hosting-and-deployment/hosting-on-gitlab/

GitLab makes it easy to build, deploy, and host your Hugo website via their free GitLab Pages service, which provides native support for Hugo.

Assumptions

  • Working familiarity with Git for version control
  • Completion of the Hugo Quick Start
  • A GitLab account
  • A Hugo website on your local machine that you are ready to publish

BaseURL

The baseURL in your site configuration must reflect the full URL of your GitLab pages repository if you are using the default GitLab Pages URL (e.g., https://<YourUsername>.gitlab.io/<your-hugo-site>/) and not a custom domain.

Configure GitLab CI/CD

Define your CI/CD jobs by creating a .gitlab-ci.yml file in the root of your project.

.gitlab-ci.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
image: registry.gitlab.com/pages/hugo/hugo_extended:latest

variables:
  GIT_SUBMODULE_STRATEGY: recursive

pages:
  script:
  - hugo
  artifacts:
    paths:
    - public
  rules:
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

See this list if you wish to use a particular Hugo version to build your site.

Push your Hugo website to GitLab

Next, create a new repository on GitLab. It is not necessary to make the repository public. In addition, you might want to add /public to your .gitignore file, as there is no need to push compiled assets to GitLab or keep your output website in version control.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# initialize new git repository
git init

# add /public directory to our .gitignore file
echo "/public" >> .gitignore

# commit and push code to master branch
git add .
git commit -m "Initial commit"
git remote add origin https://gitlab.com/YourUsername/your-hugo-site.git
git push -u origin master

Wait for your page to build

That’s it! You can now follow the CI agent building your page at https://gitlab.com/<YourUsername>/<your-hugo-site>/pipelines.

After the build has passed, your new website is available at https://<YourUsername>.gitlab.io/<your-hugo-site>/.

Next steps

GitLab supports using custom CNAME’s and TLS certificates. For more details on GitLab Pages, see the GitLab Pages setup documentation.

另请参阅

13.10 - Host on KeyCDN

Host on KeyCDN

https://gohugo.io/hosting-and-deployment/hosting-on-keycdn/

Accelerate your Hugo site globally with a KeyCDN integration. This tutorial shows you how to set up your static site as a GitLab page behind a KeyCDN pull zone.

KeyCDN provides a multitude of features to help accelerate and secure your Hugo site globally including Brotli compression, Let’s Encrypt support, Origin Shield, and more.

Assumptions

  • You already have a Hugo page configured
  • You have a GitLab account
  • You have a KeyCDN account

Create a KeyCDN Pull Zone

The first step will be to log in to your KeyCDN account and create a new zone. Name this whatever you like and select the Pull Zone option. As for the origin URL, your site will be running on GitLab Pages with a URL of https://youruser.gitlab.io/reponame/. Use this as the Origin URL.

Screenshot of KeyCDN’s pull zone creation page

While the origin location doesn’t exist yet, you will need to use your new Zone URL address (or Zone Alias) in the .gitlab-ci.yml file that will be uploaded to your GitLab project.

Ensure that you use your Zone URL or Zone alias as the BASEURL variable in the example below. This will be the user-visible website address.

Configure Your .gitlab-ci.yml File

Your .gitlab-ci.yml file should look similar to the example below. Be sure to modify any variables that are specific to your setup.

 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
image: alpine:latest

variables:
    BASEURL: "https://cipull-7bb7.kxcdn.com/"
    HUGO_VERSION: "0.26"
    HUGO_CHECKSUM: "67e4ba5ec2a02c8164b6846e30a17cc765b0165a5b183d5e480149baf54e1a50"
    KEYCDN_ZONE_ID: "75544"

before_script:
    - apk update
    - apk add curl

pages:
    stage: deploy
    script:
    - apk add git
    - git submodule update --init
    - curl -sSL https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz -o /tmp/hugo.tar.gz
    - echo "${HUGO_CHECKSUM}  /tmp/hugo.tar.gz" | sha256sum -c
    - tar xf /tmp/hugo.tar.gz hugo -C /tmp/ && cp /tmp/hugo /usr/bin
    - hugo --baseURL ${BASEURL}
    - curl "https://api.keycdn.com/zones/purge/${KEYCDN_ZONE_ID}.json" -u "${KEYCDN_API_KEY}:"
    artifacts:
    paths:
    - public
    only:
    - master

Using this integration method, you will have to specify the Zone ID and your KeyCDN API key as secret variables. To do this, navigate to the top-left menu bar in GitLab and select Projects. Then, select your project and click on the Settings page. Finally, select Pipelines from the sub-menu and scroll down to the Secret Variable section.

The Secret Variable for your Zone ID should look similar to:

Screenshot of setting the Zone ID secret variable

While the Secret Variable for your API Key will look similar to:

Screenshot of setting the API Key secret variable

The Zone ID and API key are used to purge your zone – it’s not strictly needed but otherwise, the CDN might deliver older versions of your assets for quite a while.

Push Your Changes to GitLab

Now it’s time to push the newly created repository to GitLab:

1
2
git remote add origin git@gitlab.com:youruser/ci-example.git
git push -u origin master

You can watch the progress and CI job output in your Gitlab project under “Pipelines”.

After verifying your CI job ran without issues, first check that your GitLab page shows up under https://youruser.gitlab.io/reponame/ (it might look broken depending on your browser settings as all links point to your KeyCDN zone – don’t worry about that) and then by heading to whatever Zone alias / Zone URL you defined.

To learn more about Hugo hosting options with KeyCDN, check out the complete Hugo hosting with KeyCDN integration guide.

另请参阅

13.11 - Host on Netlify

Host on Netlify

https://gohugo.io/hosting-and-deployment/hosting-on-netlify/

Netlify can host your Hugo site with CDN, continuous deployment, 1-click HTTPS, an admin GUI, and its own CLI.

Netlify provides continuous deployment services, global CDN, ultra-fast DNS, atomic deploys, instant cache invalidation, one-click SSL, a browser-based interface, a CLI, and many other features for managing your Hugo website.

Assumptions

  • You have an account with GitHub, GitLab, or Bitbucket.
  • You have completed the Quick Start or have a Hugo website you are ready to deploy and share with the world.
  • You do not already have a Netlify account.

Create a Netlify account

Go to app.netlify.com and select your preferred signup method. This will likely be a hosted Git provider, although you also have the option to sign up with an email address.

The following examples use GitHub, but other git providers will follow a similar process.

Screenshot of the homepage for app.netlify.com, containing links to the most popular hosted git solutions.

Selecting GitHub will bring up an authorization modal for authentication. Select “Authorize application.”

Screenshot of the authorization popup for Netlify and GitHub.

Create a new site with continuous deployment

You’re now already a Netlify member and should be brought to your new dashboard. Select “New site from git.”

Screenshot of the blank Netlify admin panel with no sites and highlighted ‘add new site’ button’

Netlify will then start walking you through the steps necessary for continuous deployment. First, you’ll need to select your git provider again, but this time you are giving Netlify added permissions to your repositories.

Screenshot of step 1 of create a new site for Netlify: selecting the git provider

And then again with the GitHub authorization modal:

Screenshot of step 1 of create a new site for Netlify: selecting the git provider

Select the repo you want to use for continuous deployment. If you have a large number of repositories, you can filter through them in real time using repo search:

Screenshot of step 1 of create a new site for Netlify: selecting the git provider

Once selected, you’ll be brought to a screen for basic setup. Here you can select the branch you want to publish, your build command, and your publish (i.e. deploy) directory. The publish directory should mirror that of what you’ve set in your site configuration, the default of which is public. The following steps assume you are publishing from the master branch.

Configure Hugo version in Netlify

You can set Hugo version for your environments in netlify.toml file or set HUGO_VERSION as a build environment variable in the Netlify console.

For production:

netlify.toml

1
2
[context.production.environment]
  HUGO_VERSION = "0.99.1"

For testing:

netlify.toml

1
2
[context.deploy-preview.environment]
  HUGO_VERSION = "0.99.1"

The Netlify configuration file can be a little hard to understand and get right for the different environment, and you may get some inspiration and tips from this site’s netlify.toml:

 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
34
35
[build]
publish = "public"
command = "hugo --gc --minify"

[context.production.environment]
HUGO_VERSION = "0.111.3"
HUGO_ENV = "production"
HUGO_ENABLEGITINFO = "true"

[context.split1]
command = "hugo --gc --minify --enableGitInfo"

[context.split1.environment]
HUGO_VERSION = "0.111.3"
HUGO_ENV = "production"

[context.deploy-preview]
command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"

[context.deploy-preview.environment]
HUGO_VERSION = "0.111.3"

[context.branch-deploy]
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"

[context.branch-deploy.environment]
HUGO_VERSION = "0.111.3"

[context.next.environment]
HUGO_ENABLEGITINFO = "true"

[[redirects]]
from = "/npmjs/*"
to = "/npmjs/"
status = 200

Build and Deploy Site

In the Netlify console, selecting “Deploy site” will immediately take you to a terminal for your build:.

Animated gif of deploying a site to Netlify, including the terminal read out for the build.

Once the build is finished—this should only take a few seconds–you should now see a “Hero Card” at the top of your screen letting you know the deployment is successful. The Hero Card is the first element that you see in most pages. It allows you to see a quick summary of the page and gives access to the most common/pertinent actions and information. You’ll see that the URL is automatically generated by Netlify. You can update the URL in “Settings.”

Screenshot of successful deploy badge at the top of a deployments screen from within the Netlify admin.

Screenshot of homepage to https://hugo-netlify-example.netlify.com, which is mostly dummy text

Visit the live site.

Now every time you push changes to your hosted git repository, Netlify will rebuild and redeploy your site.

See this blog post for more details about how Netlify handles Hugo versions.

Use Hugo Themes with Netlify

The git clone method for installing themes is not supported by Netlify. If you were to use git clone, it would require you to recursively remove the .git subdirectory from the theme folder and would therefore prevent compatibility with future versions of the theme.

A better approach is to install a theme as a proper git submodule. You can read the GitHub documentation for submodules or those found on Git’s website for more information, but the command is similar to that of git clone:

1
2
cd themes
git submodule add https://github.com/<THEMECREATOR>/<THEMENAME>

It is recommended to only use stable versions of a theme (if it’s versioned) and always check the changelog. This can be done by checking out a specific release within the theme’s directory.

Switch to the theme’s directory and list all available versions:

1
2
3
cd themes/<theme>
git tag
# exit with q

You can checkout a specific version as follows:

1
git checkout tags/<version-name>

You can update a theme to the latest version by executing the following command in the root directory of your project:

1
git submodule update --rebase --remote

Next Steps

You now have a live website served over HTTPS, distributed through CDN, and configured for continuous deployment. Dig deeper into the Netlify documentation:

  1. Using a Custom Domain
  2. Setting up HTTPS on Custom Domains
  3. Redirects and Rewrite Rules

另请参阅

13.12 - Host on Render

Host on Render

https://gohugo.io/hosting-and-deployment/hosting-on-render/

Host your Hugo site for free with Render’s global CDN, fully-managed SSL and auto deploys from GitHub.

Introduction

Render is a fully-managed cloud platform where you can host static sites, backend APIs, databases, cron jobs, and all your other apps in one place.

Static sites are completely free on Render and include the following:

Assumptions

  • You have an account with GitHub or GitLab.
  • You have completed the Quick Start or have a Hugo website you are ready to deploy and share with the world.
  • You have a Render account. You can sign up at https://render.com/register.

Deployment

You can set up a Hugo site on Render in two quick steps:

  1. Create a new Static Site on Render, and give Render permission to access your GitHub/Gitlab repo.
  2. Use the following values during creation:
FieldValue
Build Commandhugo --gc --minify (or your own build command)
Publish Directorypublic (or your own output directory)

That’s it! Your site will be live on your Render URL (which looks like yoursite.onrender.com) as soon as the build is done.

Continuous Deploys

Now that Render is connected to your repo, it will automatically build and publish your site any time you push to your GitHub/Gitlab.

You can choose to disable auto deploys under the Settings section for your site and deploy it manually from the Render dashboard.

CDN and Cache Invalidation

Render hosts your site on a global, lightning fast CDN which ensures the fastest possible download times for all your users across the globe.

Every deploy automatically and instantly invalidates the CDN cache, so your users can always access the latest content on your site.

Custom Domains

Add your own domains to your site easily using Render’s custom domains guide.

Pull Request Previews

With Pull Request (PR) previews, you can visualize changes introduced in a pull request instead of simply relying on code reviews.

Once enabled, every PR for your site will automatically generate a new static site based on the code in the PR. It will have its own URL, and it will be deleted automatically when the PR is closed.

Read more about Pull Request Previews on Render.

Hugo Themes

Render automatically downloads all Git submodules defined in your Git repo on every build. This way Hugo themes added as submodules work as expected.

Support

Chat with Render developers at https://render.com/chat or email support@render.com if you need help.

另请参阅

13.13 - Hosting on Azure Static Web Apps

Hosting on Azure Static Web Apps

https://gohugo.io/hosting-and-deployment/hosting-on-azure-static-web-apps/

Learn how to deploy a Hugo application to Azure Static Web Apps.

You can create and deploy a Hugo web application to Azure Static Web Apps. The final result is a new Azure Static Web App with associated GitHub Actions that give you control over how the app is built and published. You’ll learn how to create a Hugo app, set up an Azure Static Web App and deploy the Hugo app to Azure.

Here’s the tutorial on how to Publish a Hugo site to Azure Static Web Apps.

另请参阅

13.14 - Hugo Deploy

Hugo Deploy

https://gohugo.io/hosting-and-deployment/hugo-deploy/

You can upload your site to GCS, S3, or Azure using the Hugo CLI.

You can use the “hugo deploy” command to upload your site directly to a Google Cloud Storage (GCS) bucket, an AWS S3 bucket, and/or an Azure Storage container.

Assumptions

Create a bucket to deploy to

Create a storage bucket to deploy your site to. If you want your site to be public, be sure to configure the bucket to be publicly readable.

Google Cloud Storage (GCS)

Follow the GCS instructions for how to create a bucket.

AWS S3

Follow the AWS instructions for how to create a bucket.

Azure Storage

Follow the Azure instructions for how to create a storage container.

Configure the deployment

In the configuration file for your site, add a [deployment] section with one or more [[deployment.targets]] section, one for each deployment target. Here’s a detailed example:

 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
[deployment]
# By default, files are uploaded in an arbitrary order.
# Files that match the regular expressions in the "Order" list
# will be uploaded first, in the listed order.
order = [".jpg$", ".gif$"]


[[deployment.targets]]
# An arbitrary name for this target.
name = "mydeployment"
# The Go Cloud Development Kit URL to deploy to. Examples:
# GCS; see https://gocloud.dev/howto/blob/#gcs
# URL = "gs://<Bucket Name>"

# S3; see https://gocloud.dev/howto/blob/#s3
# For S3-compatible endpoints, see https://gocloud.dev/howto/blob/#s3-compatible
# URL = "s3://<Bucket Name>?region=<AWS region>"

# Azure Blob Storage; see https://gocloud.dev/howto/blob/#azure
# URL = "azblob://$web"

# You can use a "prefix=" query parameter to target a subfolder of the bucket:
# URL = "gs://<Bucket Name>?prefix=a/subfolder/"

# If you are using a CloudFront CDN, deploy will invalidate the cache as needed.
cloudFrontDistributionID = <ID>

# Optionally, you can include or exclude specific files.
# See https://godoc.org/github.com/gobwas/glob#Glob for the glob pattern syntax.
# If non-empty, the pattern is matched against the local path.
# All paths are matched against in their filepath.ToSlash form.
# If exclude is non-empty, and a local or remote file's path matches it, that file is not synced.
# If include is non-empty, and a local or remote file's path does not match it, that file is not synced.
# As a result, local files that don't pass the include/exclude filters are not uploaded to remote,
# and remote files that don't pass the include/exclude filters are not deleted.
# include = "**.html" # would only include files with ".html" suffix
# exclude = "**.{jpg, png}" # would exclude files with ".jpg" or ".png" suffix


# [[deployment.matchers]] configure behavior for files that match the Pattern.
# See https://golang.org/pkg/regexp/syntax/ for pattern syntax.
# Pattern searching is stopped on first match.

# Samples:

[[deployment.matchers]]
# Cache static assets for 1 year.
pattern = "^.+\\.(js|css|svg|ttf)$"
cacheControl = "max-age=31536000, no-transform, public"
gzip = true

[[deployment.matchers]]
pattern = "^.+\\.(png|jpg)$"
cacheControl = "max-age=31536000, no-transform, public"
gzip = false

[[deployment.matchers]]
# Set custom content type for /sitemap.xml
pattern = "^sitemap\\.xml$"
contentType = "application/xml"
gzip = true

[[deployment.matchers]]
pattern = "^.+\\.(html|xml|json)$"
gzip = true

Deploy

To deploy to a target:

1
hugo deploy [--target=<target name>, defaults to first target]

Hugo will identify and apply any local changes that need to be reflected to the remote target. You can use --dryRun to see the changes without applying them, or --confirm to be prompted before making changes.

See hugo help deploy for more command-line options.

另请参阅

14 - 贡献

14.1 - ContributeToHugo

14.2 - Development

14.3 - Documentation

14.4 - Themes

14.5 - ThemesOverview