HUGO
Menu
GitHub 87548 stars Mastodon

Hugo 页面资源

使用页面资源将资产与页面逻辑关联。

页面资源只能从 page bundles 访问,这些目录的根目录有 index.md_index.md 文件。页面资源仅对与其 bundle 的页面可用。

在此示例中,first-post 是一个页面 bundle,可以访问 10 个页面资源,包括音频、数据、文档、图像和视频。虽然 second-post 也是页面 bundle,但它没有页面资源,无法直接访问与 first-post 关联的页面资源。

content
└── post
    ├── first-post
    │   ├── images
    │   │   ├── a.jpg
    │   │   ├── b.jpg
    │   │   └── c.jpg
    │   ├── index.md (页面 bundle 的根)
    │   ├── latest.html
    │   ├── manual.json
    │   ├── notice.md
    │   ├── office.mp3
    │   ├── pocket.mp4
    │   ├── rating.pdf
    │   └── safety.txt
    └── second-post
        └── index.md (页面 bundle 的根)

示例

Page 对象上使用以下任何方法来捕获页面资源:

一旦捕获了资源,使用任何适用的 Resource 方法来返回值或执行操作。

以下示例假设此内容结构:

content/
└── example/
    ├── data/
    │  └── books.json   <-- 页面资源
    ├── images/
    │  ├── a.jpg        <-- 页面资源
    │  └── b.jpg        <-- 页面资源
    ├── snippets/
    │  └── text.md      <-- 页面资源
    └── 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 }}

渲染所有图像,调整大小为 300 像素宽:

{{ 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 }}

列出数据文件中的标题,如果文件不存在则抛出错误。

{{ $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 }}

元数据

页面资源的元数据通过名为 resources 的数组/表参数从相应页面的 front matter 管理。你可以使用 通配符 批量分配值。

page 类型的资源从其自己的 front matter 获取 Title 等。

name
(string) 设置 Name 返回的值。

方法 MatchGetGetMatch 使用 Name 来匹配资源。

title
(string) 设置 Title 返回的值
params
(map) 自定义键值对映射。

资源元数据示例

---
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
---
+++
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'
+++
{
   "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
  • bundle 中的每个 PDF(除了 documents/photo_specs.pdf)将获得 pdf 图标。
  • 所有 PDF 文件将获得新的 Namename 参数包含特殊占位符 :counter,因此 Name 将是 pdf-file-1pdf-file-2pdf-file-3
  • bundle 中的每个 docx 将获得 word 图标。

顺序很重要;只有 titlenameparams 键的第一个设置值将被使用。连续参数将仅为尚未设置的参数设置。在上面的示例中,.Params.icon 首先在 src = "documents/photo_specs.pdf" 中设置为 "photo"。所以它不会被后面设置的 src = "**.pdf" 规则覆盖为 "pdf"

nametitle 中的 :counter 占位符

:counterresourcesnametitle 参数中识别的特殊占位符。

计数器在 nametitle 中第一次使用时从 1 开始。

例如,如果 bundle 有资源 photo_specs.pdfother_specs.pdfguide.pdfchecklist.pdf,并且 front matter 已指定 resources 为:

---
resources:
- src: '*specs.pdf'
  title: 'Specification #:counter'
- name: pdf-file-:counter
  src: '**.pdf'
title: Engine inspections
---
+++
title = 'Engine inspections'
[[resources]]
  src = '*specs.pdf'
  title = 'Specification #:counter'
[[resources]]
  name = 'pdf-file-:counter'
  src = '**.pdf'
+++
{
   "resources": [
      {
         "src": "*specs.pdf",
         "title": "Specification #:counter"
      },
      {
         "name": "pdf-file-:counter",
         "src": "**.pdf"
      }
   ],
   "title": "Engine inspections"
}

NameTitle 将按如下方式分配给资源文件:

Resource file Name Title
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"

多语言

默认情况下,使用多语言单主机站点,Hugo 在构建站点时不会复制共享页面资源。

此行为仅限于 Markdown 内容。其他 content formats 的共享页面资源将复制到每个语言 bundle 中。

考虑此站点配置:

defaultContentLanguage: de
defaultContentLanguageInSubdir: true
languages:
  de:
    languageCode: de-DE
    languageName: Deutsch
    weight: 1
  en:
    languageCode: en-US
    languageName: English
    weight: 2
defaultContentLanguage = 'de'
defaultContentLanguageInSubdir = true
[languages]
  [languages.de]
    languageCode = 'de-DE'
    languageName = 'Deutsch'
    weight = 1
  [languages.en]
    languageCode = 'en-US'
    languageName = 'English'
    weight = 2
{
   "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     <-- 共享页面资源
    ├── b.jpg     <-- 共享页面资源
    ├── c.de.jpg
    ├── c.en.jpg
    ├── index.de.md
    └── index.en.md

使用 v0.122.0 及更早版本,Hugo 复制共享页面资源,为每种语言创建副本:

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

使用 v0.123.0 及更高版本,Hugo 将共享资源放在默认内容语言的页面 bundle 中:

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

这种方法减少了构建时间、存储需求、带宽消耗和部署时间,最终降低成本。

要将 Markdown 链接和图像目标解析到正确位置,你必须使用链接和图像渲染钩子,使用 Resources.Get 方法捕获页面资源,然后调用其 RelPermalink 方法。

在默认配置中,Hugo 自动使用 embedded link render hookembedded image render hook 用于多语言单主机站点,特别是当 duplication of shared page resources 功能被禁用时。这是此类站点的默认行为。如果项目、模块或主题定义了自定义链接或图像渲染钩子,将使用这些钩子。

你还可以配置 Hugo always 使用嵌入式链接或图像渲染钩子,仅作为 fallback 使用,或 never 使用。参见 详情

虽然复制共享页面资源效率低下,但如果需要,你可以在站点配置中启用此功能:

markup:
  goldmark:
    duplicateResourceFiles: true
[markup]
  [markup.goldmark]
    duplicateResourceFiles = true
{
   "markup": {
      "goldmark": {
         "duplicateResourceFiles": true
      }
   }
}

Last updated: January 1, 0001
Improve this page