Hugo URL 管理
概述
默认情况下,当 Hugo 渲染页面时,生成的 URL 匹配 content 目录内的文件路径。例如:
content/posts/post-1.md → https://example.org/posts/post-1/你可以使用 front matter 值和站点配置选项更改 URL 的结构和外观。
Front matter
slug
在 front matter 中设置 slug 以覆盖路径的最后一段。此 front matter 字段不适用于 home、section、taxonomy 或 term 页面。
---
slug: my-first-post
title: My First Post
---+++
slug = 'my-first-post'
title = 'My First Post'
+++{
"slug": "my-first-post",
"title": "My First Post"
}
生成的 URL 将是:
https://example.org/posts/my-first-post/url
在 front matter 中设置 url 以覆盖整个路径。对常规页面或 section 页面使用此字段。
Hugo 不会清理 url front matter 字段,允许你生成:
- 包含操作系统保留字符的文件路径。例如,Windows 上的文件路径不能包含任何这些 reserved characters。如果文件路径包含当前操作系统保留的字符,Hugo 将抛出错误。
- 包含不允许字符的 URL。例如,小于号(
<)在 URL 中不允许。
如果你在 front matter 中同时设置 slug 和 url,url 值优先。
包含冒号
New in v0.136.0如果你需要在 url front matter 字段中包含冒号,使用反斜杠字符转义。如果将字符串包裹在单引号中,使用一个反斜杠;如果将字符串包裹在双引号中,使用两个反斜杠。对于 YAML front matter,如果省略引号,使用单个反斜杠。
例如,使用此 front matter:
---
title: Example
url: 'my\:example'
---+++
title = 'Example'
url = 'my\:example'
+++{
"title": "Example",
"url": "my\\:example"
}
生成的 URL 将是:
https://example.org/my:example/如上所述,这在 Windows 上将失败,因为冒号(:)是保留字符。
文件扩展名
使用此 front matter:
---
title: My First Article
url: articles/my-first-article
---+++
title = 'My First Article'
url = 'articles/my-first-article'
+++{
"title": "My First Article",
"url": "articles/my-first-article"
}
生成的 URL 将是:
https://example.org/articles/my-first-article/如果你包含文件扩展名:
---
title: My First Article
url: articles/my-first-article.html
---+++
title = 'My First Article'
url = 'articles/my-first-article.html'
+++{
"title": "My First Article",
"url": "articles/my-first-article.html"
}
生成的 URL 将是:
https://example.org/articles/my-first-article.html前导斜杠
对于单语言站点,有或没有前导斜杠的 url 值相对于 baseURL。对于多语言站点,有前导斜杠的 url 值相对于 baseURL,没有前导斜杠的 url 值相对于 baseURL 加上语言前缀。
| Site type | Front matter url |
Resulting URL |
|---|---|---|
| monolingual | /about |
https://example.org/about/ |
| monolingual | about |
https://example.org/about/ |
| multilingual | /about |
https://example.org/about/ |
| multilingual | about |
https://example.org/de/about/ |
front matter 中的永久链接令牌
New in v0.131.0你还可以在设置 url 值时使用令牌。这通常在 cascade 部分中使用:
---
cascade:
- url: /:sections[last]/:slug
title: Bar
---+++
title = 'Bar'
[[cascade]]
url = '/:sections[last]/:slug'
+++{
"cascade": [
{
"url": "/:sections[last]/:slug"
}
],
"title": "Bar"
}
使用以下任何令牌:
:year- front matter
date字段中定义的 4 位年份。 :month- front matter
date字段中定义的 2 位月份。 :monthname- front matter
date字段中定义的月份名称。 :day- front matter
date字段中定义的 2 位日期。 :weekday- front matter
date字段中定义的 1 位星期几(星期日 =0)。 :weekdayname- front matter
date字段中定义的星期几名称。 :yearday- front matter
date字段中定义的 1 至 3 位一年中的第几天。 :section- 内容的部分。
:sectionslug- New in v0.149.0
- 使用 slugified 部分名称的内容部分。slugified 部分名称是 front matter 中定义的
slug,否则是 front matter 中定义的title,否则是自动标题。 :sections- 内容的部分层次结构。您可以使用 slice 语法 选择部分:
:sections[1:]包括除第一个之外的所有部分,:sections[:last]包括除最后一个之外的所有部分,:sections[last]仅包括最后一个,:sections[1:2]包括第 2 和第 3 部分。请注意,此 slice 访问不会抛出任何越界错误,因此您不必精确。 :sectionslugs- New in v0.149.0
- 使用 slugified 部分名称的内容部分层次结构。slugified 部分名称是 front matter 中定义的
slug,否则是 front matter 中定义的title,否则是自动标题。您可以使用 slice 语法 选择部分::sectionslugs[1:]包括除第一个之外的所有部分,:sectionslugs[:last]包括除最后一个之外的所有部分,:sectionslugs[last]仅包括最后一个,:sectionslugs[1:2]包括第 2 和第 3 部分。请注意,此 slice 访问不会抛出任何越界错误,因此您不必精确。 :title- front matter 中定义的
title,否则是自动标题。Hugo 为没有文件支持的部分、分类法和术语页面自动生成标题。 :slug- front matter 中定义的
slug,否则是 front matter 中定义的title,否则是自动标题。Hugo 为没有文件支持的部分、分类法和术语页面自动生成标题。 :filename- 内容的文件名(不含扩展名),适用于
page页面类型。Deprecated in v0.144.0
:filename标记已弃用。请改用:contentbasename。 :slugorfilename- front matter 中定义的
slug,否则是内容的文件名(不含扩展名),适用于page页面类型。Deprecated in v0.144.0
:slugorfilename标记已弃用。请改用:slugorcontentbasename。 :contentbasename- New in v0.144.0
- 内容基本名称。
:slugorcontentbasename- New in v0.144.0
- front matter 中定义的
slug,否则是 内容基本名称。
对于时间相关的值,您还可以使用 Go time 包 中定义的布局字符串组件。例如:
permalinks:
posts: /:06/:1/:2/:title/
[permalinks]
posts = '/:06/:1/:2/:title/'
{
"permalinks": {
"posts": "/:06/:1/:2/:title/"
}
}
站点配置
永久链接
请参阅 configure permalinks。
外观
请参阅 configure ugly URLs。
后处理
Hugo 提供两个互斥的配置选项,在渲染页面 之后 更改 URL。
规范 URL
这是一个遗留配置选项,已被模板函数和 Markdown 渲染钩子取代,可能会在 future release 中删除。
如果启用,Hugo 在渲染页面 之后 执行搜索和替换。它搜索与 action、href、src、srcset 和 url 属性关联的站点相对 URL(那些有前导斜杠的 URL)。然后它添加 baseURL 前缀以创建绝对 URL。
<a href="/about"> → <a href="https://example.org/about/">
<img src="/a.gif"> → <img src="https://example.org/a.gif">这是一种不完美的粗暴方法,可能影响内容以及 HTML 属性。如上所述,这是一个遗留配置选项,可能会在未来版本中删除。
启用:
canonifyURLs: true
canonifyURLs = true
{
"canonifyURLs": true
}
相对 URL
除非你正在创建可通过文件系统导航的无服务器站点,否则不要启用此选项。
如果启用,Hugo 在渲染页面 之后 执行搜索和替换。它搜索与 action、href、src、srcset 和 url 属性关联的站点相对 URL(那些有前导斜杠的 URL)。然后将 URL 转换为相对于当前页面。
例如,渲染 content/posts/post-1 时:
<a href="/about"> → <a href="../../about">
<img src="/a.gif"> → <img src="../../a.gif">这是一种不完美的粗暴方法,可能影响内容以及 HTML 属性。如上所述,除非你正在创建无服务器站点,否则不要启用此选项。
启用:
relativeURLs: true
relativeURLs = true
{
"relativeURLs": true
}
别名
别名允许你将旧 URL 重定向到新 URL。这对于防止链接失效并确保在你重命名或移动内容时现有书签或外部链接继续有效至关重要。
定义别名
要为页面添加重定向,在 front matter 中的 aliases 字段列出以前的路径。Hugo 在构建过程中将这些解析为 server-relative 路径,考虑 baseURL 和 content dimension 前缀,如语言、角色或版本。
---
aliases:
- /old-url
- old-name
- ../old/path
date: '2025-02-02'
title: Example 1
---+++
aliases = ['/old-url', 'old-name', '../old/path']
date = 2025-02-02
title = 'Example 1'
+++{
"aliases": [
"/old-url",
"old-name",
"../old/path"
],
"date": "2025-02-02",
"title": "Example 1"
}
如上面的示例所示,你可以使用 site-relative 路径或 page-relative 路径。页面相对路径也可以包括目录遍历。使用文件 content/examples/example-1.en.md 作为参考点,以下是 Hugo 如何解释这些不同路径类型:
| Path type | Alias | Server-relative path |
|---|---|---|
| site-relative | /old-url |
/en/old-url/ |
| page-relative | old-name |
/en/examples/old-name/ |
| page-relative | ../old/path |
/en/old/path/ |
重定向方法
根据你的托管环境和个人偏好,有两种方法实现别名:客户端重定向和服务器端重定向。
别名数据仅为 output formats 生成,其中 isHTML 和 permalinkable 都为 true。这影响客户端重定向文件的创建和服务器端重定向中使用的 Aliases 方法返回的结果。
客户端重定向
默认情况下,Hugo 使用客户端重定向,为每个别名生成一个小 HTML 文件。此文件包含一个 meta http-equiv="refresh" 标签,指示浏览器导航到新 URL。这种方法适用于所有托管提供商。
使用此方法时,Hugo 在每个别名位置创建物理目录和 index.html 文件。例如,如果 content/posts/new.md 的页面有一个页面相对别名 old-path,则在 public/posts/old-path/index.html 生成文件。
除非你提供自定义布局,否则 Hugo 使用其 embedded alias template 生成重定向文件:
<!DOCTYPE html>
<html lang="{{ site.Language.LanguageCode }}">
<head>
<title>{{ .Permalink }}</title>
{{ with .OutputFormats.Canonical }}<link rel="{{ .Rel }}" href="{{ .Permalink }}">{{ end }}
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url={{ .Permalink }}">
</head>
</html>要覆盖此,在 layouts 目录中创建名为 alias.html 的文件。此自定义模板可以访问以下上下文:
Permalink- (
string) 目标页面的绝对 URL。 Page- (
page.Page) 目标的完整Page对象。
服务器端重定向
或者,你可以使用 Page 对象上的 Aliases 方法实现服务器端重定向,生成 Web 服务器处理的单个配置文件。此方法更有效,因为重定向发生在 HTTP 标头级别,在任何页面内容处理之前,而 meta refresh 需要浏览器下载并解析 HTML 主体然后操作。此外,服务器端重定向改善构建和部署时间,因为 Hugo 不需要为每个别名写入物理目录和 HTML 文件。
要实现此,你通常创建单个模板来为你的特定主机或服务器生成必要的规则。常见示例包括:
- 用于托管服务(如 Cloudflare、GitLab Pages 和 Netlify)的
_redirects文件。 - 用于 Web 服务器(如 Apache 和 LiteSpeed)的
.htaccess文件。
请参阅 Aliases 方法页面,了解如何遍历页面生成这些规则的完整示例。
如果你实现服务器端重定向,你应该通过在站点配置中将 disableAliases 设置为 true 来禁用单个 HTML 文件的生成。此设置仅防止物理 HTML 文件的生成;Aliases 方法在 Page 对象上仍可用于你的配置模板。