HUGO
Menu
GitHub 87548 stars Mastodon

Hugo 多語言模式

為每種語言和區域本地化你的項目,包括翻譯、圖像、日期、貨幣、數字、百分比和排序順序。Hugo 的多語言框架支持單主機和多主機配置。

配置

請參閱 configure languages

翻譯內容

有兩種方法可以管理內容翻譯。兩種方法都確保每個頁面都分配了語言並鏈接到其對應的翻譯。

按文件名翻譯

考慮以下示例:

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

第一個文件分配了英語並鏈接到第二個。 第二個文件分配了法語並鏈接到第一個。

它們的語言根據添加到文件名的語言代碼後綴分配。

通過具有相同的路徑和基本文件名,內容片段作為翻譯頁面鏈接在一起。

如果文件沒有語言代碼,將分配默認語言。

按內容目錄翻譯

此系統為每種語言使用不同的內容目錄。每種語言的 content 目錄使用 contentDir 參數設置。

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

第一個文件分配了英語並鏈接到第二個。 第二個文件分配了法語並鏈接到第一個。

它們的語言根據它們放置的 content 目錄分配。

通過具有相同的路徑和基本名稱(相對於它們的語言 content 目錄),內容片段作為翻譯頁面鏈接在一起。

繞過默認鏈接

任何共享相同 translationKey(在 front matter 中設置)的頁面都將作為翻譯頁面鏈接,無論基本名稱或位置如何。

考慮以下示例:

  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 front matter 參數設置為 about,它們將作為翻譯頁面鏈接。

本地化永久鏈接

因為使用路徑和文件名來處理鏈接,所有翻譯頁面將共享相同的 URL(除了語言子目錄)。

要本地化 URL:

  • 對於常規頁面,在 front matter 中設置 slugurl
  • 對於 section 頁面,在 front matter 中設置 url

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

---
slug: a-propos
title: A Propos
---
+++
slug = 'a-propos'
title = 'A Propos'
+++
{
   "slug": "a-propos",
   "title": "A Propos"
}

在渲染時,Hugo 將構建 /about//fr/a-propos/ 而不影響翻譯鏈接。

頁面 bundle

為了避免復制文件的負擔,每個 Page Bundle 繼承其鏈接的翻譯頁面的 bundle 的資源,內容文件(Markdown 文件、HTML 文件等)除外。

因此,在模板中,頁面將可以訪問所有鏈接頁面的 bundle 的文件。

如果在鏈接的 bundle 中,兩個或多個文件共享相同的基本名稱,則只包含一個文件,選擇如下:

  • 如果存在,來自當前語言 bundle 的文件。
  • 按語言 Weight 順序在 bundle 中找到的第一個文件。

Page Bundle 資源遵循與內容文件相同的語言分配邏輯,按文件名(image.jpgimage.fr.jpg)和目錄(english/about/header.jpgfrench/about/header.jpg)。

引用翻譯內容

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

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 模板中,然後包含在任何模板中。如果給定頁面沒有翻譯,它將不打印任何內容。

上面還使用了下一節中描述的 i18n function

列出所有可用語言

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

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

字符串翻譯

請參閱 lang.Translate 模板函數。

本地化

以下本地化示例假設站點的主要語言是英語,翻譯為法語和德語。

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
      }
   }
}

日期

使用此 front matter:

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" }}

渲染的頁面顯示:

Language Value
English Wednesday, November 3, 2021
Français mercredi 3 novembre 2021
Deutsch Mittwoch, 3. November 2021

有關詳細信息,請參閱 time.Format

貨幣

使用此模板代碼:

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

渲染的頁面顯示:

Language Value
English $512.50
Français 512,50 $US
Deutsch 512,50 $

有關詳細信息,請參閱 lang.FormatCurrencylang.FormatAccounting

數字

使用此模板代碼:

{{ 512.5032 | lang.FormatNumber 2 }}

渲染的頁面顯示:

Language Value
English 512.50
Français 512,50
Deutsch 512,50

有關詳細信息,請參閱 lang.FormatNumberlang.FormatNumberCustom

百分比

使用此模板代碼:

{{ 512.5032 | lang.FormatPercent 2 }}

渲染的頁面顯示:

Language Value
English 512.50%
Français 512,50 %
Deutsch 512,50 %

有關詳細信息,請參閱 lang.FormatPercent

菜單

菜單條目的本地化取決於你如何定義它們:

  • 當你使用 section 頁面菜單 automatically 定義菜單條目時,你必須使用翻譯表來本地化每個條目。
  • 當你 in front matter 定義菜單條目時,它們已經根據 front matter 本身本地化。如果 front matter 值不足,使用翻譯表來本地化每個條目。
  • 當你 in site configuration 定義菜單條目時,你必須在每個語言鍵下創建特定語言的菜單條目。如果菜單條目的名稱不足,使用翻譯表來本地化每個條目。

創建特定語言的菜單條目

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

對於具有少量條目的簡單菜單,使用單個配置文件。例如:

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 – 使用配置目錄

對於更復雜的菜單結構,創建 configuration directory 並將菜單條目拆分為多個文件,每種語言一個文件。例如:

config/
└── _default/
    ├── menus.de.toml
    ├── menus.en.toml
    └── hugo.toml
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
      }
   ]
}
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
      }
   ]
}

使用翻譯表

當渲染每個菜單條目中顯示的文本時,example menu template 執行以下操作:

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

它使用菜單條目的 identifier 查詢當前語言的翻譯表並返回翻譯的字符串。如果翻譯表不存在,或者翻譯表中不存在 identifier 鍵,它將回退到 name

identifier 取決於你如何定義菜單條目:

例如,如果你在站點配置中定義菜單條目:

menus:
  main:
  - identifier: products
    name: Products
    pageRef: /products
    weight: 10
  - identifier: services
    name: Services
    pageRef: /services
    weight: 20
[menus]
  [[menus.main]]
    identifier = 'products'
    name = 'Products'
    pageRef = '/products'
    weight = 10
  [[menus.main]]
    identifier = 'services'
    name = 'Services'
    pageRef = '/services'
    weight = 20
{
   "menus": {
      "main": [
         {
            "identifier": "products",
            "name": "Products",
            "pageRef": "/products",
            "weight": 10
         },
         {
            "identifier": "services",
            "name": "Services",
            "pageRef": "/services",
            "weight": 20
         }
      ]
   }
}

在翻譯表中創建相應的條目:

products: Produkte
services: Leistungen
products = 'Produkte'
services = 'Leistungen'
{
   "products": "Produkte",
   "services": "Leistungen"
}

缺失的翻譯

如果字符串沒有當前語言的翻譯,Hugo 將使用默認語言的值。如果沒有設置默認值,將顯示空字符串。

在翻譯 Hugo 網站時,能夠有缺失翻譯的視覺指示器可能很方便。enableMissingTranslationPlaceholders configuration option 將用佔位符 [i18n] identifier 標記所有未翻譯的字符串,其中 identifier 是缺失翻譯的 id。

Hugo 將使用這些缺失翻譯佔位符生成你的網站。它可能不適合生產環境。

對於合並來自其他語言的內容(即缺失的內容翻譯),請參閱 lang.Merge

要追蹤缺失的翻譯字符串,使用 --printI18nWarnings 標志運行 Hugo:

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

多語言主題支持

要在主題中支持多語言模式,必須考慮模板中的 URL。如果有多種語言,URL 必須滿足以下條件:

  • 來自內置的 .Permalink.RelPermalink
  • 使用 relLangURLabsLangURL 模板函數構建,或前綴為 {{ .LanguagePrefix }}

如果定義了多種語言,LanguagePrefix 方法將返回 /en(或當前語言)。如果未啟用,它將是空字符串(因此對單語言 Hugo 網站無害)。

使用 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

Last updated: January 1, 0001
Improve this page