hugo v0.161.0 版本更新介绍
发布日期: 2026-04-28
版本号: v0.161.0
本次发布包含多项更新:首先,两项安全加固措施——默认为Node工具(如PostCSS、Babel和TailwindCSS)启用权限标识(需Node≥22且Tailwind CSS必须以Node.js包形式安装,不再支持独立可执行文件),以及收紧HTTP URL的默认安全策略。其次,引入多项新功能,包括:在css.Build和css.Sass中支持嵌套的Hugo变量导入;permavlinks配置现可采用基于Slice的灵活匹配规则,支持按路径、类型等条件分类设置;文件名中支持更丰富的维度标识符(如角色、版本、输出格式等),替代原有的挂载配置。此外,更新还涵盖错误修复、依赖升级及代码清理等大量变更。
更新内容 (中文)
本版本包含两个安全加固修复:
- 我们现在默认使用
--permission标志运行 Node 工具 PostCSS、Babel 和 TailwindCSS,权限定义在 security.node.permissions 中。这意味着您需要安装 Node >= 22,且css.TailwindCSS现在要求 Tailwind CSS CLI 必须作为 Node.js 包安装。独立可执行文件不再受支持 - 我们使 security.http.urls 中的默认值更加严格。
但还有一些值得注意的新功能:
css.Build 和 css.Sass 中的嵌套变量支持
css.Build 中的一个实际示例是在 hugo.toml 中如下配置:
[params.style]
primary = \"#000000\"
background = \"#ffffff\"
[params.style.dark]
primary = \"#ffffff\"
background = \"#000000\"
在样式表中:
@import \"hugo:vars\";
@import \"hugo:vars/dark\" (prefers-color-scheme: dark);
:root {
color-scheme: light dark;
}
基于切片的永久链接配置
permalinks 配置现在更加灵活(旧设置仍然有效)。它使用与 cascade 配置中相同的 target 匹配器,这意味着您现在可以这样操作:
permalinks:
- target:
kind: page
path: \"/books/**\"
pattern: /books/:year/:slug/
- target:
kind: section
path: \"/{books,books/**}\"
pattern: /libros/:sections[1:]
- target:
kind: page
pattern: /other/:slug/
以上示例并不完美,但至少展示了核心思想。
文件名中更灵活的标识符方案
我们之前的做法例如 content/mypost.en.md,告知 Hugo 内容文件为英语。使用新方案,您也可以将文件命名为 content/mypost._language_en_.md。这本身听起来不太有用,但它允许使用更多前缀:
| 前缀 | 描述 | 相关场景 |
|---|---|---|
| language_ | 语言 | 内容和布局文件。 |
| role_ | 角色 | 内容和布局文件。 |
| version_ | 版本 | 内容和布局文件。 |
| outputformat_ | 输出格式 | 布局文件。 |
| mediatype_ | 媒体类型 | 布局文件。 |
| kind_ | 页面类型 | 布局文件。 |
| layout_ | 布局 | 布局文件。 |
所有变更
- langs/i18n:修复使用语言变体时的翻译查找 72b85d5f @jmooring #7982
- create:修复 hugo new content 中的非确定性冲突检测 6436deb3 @jmooring #12602 #12786 #14112 #14769
- commands:修复配置设置的环境隔离 1eea9fba @jmooring #14763
- 修复文件名维度标识符(role_X、version_X)以替换挂载配置 8d6145f3 @bep #14756
- 修复确保永远不会自动回退到其他角色/版本的页面资源 97477242 @bep #14749 #14752
- css:支持嵌套的 hugo:vars/
导入 7622dd86 @bep #14705 - github:更新 GitHub actions 版本 0814059b @bep #14810
- hugolib:如果页面未渲染则不渲染别名 8920d56e @jmooring #14807
- langs/i18n:改进默认内容语言回退 633cc772 @jmooring #14243
- helpers:移除未使用的代码 4c40c6d5 @bep
- common/constants:移除未使用的常量 d2594db6 @bep
- common/paths:移除未使用的代码 ab2de51e @bep
- tests:更新 Ruby 设置 action 至 v1.305.0 75f61832 @jmooring
- langs:使用 Language.Locale 作为主要本地化键 1b7495bc @jmooring #9109
- config/security:向白名单添加 "! " 否定,加固默认 http.urls 79f030be @bep #14792
- 使用 –permission 标志加固 Node 工具执行 a54c398b @bep #7287
- tpl/collections:在 where 比较中遵循 Eqer 接口 f5fce935 @bep #14777
- modules:在 go.mod 重写中忽略非 require 块 4169c1f7 @bep #14783
- 用相同的上游版本替换并发映射 7574e35b @bep
- 添加基于切片的永久链接配置,支持 PageMatcher 目标 017a7cd6 @bep #14744
- commands:添加缺失的导入 e3413d92 @bep
- 回退 "common/hugo:弃用 extended 和 extended_withdeploy 版本" b01cc147 @bep #14771
- 稍作调整 SECURITY.md 8ee19ff9 @bep
- resources/page:为 Issue #14325 添加传递测试 0d58e428 @jmooring
- 添加更灵活的文件名标识符方案,允许设置角色和版本 (#14754) ce2a156a @bep #14750
- common/hugo:弃用 extended 和 extended_withdeploy 版本 a17bdbc5 @jmooring #14696
- parser/pageparser:添加解析器模糊测试 8f94d65c @bep
- 在测试中用 hugo.Sites 替换已弃用的 .Site.Sites/.Page.Sites 90d8bf34 @bep
- agents:添加关于在测试名称中包含问题 ID 的说明 bbb42b5a @bep
- build(deps):将 github.com/getkin/kin-openapi 从 0.135.0 升级到 0.137.0 d4ae662d @dependabot[bot]
- build(deps):将 github.com/mattn/go-isatty 从 0.0.21 升级到 0.0.22 9ede5fb9 @dependabot[bot]
- build(deps):将 github.com/tdewolff/minify/v2 从 2.24.12 升级到 2.24.13 833a878e @dependabot[bot]
- build(deps):将 github.com/magefile/mage 从 1.17.1 升级到 1.17.2 4c03129f @dependabot[bot]
- deps:升级 github.com/bep/imagemeta v0.17.1 => v0.17.2 080970bc @bep
- build(deps):将 github.com/aws/aws-sdk-go-v2/service/cloudfront 升级 (#14789) 896bc89a @dependabot[bot]
- build(deps):将 github.com/mattn/go-isatty 从 0.0.20 升级到 0.0.21 (#14788) 100dde53 @dependabot[bot]
- build(deps):将 github.com/bep/mclib 升级 (#14787) bdebb797 @dependabot[bot]
- build(deps):将 google.golang.org/api 从 0.267.0 升级到 0.276.0 52123ae2 @dependabot[bot]
- build(deps):将 github.com/aws/aws-sdk-go-v2 从 1.41.5 升级到 1.41.6 38b8afdc @dependabot[bot]
- build(deps):将 github.com/getkin/kin-openapi 从 0.134.0 升级到 0.135.0 (#14781) 92766600 @dependabot[bot]
- build(deps):将 github.com/bep/goportabletext 从 0.1.0 升级到 0.2.0 (#14779) 790f4084 @dependabot[bot]
- build(deps):将 golang.org/x/image 从 0.38.0 升级到 0.39.0 (#14780) de6955ba @dependabot[bot]
- deps:升级 github.com/bep/imagemeta v0.17.0 => v0.17.1 (#14775) a77bd527 @bep #14758
- build(deps):将 golang.org/x/tools 从 0.43.0 升级到 0.44.0 547ab29c @dependabot[bot]
- build(deps):将 github.com/evanw/esbuild 从 0.27.4 升级到 0.28.0 9a5c7e0d @dependabot[bot]
- build(deps):将 github.com/aws/aws-sdk-go-v2 从 1.41.1 升级到 1.41.5 6613b08e @dependabot[bot]
- build(deps):将 github.com/pelletier/go-toml/v2 从 2.2.4 升级到 2.3.0 582c26ef @dependabot[bot]
- build(deps):将 github.com/tdewolff/minify/v2 从 2.24.11 升级到 2.24.12 a4f2a8a5 @dependabot[bot]
更新内容 (原始)
This release contains two security hardening fixes:
- We now run the Node tools PostCSS, Babel and TailwindCSS, by default, with the
--permissionflag with the permissions defined in security.node.permissions. This means that you need Node >= 22 installed and thatcss.TailwindCSSnow requires that the Tailwind CSS CLI must be installed as a Node.js package. The standalone executable is no longer supported - We have made the defaults in security.http.urls more restrictive.
But there are some notable new features, as well:
Nested vars support in css.Build and css.Sass
A practical example in css.Build would be to have something like this in hugo.toml:
[params.style]
primary = "#000000"
background = "#ffffff"
[params.style.dark]
primary = "#ffffff"
background = "#000000"
And in the stylesheet:
@import "hugo:vars";
@import "hugo:vars/dark" (prefers-color-scheme: dark);
:root {
color-scheme: light dark;
}
Slice-based permalinks config
The permalinks configuration is now much more flexible (the old setup still works). It uses the same target matchers as in the cascade config, meaning you can now do:
permalinks:
- target:
kind: page
path: "/books/**"
pattern: /books/:year/:slug/
- target:
kind: section
path: "/{books,books/**}"
pattern: /libros/:sections[1:]
- target:
kind: page
pattern: /other/:slug/
The above example isn’t great, but it at least shows the gist of it.
A more flexible scheme for identifiers in filenames
What we had before was e.g. content/mypost.en.md which told Hugo that the content files was in English. With the new setup you could also name the file content/mypost._language_en_.md. This alone doesn’t sound very useful, but this allows you to use more prefixes:
| Prefix | Description | Relevant for |
|---|---|---|
| language_ | Language | Content and layout files. |
| role_ | Role | Content and layout files. |
| version_ | Version | Content and layout files. |
| outputformat_ | Output format | Layout files. |
| mediatype_ | Media type | Layout files. |
| kind_ | Page kind | Layout files. |
| layout_ | Layout | Layout files. |
All Changes
- langs/i18n: Fix translation lookup when using language variants 72b85d5f @jmooring #7982
- create: Fix non-deterministic conflict detection in hugo new content 6436deb3 @jmooring #12602 #12786 #14112 #14769
- commands: Fix environment isolation for configuration settings 1eea9fba @jmooring #14763
- Fix filename dimension identifiers (role_X, version_X) to replace mount config 8d6145f3 @bep #14756
- Fix it so we never auto-fallback to page resources in other roles/versions 97477242 @bep #14749 #14752
- css: Support nested hugo:vars/
imports 7622dd86 @bep #14705 - github: Update GitHub actions versions 0814059b @bep #14810
- hugolib: Do not render aliases if the page is not rendered 8920d56e @jmooring #14807
- langs/i18n: Improve default content language fallback 633cc772 @jmooring #14243
- helpers: Remove unused code 4c40c6d5 @bep
- common/constants: Remove unused consts d2594db6 @bep
- common/paths: Remove unused code ab2de51e @bep
- tests: Update Ruby setup action to v1.305.0 75f61832 @jmooring
- langs: Use Language.Locale as primary localization key 1b7495bc @jmooring #9109
- config/security: Add “! " negation to Whitelist, harden default http.urls 79f030be @bep #14792
- Harden Node tool execution with –permission flag a54c398b @bep #7287
- tpl/collections: Honor the Eqer interface in where comparisons f5fce935 @bep #14777
- modules: Ignore non-require blocks in go.mod rewrite 4169c1f7 @bep #14783
- Replace the concurrent map with an identical upstream version 7574e35b @bep
- Add slice-based permalinks config with PageMatcher target 017a7cd6 @bep #14744
- commands: Add missing import e3413d92 @bep
- Revert “common/hugo: Deprecate extended and extended_withdeploy editions” b01cc147 @bep #14771
- Adjust the SECURITY.md slightly 8ee19ff9 @bep
- resources/page: Add passing test for Issue #14325 0d58e428 @jmooring
- Add a more flexible filename identifier scheme that also allows setting roles and versions (#14754) ce2a156a @bep #14750
- common/hugo: Deprecate extended and extended_withdeploy editions a17bdbc5 @jmooring #14696
- parser/pageparser: Add a parser fuzz test 8f94d65c @bep
- Replace deprecated .Site.Sites/.Page.Sites with hugo.Sites intests 90d8bf34 @bep
- agents: Add a note about having the issue ID in test names bbb42b5a @bep
- build(deps): bump github.com/getkin/kin-openapi from 0.135.0 to 0.137.0 d4ae662d @dependabot[bot]
- build(deps): bump github.com/mattn/go-isatty from 0.0.21 to 0.0.22 9ede5fb9 @dependabot[bot]
- build(deps): bump github.com/tdewolff/minify/v2 from 2.24.12 to 2.24.13 833a878e @dependabot[bot]
- build(deps): bump github.com/magefile/mage from 1.17.1 to 1.17.2 4c03129f @dependabot[bot]
- deps: Upgrade github.com/bep/imagemeta v0.17.1 => v0.17.2 080970bc @bep
- build(deps): bump github.com/aws/aws-sdk-go-v2/service/cloudfront (#14789) 896bc89a @dependabot[bot]
- build(deps): bump github.com/mattn/go-isatty from 0.0.20 to 0.0.21 (#14788) 100dde53 @dependabot[bot]
- build(deps): bump github.com/bep/mclib (#14787) bdebb797 @dependabot[bot]
- build(deps): bump google.golang.org/api from 0.267.0 to 0.276.0 52123ae2 @dependabot[bot]
- build(deps): bump github.com/aws/aws-sdk-go-v2 from 1.41.5 to 1.41.6 38b8afdc @dependabot[bot]
- build(deps): bump github.com/getkin/kin-openapi from 0.134.0 to 0.135.0 (#14781) 92766600 @dependabot[bot]
- build(deps): bump github.com/bep/goportabletext from 0.1.0 to 0.2.0 (#14779) 790f4084 @dependabot[bot]
- build(deps): bump golang.org/x/image from 0.38.0 to 0.39.0 (#14780) de6955ba @dependabot[bot]
- deps: Upgrade github.com/bep/imagemeta v0.17.0 => v0.17.1 (#14775) a77bd527 @bep #14758
- build(deps): bump golang.org/x/tools from 0.43.0 to 0.44.0 547ab29c @dependabot[bot]
- build(deps): bump github.com/evanw/esbuild from 0.27.4 to 0.28.0 9a5c7e0d @dependabot[bot]
- build(deps): bump github.com/aws/aws-sdk-go-v2 from 1.41.1 to 1.41.5 6613b08e @dependabot[bot]
- build(deps): bump github.com/pelletier/go-toml/v2 from 2.2.4 to 2.3.0 582c26ef @dependabot[bot]
- build(deps): bump github.com/tdewolff/minify/v2 from 2.24.11 to 2.24.12 a4f2a8a5 @dependabot[bot]
下载链接
- hugo_0.161.0_checksums.txt
- hugo_0.161.0_darwin-universal.pkg
- hugo_0.161.0_dragonfly-amd64.tar.gz
- hugo_0.161.0_freebsd-amd64.tar.gz
- hugo_0.161.0_Linux-64bit.tar.gz
- hugo_0.161.0_linux-amd64.deb
- hugo_0.161.0_linux-amd64.tar.gz
- hugo_0.161.0_linux-arm.tar.gz
- hugo_0.161.0_linux-arm64.deb
- hugo_0.161.0_linux-arm64.tar.gz
- hugo_0.161.0_netbsd-amd64.tar.gz
- hugo_0.161.0_openbsd-amd64.tar.gz
- hugo_0.161.0_solaris-amd64.tar.gz
- hugo_0.161.0_windows-amd64.zip
- hugo_0.161.0_windows-arm64.zip
- hugo_extended_0.161.0_darwin-universal.pkg
- hugo_extended_0.161.0_Linux-64bit.tar.gz
- hugo_extended_0.161.0_linux-amd64.deb
- hugo_extended_0.161.0_linux-amd64.tar.gz
- hugo_extended_0.161.0_linux-arm64.deb
- hugo_extended_0.161.0_linux-arm64.tar.gz
- hugo_extended_0.161.0_windows-amd64.zip
- hugo_extended_withdeploy_0.161.0_darwin-universal.pkg
- hugo_extended_withdeploy_0.161.0_Linux-64bit.tar.gz
- hugo_extended_withdeploy_0.161.0_linux-amd64.deb
- hugo_extended_withdeploy_0.161.0_linux-amd64.tar.gz
- hugo_extended_withdeploy_0.161.0_linux-arm64.deb
- hugo_extended_withdeploy_0.161.0_linux-arm64.tar.gz
- hugo_extended_withdeploy_0.161.0_windows-amd64.zip
- hugo_withdeploy_0.161.0_darwin-universal.pkg
- hugo_withdeploy_0.161.0_Linux-64bit.tar.gz
- hugo_withdeploy_0.161.0_linux-amd64.deb
- hugo_withdeploy_0.161.0_linux-amd64.tar.gz
- hugo_withdeploy_0.161.0_linux-arm64.deb
- hugo_withdeploy_0.161.0_linux-arm64.tar.gz
- hugo_withdeploy_0.161.0_windows-amd64.zip