URL management
概覽
預設情況下,當 Hugo 渲染頁面時,生成的 URL 會與 content
目錄中的檔案路徑相符。例如:
content/posts/post-1.md → https://example.org/posts/post-1/
您可以通過前端資料的值和網站配置選項來改變 URL 的結構和顯示方式。
前端資料
slug
在前端資料中設定 slug
,以覆蓋路徑的最後一個段落。slug
值不會影響區塊頁面。
---
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
在前端資料中設定 url
,以覆蓋整個路徑。可以與常規頁面或區塊頁面一起使用。
如果在前端資料中同時設定了 slug
和 url
,則以 url
的值為主。
包含冒號
New in v0.136.0如果需要在 url
前端資料欄位中包含冒號,請使用反斜線字符轉義。如果字符串使用單引號包裹,請使用一個反斜線;如果使用雙引號包裹,請使用兩個反斜線。在 YAML 前端資料中,如果省略引號,請使用單個反斜線。
例如,使用以下前端資料:
---
title: Example
url: my\:example
---
+++
title = 'Example'
url = 'my\:example'
+++
{
"title": "Example",
"url": "my\\:example"
}
生成的 URL 會是:
https://example.org/my:example/
如上所述,這會在 Windows 上失敗,因為冒號(:
)是保留字符。
檔案擴展名
使用此前端資料:
---
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
加上語言前綴。
網站類型 | 前端資料 url |
生成的 URL |
---|---|---|
單語言 | /about |
https://example.org/about/ |
單語言 | about |
https://example.org/about/ |
多語言 | /about |
https://example.org/about/ |
多語言 | about |
https://example.org/de/about/ |
前端資料中的固定連結令牌
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"
}
網站配置
固定連結
在網站配置中,為每個頂層區塊定義 URL 模式。每個 URL 模式可以針對特定語言和/或頁面類型進行設定。
前端資料中的 url
值會覆蓋網站配置中 permalinks
區塊中定義的 URL 模式。
單語言範例
使用以下內容結構:
content/
├── posts/
│ ├── bash-in-slow-motion.md
│ └── tls-in-a-nutshell.md
├── tutorials/
│ ├── git-for-beginners.md
│ └── javascript-bundling-with-hugo.md
└── _index.md
將教程渲染到 “training” 目錄,並將文章渲染到 “articles” 目錄,並基於日期建立階層結構:
permalinks:
page:
posts: /articles/:year/:month/:slug/
tutorials: /training/:slug/
section:
posts: /articles/
tutorials: /training/
[permalinks]
[permalinks.page]
posts = '/articles/:year/:month/:slug/'
tutorials = '/training/:slug/'
[permalinks.section]
posts = '/articles/'
tutorials = '/training/'
{
"permalinks": {
"page": {
"posts": "/articles/:year/:month/:slug/",
"tutorials": "/training/:slug/"
},
"section": {
"posts": "/articles/",
"tutorials": "/training/"
}
}
}
公開網站的結構將是:
public/
├── articles/
│ ├── 2023/
│ │ ├── 04/
│ │ │ └── bash-in-slow-motion/
│ │ │ └── index.html
│ │ └── 06/
│ │ └── tls-in-a-nutshell/
│ │ └── index.html
│ └── index.html
├── training/
│ ├── git-for-beginners/
│ │ └── index.html
│ ├── javascript-bundling-with-hugo/
│ │ └── index.html
│ └── index.html
└── index.html
若要為根目錄中的常規頁面創建基於日期的階層結構:
permalinks:
page:
/: /:year/:month/:slug/
[permalinks]
[permalinks.page]
'/' = '/:year/:month/:slug/'
{
"permalinks": {
"page": {
"/": "/:year/:month/:slug/"
}
}
}
對於分類術語也可以使用相同的方法。例如,若要省略 URL 中的分類段落:
permalinks:
term:
tags: /:slug/
[permalinks]
[permalinks.term]
tags = '/:slug/'
{
"permalinks": {
"term": {
"tags": "/:slug/"
}
}
}
多語言範例
將 permalinks
配置作為本地化策略的一部分。
使用以下內容結構:
content/
├── en/
│ ├── books/
│ │ ├── les-miserables.md
│ │ └── the-hunchback-of-notre-dame.md
│ └── _index.md
└── es/
├── books/
│ ├── les-miserables.md
│ └── the-hunchback-of-notre-dame.md
└── _index.md
以及這樣的網站配置:
defaultContentLanguage: en
defaultContentLanguageInSubdir: true
languages:
en:
contentDir: content/en
languageCode: en-US
languageDirection: ltr
languageName: English
permalinks:
page:
books: /books/:slug/
section:
books: /books/
weight: 1
es:
contentDir: content/es
languageCode: es-ES
languageDirection: ltr
languageName: Español
permalinks:
page:
books: /libros/:slug/
section:
books: /libros/
weight: 2
defaultContentLanguage = 'en'
defaultContentLanguageInSubdir = true
[languages]
[languages.en]
contentDir = 'content/en'
languageCode = 'en-US'
languageDirection = 'ltr'
languageName = 'English'
weight = 1
[languages.en.permalinks]
[languages.en.permalinks.page]
books = '/books/:slug/'
[languages.en.permalinks.section]
books = '/books/'
[languages.es]
contentDir = 'content/es'
languageCode = 'es-ES'
languageDirection = 'ltr'
languageName = 'Español'
weight = 2
[languages.es.permalinks]
[languages.es.permalinks.page]
books = '/libros/:slug/'
[languages.es.permalinks.section]
books = '/libros/'
{
"defaultContentLanguage": "en",
"defaultContentLanguageInSubdir": true,
"languages": {
"en": {
"contentDir": "content/en",
"languageCode": "en-US",
"languageDirection": "ltr",
"languageName": "English",
"permalinks": {
"page": {
"books": "/books/:slug/"
},
"section": {
"books": "/books/"
}
},
"weight": 1
},
"es": {
"contentDir": "content/es",
"languageCode": "es-ES",
"languageDirection": "ltr",
"languageName": "Español",
"permalinks": {
"page": {
"books": "/libros/:slug/"
},
"section": {
"books": "/libros/"
}
},
"weight": 2
}
}
}
公開網站的結構將是:
public/
├── en/
│ ├── books/
│ │ ├── les-miserables/
│ │ │ └── index.html
│ │ ├── the-hunchback-of-notre-dame/
│ │ │ └── index.html
│ │ └── index.html
│ └── index.html
├── es/
│ ├── libros/
│ │ ├── les-miserables/
│ │ │ └── index.html
│ │ ├── the-hunchback-of-notre-dame/
│ │ │ └── index.html
│ │ └── index.html
│ └── index.html
└── index.html
令牌
在定義 URL 模式時使用這些令牌。您也可以在前端資料中設定 url
值時使用這些令牌。
:year
- 前端資料
date
欄位中定義的 4 位數年份。 :month
- 前端資料
date
欄位中定義的 2 位數月份。 :monthname
- 前端資料
date
欄位中定義的月份名稱。 :day
- 前端資料
date
欄位中定義的 2 位數日期。 :weekday
- 前端資料
date
欄位中定義的星期幾(星期日 = 0)。 :weekdayname
- 前端資料
date
欄位中定義的星期幾名稱。 :yearday
- 前端資料
date
欄位中定義的 1 至 3 位數年份中的第幾天。 :section
- 內容的區塊。
:sections
- 內容的區塊層次結構。您可以使用 切片語法 選擇某些區塊:
:sections[1:]
包含除第一個之外的所有區塊,:sections[:last]
包含除最後一個之外的所有區塊,:sections[last]
僅包含最後一個區塊,:sections[1:2]
包含第 2 和第 3 個區塊。注意,這種切片訪問不會拋出任何越界錯誤,因此您不必精確。 :title
- 如前端資料中所定義的標題,否則為自動生成的標題。Hugo 會自動為無檔案支援的區塊、分類和術語頁面生成標題。
:slug
- 如前端資料中所定義的 slug,否則為前端資料中定義的標題,否則為自動生成的標題。Hugo 會自動為無檔案支援的區塊、分類和術語頁面生成標題。
:filename
- 內容的檔案名稱,不包括副檔名,適用於
page
頁面類型。 :slugorfilename
- 如前端資料中所定義的 slug,否則為內容的檔案名稱,不包括副檔名,適用於
page
頁面類型。
對於時間相關的值,您也可以使用 Go 的 time 包 中定義的佈局字串組件。例如:
permalinks:
posts: /:06/:1/:2/:title/
[permalinks]
posts = '/:06/:1/:2/:title/'
{
"permalinks": {
"posts": "/:06/:1/:2/:title/"
}
}
顯示方式
URL 的顯示方式可以是醜陋或漂亮的。
類型 | 路徑 | URL |
---|---|---|
醜陋 | content/about.md | https://example.org/about.html |
漂亮 | content/about.md | https://example.org/about/ |
預設情況下,Hugo 生成漂亮的 URL。如果要生成醜陋的 URL,可以更改網站配置:
uglyURLs: true
uglyURLs = true
{
"uglyURLs": true
}
您也可以按區塊啟用醜陋 URL。例如,對於包含書籍和電影區塊的網站:
uglyURLs:
books: true
films: false
[uglyURLs]
books = true
films = false
{
"uglyURLs": {
"books": true,
"films": false
}
}
後處理
Hugo 提供了兩個互斥的配置選項,用來在渲染頁面 之後 修改 URL。
正規化 URL
如果啟用,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 轉換為相對於當前頁面的 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 的重定向:
- 以斜線開頭的別名是相對於
baseURL
的 - 沒有斜線開頭的別名是相對於當前目錄的
範例
更改現有頁面的檔案名稱,並從舊的 URL 創建別名到新的 URL:
aliases:
- /posts/previous-file-name
aliases = ['/posts/previous-file-name']
{
"aliases": [
"/posts/previous-file-name"
]
}
每個這樣的目錄相對別名與上面的站點相對別名等效:
previous-file-name
./previous-file-name
../posts/previous-file-name
您可以為當前頁面創建多個別名:
aliases:
- previous-file-name
- original-file-name
aliases = ['previous-file-name', 'original-file-name']
{
"aliases": [
"previous-file-name",
"original-file-name"
]
}
在多語言網站中,使用目錄相對的別名,或者在站點相對的別名中包括語言前綴:
aliases:
- /de/posts/previous-file-name
aliases = ['/de/posts/previous-file-name']
{
"aliases": [
"/de/posts/previous-file-name"
]
}
別名如何運作
使用上面的第一個範例,Hugo 會生成以下網站結構:
public/
├── posts/
│ ├── new-file-name/
│ │ └── index.html
│ ├── previous-file-name/
│ │ └── index.html
│ └── index.html
└── index.html
從舊 URL 到新 URL 的別名是一個客戶端重定向:
<!DOCTYPE html>
<html lang="en-us">
<head>
<title>https://example.org/posts/new-file-name/</title>
<link rel="canonical" href="https://example.org/posts/new-file-name/">
<meta name="robots" content="noindex">
<meta charset="utf-8">
<meta http-equiv="refresh" content="0; url=https://example.org/posts/new-file-name/">
</head>
</html>
head
區塊中的元素總體上:
- 告訴搜尋引擎新的 URL 是正規 URL
- 告訴搜尋引擎不要索引舊的 URL
- 告訴瀏覽器重定向到新的 URL
Hugo 在渲染頁面之前會先渲染別名文件。使用舊檔案名稱的新頁面會覆蓋別名,正如預期的那樣。
自訂
若要覆蓋 Hugo 內建的 alias
模板,請將 源代碼 複製到 layouts
目錄中的同名文件中。模板會接收以下上下文:
- Permalink
- 被別名指向的頁面的鏈接。
- Page
- 被別名指向頁面的頁面資料。