templates.Defer
把模板的执行推迟到所有站点与输出格式都渲染完成之后。
用法
templates.Defer 函数把模板的执行推迟到所有站点与输出格式都渲染完成之后。
templates.Defer 函数只接受一个参数,即一个映射,其中可含以下键:
key- (
string)用于该延迟模板的键。它与模板内容的哈希值一起作为缓存键。不指定该键时,Hugo 每次渲染都会执行这个延迟模板,对 CSS、JavaScript 这类共享资源来说效率很低。 data- (
map)可选,作为数据传给延迟模板的映射。在延迟模板中可以通过.或$访问它。
Language Outside: {{ site.Language.Name }}
Page Outside: {{ .RelPermalink }}
I18n Outside: {{ i18n "hello" }}
{{ $data := (dict "page" . )}}
{{ with (templates.Defer (dict "data" $data )) }}
Language Inside: {{ site.Language.Name }}
Page Inside: {{ .page.RelPermalink }}
I18n Inside: {{ i18n "hello" }}
{{ end }}即使执行被推迟,输出格式、站点与语言仍保持不变。在上例中,这意味着延迟模板内部的 site.Language.Name 与 .RelPermalink 与其外部完全一致。
示例
下面的示例把 CSS 处理推迟到 Hugo 渲染完所有页面之后。
处理 Tailwind CSS
css.TailwindCSS 函数会用 hugo_stats.json 判断哪些类名及其它 HTML 标识符被使用。由于 Hugo 必须先渲染完所有页面才能写出该文件,处理 CSS 时要按下面的模板延迟执行:
<head>
{{ with (templates.Defer (dict "key" "global")) }}
{{ partial "css.html" . }}
{{ end }}
</head>{{ with resources.Get "css/main.css" }}
{{ $opts := dict "minify" (not hugo.IsDevelopment) }}
{{ with . | css.TailwindCSS $opts }}
{{ if hugo.IsDevelopment }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{ else }}
{{ with . | fingerprint }}
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
{{ end }}
{{ end }}
{{ end }}
{{ end }}要让上面的写法在运行服务器(或 hugo -w)时也工作良好,请添加以下配置:
[build]
[build.buildStats]
enable = true
[[build.cachebusters]]
source = 'assets/notwatching/hugo_stats\.json'
target = 'css'
[[build.cachebusters]]
source = '(postcss|tailwind)\.config\.js'
target = 'css'
[module]
[[module.mounts]]
source = 'assets'
target = 'assets'
[[module.mounts]]
disableWatch = true
source = 'hugo_stats.json'
target = 'assets/notwatching/hugo_stats.json'移除未使用的 CSS
在第 4 步中创建的 postcss.config.mjs 配置文件,会让 PurgeCSS 插件在 css.PostCSS 函数运行时读取 hugo_stats.json。由于 Hugo 只有在所有页面渲染完成后才会写出该文件,CSS 处理必须延迟执行。
- 第 1 步
- 安装 Node.js。
- 第 2 步
- 在项目根目录安装所需的 Node 包:
npm i -D postcss postcss-cli autoprefixer @fullhuman/postcss-purgecss - 第 3 步
- 构建站点时启用生成
hugo_stats.json文件。如果只在生产构建中使用它,可以考虑把它放到config/production下。[build.buildStats] enable = true细节与可选设置参见配置构建。
- 第 4 步
- 在项目根目录为
PurgeCSS与autoprefixer插件创建配置文件。postcss.config.mjs import autoprefixer from 'autoprefixer'; import purgeCSSPlugin from '@fullhuman/postcss-purgecss'; const purgecss = purgeCSSPlugin({ content: ['./hugo_stats.json'], defaultExtractor: content => { const els = JSON.parse(content).htmlElements; return [ ...(els.tags || []), ...(els.classes || []), ...(els.ids || []), ]; }, // https://purgecss.com/safelisting.html safelist: [] }); export default { plugins: [ process.env.HUGO_ENVIRONMENT !== 'development' ? purgecss : null, autoprefixer, ] }; - 第 5 步
- 把 CSS 文件放到
assets/css目录中。 - 第 6 步
- 延迟 CSS 处理,让它在站点渲染完成后再执行:
layouts/baseof.html <head> {{ with (templates.Defer (dict "key" "global")) }} {{ partial "css.html" . }} {{ end }} </head>layouts/_partials/css.html {{ with resources.Get "css/main.css" }} {{ if hugo.IsDevelopment }} <link rel="stylesheet" href="{{ .RelPermalink }}"> {{ else }} {{ with . | postCSS | minify | fingerprint }} <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"> {{ end }} {{ end }} {{ end }}