Hugo 多语言模式
配置
请参阅 configure languages。
翻译内容
有两种方法可以管理内容翻译。两种方法都确保每个页面都分配了语言并链接到其对应的翻译。
按文件名翻译
考虑以下示例:
/content/about.en.md/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 的值可以是任何有效的路径——甚至是绝对路径引用。唯一的限制是内容目录不能重叠。
考虑以下示例与上面的配置结合:
/content/english/about.md/content/french/about.md
第一个文件分配了英语并链接到第二个。 第二个文件分配了法语并链接到第一个。
它们的语言根据它们放置的 content 目录分配。
通过具有相同的路径和基本名称(相对于它们的语言 content 目录),内容片段作为翻译页面链接在一起。
绕过默认链接
任何共享相同 translationKey(在 front matter 中设置)的页面都将作为翻译页面链接,无论基本名称或位置如何。
考虑以下示例:
/content/about-us.en.md/content/om.nn.md/content/presentation/a-propos.fr.md
translationKey: about
translationKey = 'about'
{
"translationKey": "about"
}
通过在所有三个页面中将 translationKey front matter 参数设置为 about,它们将作为翻译页面链接。
本地化永久链接
因为使用路径和文件名来处理链接,所有翻译页面将共享相同的 URL(除了语言子目录)。
要本地化 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.jpg、image.fr.jpg)和目录(english/about/header.jpg、french/about/header.jpg)。
引用翻译内容
要创建翻译内容链接列表,使用类似以下的模板:
{{ 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 可用于列出所有翻译,包括页面本身。在首页上,它可用于构建语言导航器:
<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.FormatCurrency 和 lang.FormatAccounting。
数字
使用此模板代码:
{{ 512.5032 | lang.FormatNumber 2 }}渲染的页面显示:
| Language | Value |
|---|---|
| English | 512.50 |
| Français | 512,50 |
| Deutsch | 512,50 |
有关详细信息,请参阅 lang.FormatNumber 和 lang.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.tomlmain:
- 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 取决于你如何定义菜单条目:
- 如果你使用 section 页面菜单 automatically 定义菜单条目,
identifier是页面的.Section。 - 如果你 in site configuration 或 in front matter 定义菜单条目,将
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 - 使用
relLangURL或absLangURL模板函数构建,或前缀为{{ .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