1. archetypes

archetypes目录包含新建页面的模板。可以创建一个或多个内容类型(content types)对应的模板。例如默认的模板和posts类型的模板。内容类型可在内容的前言区中使用type字段来设置,默认值为文件自content/后的第一级目录。

archetypes/
├── default.md
└── posts.md

对于hugo new 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

如果以上都不存在,Hugo使用内置的默认模板。

新建页面时,可使用--kind命令行参数来指定所使用的archetype模板。

对于archetypes的说明,请参考官方文档

2. assets

assets目录含全局的资源,通常包括图片、CSS、Sass、JavaScript和TypeScript等。

对于assets的说明,请参考官方文档

3. config

config目录包含网站的配置项,可分割成多个子目录或文件,对于最小配置的项目或者项目不需要不同的环境时,在项目的根目录下使用名为hugo.toml(或hugo.yaml,或hugo.json)单一的配置文件即可。如hugo.yaml

baseURL: https://example.org/
languageCode: en-us
params:
  contact:
    email: info@example.org
    phone: +1 202-555-1212
  subtitle: The Best Widgets on Earth
title: ABC Widgets, Inc.

构建站点时,可使用--config参数来指定配置文件,多个配置文件以英文逗号分隔。

可以根据环境、根配置键(root configuration key)以及语言,来分割配置文件。如:

my-project/
└── config/
    ├── _default/
    │   ├── hugo.toml
    │   ├── menus.en.toml
    │   ├── menus.de.toml
    │   └── params.toml
    └── production/
        └── params.toml

根配置键有:build, caches, cascade, deployment, frontmatter, imaging, languages, markup, mediatypes, menus, minify, module, outputformats, outputs, params, permalinks, privacy, related, security, segments, server, services, sitemaptaxonomies

环境通常是development, stagingproduction之一。可以使用--environment命令行参数或HUGO_ENVIRONMENT来指定环境。

Hugo递归解析config目录,可以使用子目前来组织文件。如:

my-project/
└── config/
    ├── _default/
    │   ├── hugo.toml
    │   ├── menus.en.toml
    │   ├── menus.de.toml
    │   └── params.toml
    ├── production/
    │   ├── hugo.toml
    │   └── params.toml
    └── staging/
        ├── hugo.toml
        └── params.toml

当运行hugo --environment staging命令时,Hugo将使用config/_default的配置,并再次基础之上合并staging中的配置。

举个例子,在设置Google tag ID 考虑以下场景:

  1. 运行hugo server时,无需加载分析代码(analytics code)。
  2. productionstaging环境中,使用不同的Google tag ID。如production环境中值为G-PPPPPPPPPstaging环境中值为G-SSSSSSSSS

为满足以上场景的需求,可以做如下配置:

  1. 配置config/_default/hugo.toml,排除services.googleAnalytics,阻止运行hugo server时加载分析代码。
  2. 配置config/production/hugo.yaml,仅包括如下内容:
services:
  googleAnalytics:
    ID: G-PPPPPPPPP

Hugo将从默认的配置中合并其他参数的配置。 3. 配置config/staging/hugo.ymal,仅包括如下内容:

services:
  googleAnalytics:
    ID: G-SSSSSSSSS

当从主题中,合并配置值时,可以使用_merge键。其取值包括:

  • none:不合并;
  • shallow:仅添加新键的值;
  • deep:添加新键,并合并已有的。

默认的_merge取值如下:

build:
  _merge: none
caches:
  _merge: none
cascade:
  _merge: none
deployment:
  _merge: none
frontmatter:
  _merge: none
httpcache:
  _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
outputs:
  _merge: none
page:
  _merge: none
pagination:
  _merge: none
params:
  _merge: deep
permalinks:
  _merge: none
privacy:
  _merge: none
related:
  _merge: none
security:
  _merge: none
segments:
  _merge: none
server:
  _merge: none
services:
  _merge: none
sitemap:
  _merge: none
taxonomies:
  _merge: none

对于config的说明,请参考官方文档

4. content

content目录包含生成网站内容的标签文件(通常是Markdown文件)、页面资源。自Hugo v0.32起,采用相对页面(page-relative)的图片和其他资源打包方式,打成页面包(Page Bundles)。其通常的目录结构如下:

content/
├── blog/
│   ├── hugo-is-cool/
│   │   ├── images/
│   │   │   ├── funnier-cat.jpg
│   │   │   └── funny-cat.jpg
│   │   ├── cats-info.md
│   │   └── index.md
│   ├── posts/
│   │   ├── post1.md
│   │   └── post2.md
│   ├── 1-landscape.jpg
│   ├── 2-sunset.jpg
│   ├── _index.md
│   ├── content-1.md
│   └── content-2.md
├── 1-logo.png
└── _index.md

注意:首页页面包(home page bundle)不可含其他内容页,但可含其他文件(如图片文件)等。

无需额外的配置,页面与访问链接的映射关系如下:

.
└── content
    └── about
    |   └── index.md  // <- https://example.org/about/
    ├── posts
    |   ├── firstpost.md   // <- https://example.org/posts/firstpost/
    |   ├── happy
    |   |   └── ness.md  // <- https://example.org/posts/happy/ness/
    |   └── secondpost.md  // <- https://example.org/posts/secondpost/
    └── quote
        ├── first.md       // <- https://example.org/quote/first/
        └── second.md      // <- https://example.org/quote/second/

4.1 页面包(Page bundle)

使用页面包(Page bundle)将一个或多个资源在逻辑上与页面内容相关联。页面包是封装页面内容及其相关资源的目录。例如:

content/
├── about/
│   ├── index.md
│   └── welcome.jpg
└── privacy.md

如上所示,about为一个页面包,它在逻辑上将页面资源与页面内容相关联。页面包内的资源被称为“页面资源”(page resources ),可以通过Page对象的Resources方法来访问。

页面包有叶子包(leaf bundles)和枝干包(branch bundles)两种类型。叶子包为包含一个index.md文件、零或多个资源文件的目录。与物理上的叶节点类似,叶子包位于枝干包的末端,它没有子孙。枝干包为包含一个_index.md文件、零或多个资源文件的目录。与物理上的枝干节点相似,它可以有包含叶子包或其他枝干包的子孙。顶级的枝干包目录也可有或没有_index.md文件。这适用于首页(home page)。

将叶子包和枝干包做个对比,如下表:

叶子包枝干包
index文件index.md_index.md
示例content/about/index.mdcontent/posts/_index.md
页面类型pagehome, section, taxonomyterm
模板类型singlehome, section, taxonomyterm
子孙页零个或多个
资源位置与index文件同级或子目录同叶子包,但不包括子孙包
资源类型page, image, video除page外的其他类型

对于page类型的资源文件,其内容可用Markdown、HTML、AsciiDoc、Pandoc、reStructuredText及Emacs Org Mode等格式来编写。在叶子包中,除index文件外,其他资源文件仅作为页面资源来访问;在枝干包中,这些文件也可作为内容页面来访问。

叶子包的示例:

content/
├── about
│   └── index.md
├── posts
│   ├── my-post
│   │   ├── content-1.md
│   │   ├── content-2.md
│   │   ├── image-1.jpg
│   │   ├── image-2.png
│   │   └── index.md
│   └── my-other-post
│       └── index.md
└── another-section
    ├── foo.md
    └── not-a-leaf-bundle
        ├── bar.md
        └── another-leaf-bundle
            └── index.md

如上所示,其中的叶子包有:

  • about: 不含任何页面资源;
  • my-post:包含一个index文件,两个page类型的资源和两个image类型的资源;
    • content-1, content-2:作为page类型的资源,可通过Page对象的Resources方法来访问。Hugo不会将其渲染为单独的页面。
    • image-1, image-2:作为image类型的资源,可通过Page对象的Resources方法来访问。
  • my-other-post:不含任何页面资源;
  • another-leaf-bundle:不含任何页面资源。

枝干包的示例:

content/
├── branch-bundle-1/
│   ├── _index.md
│   ├── content-1.md
│   ├── content-2.md
│   ├── image-1.jpg
│   └── image-2.png
├── branch-bundle-2/
│   ├── a-leaf-bundle/
│   │   └── index.md
│   └── _index.md
└── _index.md

如上所示,其中含三个枝干包:

  • home page: 包含一个index文件及两个子孙枝干包,不含资源;
  • branch-bundle-1:包含一个index文件,两个page类型的资源及两个image类型的资源;
  • branch-bundle-2:包含一个index文件和一个叶子包。

关于页面包更多的细节,请参考官方文档

4.2 页面资源(Page resources)

页面资源(Page resources)用作将页面相关资源与页面相关联。页面资源仅可通过页面包来访问,页面包目录以index.md_index.md作为根文件。页面资源仅可由该页面包的页面访问。

例如:

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)

如上所示,first-post页面包含有10个页面资源,包括音频(.mp3)、数据(.json)、文档(.pdf/.txt/.md)、图片(.jpg)和视频(.mp4)等。虽然second-post也是页面包,但其不含页面资源,它也不能直接访问first-post页面包中的页面资源。可以使用Page对象的相关方法来获取页面资源,方法有:

  • Resources.ByType
  • Resources.Get
  • Resources.GetMatch
  • Resources.Match

例如:

content/
└── example/
    ├── data/
    │  └── books.json   <-- page resource
    ├── images/
    │  ├── a.jpg        <-- page resource
    │  └── b.jpg        <-- page resource
    ├── snippets/
    │  └── text.md      <-- page resource
    └── index.md
  • 当图片文件不存在时,抛出异常:
{{ $path := "images/a.jpg" }}
{{ with .Resources.Get $path }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ else }}
  {{ errorf "Unable to get page resource %q" $path }}
{{ end }}
  • 将所有图片尺寸调整为300px宽:
{{ range .Resources.ByType "image" }}
  {{ with .Resize "300x" }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
  {{ end }}
{{ end }}
  • 使用Markdown代码片段来渲染内容:
{{ with .Resources.Get "snippets/text.md" }}
  {{ .Content }}
{{ end }}
  • 列出数据文件中的title字段,如果文件不存在抛出异常:
{{ $path := "data/books.json" }}
{{ with .Resources.Get $path }}
  {{ with . | transform.Unmarshal }}
    <p>Books:</p>
    <ul>
      {{ range . }}
        <li>{{ .title }}</li>
      {{ end }}
    </ul>
  {{ end }}
{{ else }}
  {{ errorf "Unable to get page resource %q" $path }}
{{ end }}

4.3 多语言

对于多语言单一站点,默认的,Hugo在生成网站时,不复制共享的页面资源(仅限于Markdown格式的内容,内容其他格式编写时,共享的页面资源会复制到各语言的页面包中)。

例如,有如下hugo.yaml配置文件:

defaultContentLanguage: de
defaultContentLanguageInSubdir: true
languages:
  de:
    languageCode: de-DE
    languageName: Deutsch
    weight: 1
  en:
    languageCode: en-US
    languageName: English
    weight: 2

页面内容为:

content/
└── my-bundle/
    ├── a.jpg     <-- 共享页面资源(shared page resource)
    ├── b.jpg     <-- 共享页面资源(shared page resource)
    ├── c.de.jpg
    ├── c.en.jpg
    ├── index.de.md
    └── index.en.md

自v0.123.0后,Hugo在生成页面内容时,将共享页面资源放在默认语言(defaultContentLanguage)对应的页面包中。以上配置和内容,生成public的目录结构如下:

public/
├── de/
│   ├── my-bundle/
│   │   ├── a.jpg     <-- 共享页面资源(shared page resource)
│   │   ├── b.jpg     <-- 共享页面资源(shared page resource)
│   │   ├── c.de.jpg
│   │   └── index.html
│   └── index.html
├── en/
│   ├── my-bundle/
│   │   ├── c.en.jpg
│   │   └── index.html
│   └── index.html
└── index.html

可以使用如下hugo.yaml配置,强制将共享页面资源根据语言重复放在各自语言包中,即v0.122.0及更早的版本。

markup:
  goldmark:
    duplicateResourceFiles: true

v0.122.0及更早版本,生成public的目录结构如下:

public/
├── de/
│   ├── my-bundle/
│   │   ├── a.jpg     <-- 共享页面资源(shared page resource)
│   │   ├── b.jpg     <-- 共享页面资源(shared page resource)
│   │   ├── c.de.jpg
│   │   └── index.html
│   └── index.html
├── en/
│   ├── my-bundle/
│   │   ├── a.jpg     <-- 共享页面资源(shared page resource) (重复的)
│   │   ├── b.jpg     <-- 共享页面资源(shared page resource) (重复的)
│   │   ├── c.en.jpg
│   │   └── index.html
│   └── index.html
└── index.html

对于content更详细的内容,请参考官方文档

5. data

data用于使用本地或远程数据来增强或生成内容。Hugo支持的本地或远程数据源包括CSV、JSON、TOML、YAML、XML等。可以有一个或多个数据文件,Hugo将合并所有的数据文件来创建单一的数据结构,可通过Site对象的Data方法来访问。

对于data更详细的内容,请参考官方文档Data方法

6. i18n

i18n目录包含多语言站点的翻译,请参考官方文档

7. layouts

layouts目录包含转换内容、数据和资源的模板,请参考官方文档

8. public

public包含运行hugohugo server命令,生成的可发布的网站内容,请参考官方文档

9. resources

resources目录包含运行hugohugo server命令,输出的资源缓存,默认地,这些缓存目录包含CSS和图片等。

10. static

static目录包含在生成网站时,需要复制到public目录中的文件,如favicon.icorobots.txt。在有page bundlesasset pipelines 概念之前,static目录也被用来存放图片、CSS和JavaScript文件。

11. themes

themes目录用来存放主题,每个主题有单独的子目录。可以使用hugo new theme my-theme命令来新建主题,主题的目录结构与站点的目录结构相同,