CONTENT MANAGEMENT

Multilingual mode

配置語言

這是預設的語言配置:

hugo.
     
languages:
  en:
    disabled: false
    languageCode: ""
    languageDirection: ""
    languageName: ""
    title: ""
    weight: 0
[languages]
  [languages.en]
    disabled = false
    languageCode = ''
    languageDirection = ''
    languageName = ''
    title = ''
    weight = 0
{
   "languages": {
      "en": {
         "disabled": false,
         "languageCode": "",
         "languageDirection": "",
         "languageName": "",
         "title": "",
         "weight": 0
      }
   }
}

在上面的範例中,en 是語言鍵。

語言鍵必須符合 RFC 5646 中所描述的語法。例如:

  • en
  • en-US

依據 RFC 5646 § 2.2.7 定義的人工語言與私用子標籤也受到支援。請省略語言鍵中的 art-x- 前綴。例如:

  • hugolang

以下是多語言專案網站配置的範例。任何在 languages 物件中未定義的鍵,都會回退至網站配置根目錄中的全域值。

hugo.
     
defaultContentLanguage: de
defaultContentLanguageInSubdir: true
languages:
  de:
    contentDir: content/de
    disabled: false
    languageCode: de-DE
    languageDirection: ltr
    languageName: Deutsch
    params:
      subtitle: Referenz, Tutorials und Erklärungen
    title: Projekt Dokumentation
    weight: 1
  en:
    contentDir: content/en
    disabled: false
    languageCode: en-US
    languageDirection: ltr
    languageName: English
    params:
      subtitle: Reference, Tutorials, and Explanations
    title: Project Documentation
    weight: 2
defaultContentLanguage = 'de'
defaultContentLanguageInSubdir = true
[languages]
  [languages.de]
    contentDir = 'content/de'
    disabled = false
    languageCode = 'de-DE'
    languageDirection = 'ltr'
    languageName = 'Deutsch'
    title = 'Projekt Dokumentation'
    weight = 1
    [languages.de.params]
      subtitle = 'Referenz, Tutorials und Erklärungen'
  [languages.en]
    contentDir = 'content/en'
    disabled = false
    languageCode = 'en-US'
    languageDirection = 'ltr'
    languageName = 'English'
    title = 'Project Documentation'
    weight = 2
    [languages.en.params]
      subtitle = 'Reference, Tutorials, and Explanations'
{
   "defaultContentLanguage": "de",
   "defaultContentLanguageInSubdir": true,
   "languages": {
      "de": {
         "contentDir": "content/de",
         "disabled": false,
         "languageCode": "de-DE",
         "languageDirection": "ltr",
         "languageName": "Deutsch",
         "params": {
            "subtitle": "Referenz, Tutorials und Erklärungen"
         },
         "title": "Projekt Dokumentation",
         "weight": 1
      },
      "en": {
         "contentDir": "content/en",
         "disabled": false,
         "languageCode": "en-US",
         "languageDirection": "ltr",
         "languageName": "English",
         "params": {
            "subtitle": "Reference, Tutorials, and Explanations"
         },
         "title": "Project Documentation",
         "weight": 2
      }
   }
}
defaultContentLanguage
(string) 專案的預設語言鍵,符合 RFC 5646 所描述的語法。此值必須與定義的語言鍵之一匹配。範例如下:
  • en
  • en-GB
  • pt-BR
defaultContentLanguageInSubdir
(bool) 如果為 true,Hugo 會將預設語言的網站渲染至對應的子目錄。預設為 false
contentDir
(string) 此語言的內容目錄。如果使用 根據檔名翻譯,則可省略此欄位。
disabled
(bool) 如果為 true,Hugo 不會渲染此語言的內容。預設為 false
languageCode
(string) 語言標籤,符合 RFC 5646 所描述的語法。此值不會影響在地化或網址。Hugo 會使用此值填充內建 RSS 模板中的 language 元素,並將其設為內建別名模板中 html 元素的 lang 屬性。範例如下:
  • en
  • en-GB
  • pt-BR
languageDirection
(string) 語言方向,可以是從左到右(ltr)或從右到左(rtl)。在模板中,請使用此值與全域 dir HTML 屬性。
languageName
(string) 語言名稱,通常用於渲染語言切換器。
title
(string) 此語言的網站標題(選填)。
weight
(int) 語言的權重。若設為非零值,則這將是語言排序的主要依據。

Hugo 0.112.0 的變更

New in v0.112.0

在 Hugo v0.112.0 中,我們整合了所有配置選項,並改善了語言及其參數與主配置合併的方式。但在測試這些變更時,我們收到了一些錯誤報告,並將部分變更恢復,改為顯示過時警告:

  1. site.Language.Params 已過時。請直接使用 site.Params
  2. 在語言配置的頂層添加自定義參數已過時。請在 languages.xx.params 內定義自定義參數。以下範例中的 color 就是這樣的例子。
hugo.
     
languageCode: en-us
languages:
  en:
    params:
      color: blue
  sv:
    languageCode: sv
    title: Min blogg
title: My blog
languageCode = 'en-us'
title = 'My blog'
[languages]
  [languages.en]
    [languages.en.params]
      color = 'blue'
  [languages.sv]
    languageCode = 'sv'
    title = 'Min blogg'
{
   "languageCode": "en-us",
   "languages": {
      "en": {
         "params": {
            "color": "blue"
         }
      },
      "sv": {
         "languageCode": "sv",
         "title": "Min blogg"
      }
   },
   "title": "My blog"
}

在上述範例中,除了 color 外,所有設定都對應 Hugo 的預設配置選項,應通過文件中記錄的訪問器進行存取:

{{ site.Title }}
{{ site.Language.LanguageCode }}
{{ site.Params.color }}

禁用語言

若要禁用網站配置中的 languages 物件內的某個語言:

hugo.
     
languages:
  es:
    disabled: true
[languages]
  [languages.es]
    disabled = true
{
   "languages": {
      "es": {
         "disabled": true
      }
   }
}

若要禁用網站配置根目錄中的一個或多個語言:

hugo.
     
disableLanguages:
- es
- fr
disableLanguages = ['es', 'fr']
{
   "disableLanguages": [
      "es",
      "fr"
   ]
}

若要使用環境變數禁用一個或多個語言:

HUGO_DISABLELANGUAGES="es fr" hugo

請注意,無法禁用預設內容語言。

配置多語言多主機

Hugo 支援在多主機配置中使用多種語言。這意味著您可以為每種語言配置一個 baseURL

範例:

hugo.
     
languages:
  en:
    baseURL: https://en.example.org/
    languageName: English
    title: In English
    weight: 2
  fr:
    baseURL: https://fr.example.org
    languageName: Français
    title: En Français
    weight: 1
[languages]
  [languages.en]
    baseURL = 'https://en.example.org/'
    languageName = 'English'
    title = 'In English'
    weight = 2
  [languages.fr]
    baseURL = 'https://fr.example.org'
    languageName = 'Français'
    title = 'En Français'
    weight = 1
{
   "languages": {
      "en": {
         "baseURL": "https://en.example.org/",
         "languageName": "English",
         "title": "In English",
         "weight": 2
      },
      "fr": {
         "baseURL": "https://fr.example.org",
         "languageName": "Français",
         "title": "En Français",
         "weight": 1
      }
   }
}

以上配置會將兩個網站生成到 public 資料夾中,並且各自擁有自己的根目錄:

public
├── en
└── fr

所有的網址(例如 .Permalink 等)將從該根目錄生成。所以上面的英文首頁將會將 .Permalink 設為 https://example.org/

當您執行 hugo server 時,我們將啟動多個 HTTP 伺服器。您通常會在控制台看到如下信息:

Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1) fr
Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1) en
Press Ctrl+C to stop

多伺服器的實時重載與 --navigateToChanged 按預期工作。

翻譯您的內容

有兩種方式可以管理您的內容翻譯。這兩種方式都確保每個頁面被指定語言並且與其對應的翻譯頁面相鏈接。

根據檔名翻譯

考慮以下範例:

  1. /content/about.en.md
  2. /content/about.fr.md

第一個檔案被分配為英文,並且與第二個檔案相鏈接。 第二個檔案被分配為法文,並且與第一個檔案相鏈接。

它們的語言是根據檔名中的語言代碼作為檔名後綴來指派的。

透過相同的 路徑和基本檔案名稱,這些內容會作為翻譯頁面相鏈接。

根據內容目錄翻譯

這個系統為每個語言使用不同的內容目錄。每個語言的內容目錄是透過 contentDir 參數設定的。

hugo.
     
languages:
  en:
    contentDir: content/english
    languageName: English
    weight: 10
  fr:
    contentDir: content/french
    languageName: Français
    weight: 20
[languages]
  [languages.en]
    contentDir = 'content/english'
    languageName = 'English'
    weight = 10
  [languages.fr]
    contentDir = 'content/french'
    languageName = 'Français'
    weight = 20
{
   "languages": {
      "en": {
         "contentDir": "content/english",
         "languageName": "English",
         "weight": 10
      },
      "fr": {
         "contentDir": "content/french",
         "languageName": "Français",
         "weight": 20
      }
   }
}

contentDir 的值可以是任何有效的路徑,甚至是絕對路徑參考。唯一的限制是內容目錄不能重疊。

考慮以下範例並結合上述配置:

  1. /content/english/about.md
  2. /content/french/about.md

第一個檔案被分配為英文,並且與第二個檔案相鏈接。 第二個檔案被分配為法文,並且與第一個檔案相鏈接。

它們的語言是根據它們所在的內容目錄來指派的。

透過相同的 路徑和基本檔案名稱(相對於它們的語言內容目錄),這些內容會作為翻譯頁面相鏈接。

跳過預設的鏈接方式

任何共享相同 translationKey 前置資料的頁面將會被作為翻譯頁面相鏈接,而不管檔案名稱或位置。

考慮以下範例:

  1. /content/about-us.en.md
  2. /content/om.nn.md
  3. /content/presentation/a-propos.fr.md
     
translationKey: about
translationKey = 'about'
{
   "translationKey": "about"
}

透過在這三個頁面中都設定 translationKey 前置資料參數為 about,它們將會被作為翻譯頁面相鏈接。

本地化永久鏈接

由於路徑和檔名用於處理鏈接,所有翻譯頁面將共享相同的 URL(除了語言子目錄外)。

要本地化網址:

  • 對於一般頁面,在前置資料中設置 slugurl
  • 對於區段頁面,在前置資料中設置 url

例如,法語翻譯可以有其自己的本地化 slug。

content/about.fr.md
     
---
slug: a-propos
title: A Propos
---
+++
slug = 'a-propos'
title = 'A Propos'
+++
{
   "slug": "a-propos",
   "title": "A Propos"
}

在渲染時,Hugo 會生成 /about//fr/a-propos/,而不會影響翻譯鏈接。

頁面綑綁

為了避免重複檔案,每個頁面綑綁將繼承其鏈接的翻譯頁面綑綁中的資源,內容檔案(如 Markdown 檔案、HTML 檔案等)除外。

因此,在模板中,頁面將能夠訪問所有鏈接頁面綑綁中的檔案。

如果在多個綑綁頁面中,兩個或更多的檔案擁有相同的檔名,則只會包含其中一個,選擇的順序如下:

  • 如果當前語言的綑綁中存在該檔案,則使用該檔案。
  • 如果檔案在綑綁中存在,則按照語言的 Weight 順序選擇第一個。

引用翻譯內容

要創建一個翻譯內容鏈接的列表,可以使用類似以下的模板:

layouts/partials/i18nlist.html
{{ if .IsTranslated }}
<h4>{{ i18n "translations" }}</h4>
<ul>
  {{ range .Translations }}
  <li>
    <a href="{{ .RelPermalink }}">{{ .Language.Lang }}: {{ .LinkTitle }}{{ if .IsPage }} ({{ i18n "wordCount" . }}){{ end }}</a>
  </li>
  {{ end }}
</ul>
{{ end }}

上述代碼可以放在 partial(即 layouts/partials/ 目錄中),並在任何模板中引入。如果某頁面沒有翻譯,它不會顯示任何內容。

這裡還使用了 i18n 函數,詳情見下一節。

列出所有可用語言

.AllTranslations 可用於列出所有翻譯,包括該頁面本身。在首頁中,它可用於構建語言導航器:

layouts/partials/allLanguages.html
<ul>
{{ range $.Site.Home.AllTranslations }}
<li><a href="{{ .RelPermalink }}">{{ .Language.LanguageName }}</a></li>
{{ end }}
</ul>

字串翻譯

參見 lang.Translate 模板函數。

在地化

以下本地化範例假設您網站的主要語言為英文,並且有法語和德語的翻譯。

hugo.
     
defaultContentLanguage: en
languages:
  de:
    contentDir: content/de
    languageName: Deutsch
    weight: 3
  en:
    contentDir: content/en
    languageName: English
    weight: 1
  fr:
    contentDir: content/fr
    languageName: Français
    weight: 2
defaultContentLanguage = 'en'
[languages]
  [languages.de]
    contentDir = 'content/de'
    languageName = 'Deutsch'
    weight = 3
  [languages.en]
    contentDir = 'content/en'
    languageName = 'English'
    weight = 1
  [languages.fr]
    contentDir = 'content/fr'
    languageName = 'Français'
    weight = 2
{
   "defaultContentLanguage": "en",
   "languages": {
      "de": {
         "contentDir": "content/de",
         "languageName": "Deutsch",
         "weight": 3
      },
      "en": {
         "contentDir": "content/en",
         "languageName": "English",
         "weight": 1
      },
      "fr": {
         "contentDir": "content/fr",
         "languageName": "Français",
         "weight": 2
      }
   }
}

日期

使用這個前置資料:

     
date: 2021-11-03T12:34:56+01:00
date = 2021-11-03T12:34:56+01:00
{
   "date": "2021-11-03T12:34:56+01:00"
}

和這段模板代碼:

{{ .Date | time.Format ":date_full" }}

渲染後的頁面顯示如下:

語言 數值
英文 Wednesday, November 3, 2021
法文 mercredi 3 novembre 2021
德文 Mittwoch, 3. November 2021

請參見 time.Format 了解更多細節。

貨幣

使用這段模板代碼:

{{ 512.5032 | lang.FormatCurrency 2 "USD" }}

渲染後的頁面顯示如下:

語言 數值
英文 $512.50
法文 512,50 $US
德文 512,50 $

請參見 lang.FormatCurrencylang.FormatAccounting 了解更多細節。

數字

使用這段模板代碼:

{{ 512.5032 | lang.FormatNumber 2 }}

渲染後的頁面顯示如下:

語言 數值
英文 512.50
法文 512,50
德文 512,50

請參見 lang.FormatNumberlang.FormatNumberCustom 了解更多細節。

百分比

使用這段模板代碼:

{{ 512.5032 | lang.FormatPercent 2 }}

渲染後的頁面顯示如下:

語言 數值
英文 512.50%
法文 512,50 %
德文 512,50 %

請參見 lang.FormatPercent 了解更多細節。

選單

選單項目的本地化取決於您如何定義它們:

  • 當您使用區段頁面選單 [自動] 定義選單項目時,必須使用翻譯表來本地化每個項目。
  • 當您在前置資料中 [定義] 選單項目時,它們已經基於前置資料本身進行本地化。如果前置資料中的值不夠,請使用翻譯表來本地化每個項目。
  • 當您在網站配置中 [定義] 選單項目時,必須在每個語言鍵下創建語言特定的選單項目。如果選單項目的名稱不足,請使用翻譯表來本地化每個項目。

創建語言特定的選單項目

方法 1 – 使用單一配置文件

對於包含少數項目的簡單選單,使用單一配置文件。例如:

hugo.
     
languages:
  de:
    languageCode: de-DE
    languageName: Deutsch
    menus:
      main:
      - name: Produkte
        pageRef: /products
        weight: 10
      - name: Leistungen
        pageRef: /services
        weight: 20
    weight: 1
  en:
    languageCode: en-US
    languageName: English
    menus:
      main:
      - name: Products
        pageRef: /products
        weight: 10
      - name: Services
        pageRef: /services
        weight: 20
    weight: 2
[languages]
  [languages.de]
    languageCode = 'de-DE'
    languageName = 'Deutsch'
    weight = 1
    [languages.de.menus]
      [[languages.de.menus.main]]
        name = 'Produkte'
        pageRef = '/products'
        weight = 10
      [[languages.de.menus.main]]
        name = 'Leistungen'
        pageRef = '/services'
        weight = 20
  [languages.en]
    languageCode = 'en-US'
    languageName = 'English'
    weight = 2
    [languages.en.menus]
      [[languages.en.menus.main]]
        name = 'Products'
        pageRef = '/products'
        weight = 10
      [[languages.en.menus.main]]
        name = 'Services'
        pageRef = '/services'
        weight = 20
{
   "languages": {
      "de": {
         "languageCode": "de-DE",
         "languageName": "Deutsch",
         "menus": {
            "main": [
               {
                  "name": "Produkte",
                  "pageRef": "/products",
                  "weight": 10
               },
               {
                  "name": "Leistungen",
                  "pageRef": "/services",
                  "weight": 20
               }
            ]
         },
         "weight": 1
      },
      "en": {
         "languageCode": "en-US",
         "languageName": "English",
         "menus": {
            "main": [
               {
                  "name": "Products",
                  "pageRef": "/products",
                  "weight": 10
               },
               {
                  "name": "Services",
                  "pageRef": "/services",
                  "weight": 20
               }
            ]
         },
         "weight": 2
      }
   }
}

方法 2 – 使用配置目錄

對於結構較為複雜的選單,創建一個 配置目錄,並將選單項目拆分為多個文件,每個語言一個文件。例如:

config/
└── _default/
    ├── menus.de.toml
    ├── menus.en.toml
    └── hugo.toml
config/_default/menus.de.
     
main:
- name: Produkte
  pageRef: /products
  weight: 10
- name: Leistungen
  pageRef: /services
  weight: 20
[[main]]
  name = 'Produkte'
  pageRef = '/products'
  weight = 10
[[main]]
  name = 'Leistungen'
  pageRef = '/services'
  weight = 20
{
   "main": [
      {
         "name": "Produkte",
         "pageRef": "/products",
         "weight": 10
      },
      {
         "name": "Leistungen",
         "pageRef": "/services",
         "weight": 20
      }
   ]
}
config/_default/menus.en.
     
main:
- name: Products
  pageRef: /products
  weight: 10
- name: Services
  pageRef: /services
  weight: 20
[[main]]
  name = 'Products'
  pageRef = '/products'
  weight = 10
[[main]]
  name = 'Services'
  pageRef = '/services'
  weight = 20
{
   "main": [
      {
         "name": "Products",
         "pageRef": "/products",
         "weight": 10
      },
      {
         "name": "Services",
         "pageRef": "/services",
         "weight": 20
      }
   ]
}

使用翻譯表

在渲染選單中每個項目的文本時,[示例選單模板] 會這樣做:

{{ or (T .Identifier) .Name | safeHTML }}

它使用選單項目的 identifier 查詢當前語言的翻譯表並返回翻譯的字串。如果翻譯表不存在,或者 identifier 鍵在翻譯表中沒有,則回退到使用 name

identifier 取決於您如何定義選單項目:

  • 如果您使用區段頁面選單 [自動] 定義選單項目,identifier 是該頁面的 .Section
  • 如果您在網站配置中 [定義] 選單項目或 [在前置資料中] 定義,請將 identifier 屬性設置為所需的值。

例如,如果您在網站配置中定義選單項目:

選單條目的本地化

在 Hugo 中,您可以定義選單條目並使用翻譯表來本地化它們。以下是一個範例,顯示如何定義選單條目並創建對應的翻譯。

定義選單條目:

[[menus.main]]
  identifier = 'products'
  name = 'Products'
  pageRef = '/products'
  weight = 10
[[menus.main]]
  identifier = 'services'
  name = 'Services'
  pageRef = '/services'
  weight = 20

創建翻譯條目:

在翻譯表中,為每個選單條目創建對應的翻譯:

products = 'Produkte'
services = 'Leistungen'

缺少的翻譯

如果某個字串在當前語言中缺少翻譯,Hugo 會使用默認語言的值。如果沒有設置默認值,則會顯示空字串。

要可視化缺少的翻譯,可以啟用 [enableMissingTranslationPlaceholders] 配置選項,Hugo 會標記所有未翻譯的字串,並顯示 [i18n] identifier,其中 identifier 是缺少翻譯的 ID。

如果需要合併其他語言的內容(即缺少的翻譯),可以參考 lang.Merge

要追蹤缺少的翻譯字串,運行以下命令:

hugo --printI18nWarnings | grep i18n
i18n|MISSING_TRANSLATION|en|wordCount

多語言主題支持

若您的主題支持多語言模式,則模板中的 URL 需要遵循一些準則:

  • 使用內建的 .Permalink.RelPermalink
  • 使用 relLangURLabsLangURL 函數來構建 URL,或者使用 {{ .LanguagePrefix }} 來為 URL 添加語言前綴

當您設置了多語言時,LanguagePrefix 方法會返回 /en(或當前語言)。如果未啟用此功能,則返回空字串(對於單語言網站無害)。

使用 hugo new content 創建多語言內容

若將翻譯內容組織在同一目錄中,請使用以下命令:

hugo new content post/test.en.md
hugo new content post/test.de.md

若將翻譯內容組織在不同目錄中,請使用以下命令:

hugo new content content/en/post/test.md
hugo new content content/de/post/test.md