Hugo 不完美教程 - VI: Multilingual 多语言支持

前言

shot.jpg

本静态站点用于演示之用,使用 Hugo 构建,以及 Markdown 供应内容。

流行的静态站点框架有以下几个:

演示站点有两个访问入口:

此站点提供了一篇关于 Hugo 静态站点生成框架的入门教程。

代码仓库地址如下,查看 hugo-project 分支是原文件,master 分支是发布的静态站点文件:


title: "VI: Multilingual 多语言支持"
description: "坚果的 Hugo 教程"
date: 2020-08-06T20:14:08-04:00
featured_image_: "/assets/IMG_20181101_233654_s.jpg"
summary: Hugo 的多语言支持是深入各个方面的,包括页面的语言、数据文件的多语言、i18n 多语言字符串转换函数等。多语言的内容组织方式有两种,文件名组织和目录结构组织。多语言可以与菜单很好地结合,让静态站点也可以拥有动态站在一样的效果。
tags: ["hugo"]
disable_share: false


Multilingual 多语言支持

Hugo 的多语言支持是深入各个方面的,包括页面的语言、数据文件的多语言、i18n 多语言字符串转换函数等。

在 config.toml 配置中,DefaultContentLanguage 设置默认的语言,在 [languages] 区定义多语言相应配置:

{{< code file="config.toml">}}
DefaultContentLanguage = "en"
copyright = "Everything is mine"

defaultContentLanguageInSubdirto = true

[languages]
  [languages.ar]
    LanguageName = "阿拉伯语"
    languagedirection = "rtl"
    title = "مدونتي"
    weight = 2
  [languages.en]
    LanguageName = "英文"
    title = "My blog"
    weight = 1
    [languages.en.params]
      linkedin = "https://linkedin.com/whoever"
  [languages.fr]
    LanguageName = "法语"
    title = "Mon blogue"
    weight = 2
    contentDir = content/french
    [languages.fr.params]
      linkedin = "https://linkedin.com/fr/whoever"
      [languages.fr.params.navigation]
        help = "Aide"

[params]
  [params.navigation]
    help = "Help"

{{< /code >}}
对应到些没有多语言配置的参数,比如 help 在定义了 fr 语版本,那么在使用 ar 或 en 时就会自动回滚到顶级的 help = "Help"

<title>{{ .Param "title" }}</title>

多语言的内容组织方式有两种,文件名组织和目录结构组织:

  • content/about.md
  • content/contact.md
  • content/about.fr.md ✅
  • content/french/about.md ✅
  • content/french/a-propos.md 🚫

在 config.yaml 配置文件中,defaultContentLanguageInSubdirto 可以设置默认的语言也在内容子目录中,而 contentDir 参数可以为具体语言指定其内容目录名称。

可以配置禁用某些语言:

disableLanguages = ["fr", "ja"]

通过环境变量可以覆盖禁用配置:

HUGO_DISABLELANGUAGES="fr ja"
HUGO_DISABLELANGUAGES=" "

翻译内容连接设置是很重要的步骤,通过在 MD 内容文件的扉页设置 translationKey,可以

# From all three pages: about.md, a-propos.fr.md, acerda.es.md
---
translationKey: about
---

Hugo 将链接的翻译内容保存在页面对象的两个变量中:

  • .Translations 包含已链接的页面;
  • .AllTranslations 包含已经链接的页面,包括当前翻译的页面。

这两个集合按 language Weight 设置的值排序,值小的靠前。.IsTranslated 表示当前查看的页面是否有相应的翻译内容页面,如果有,就可以在以上两个页面变量集合中获取。

{{ if .IsTranslated }}
  {{ range .Translations }}
  <link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}" title="{{ .Language.LanguageName }}">
  {{ end }}
{{ end }}

{{ if .IsTranslated }}
  <nav class="LangNav">
  {{ range .Translations }}
    <a href="{{ .Permalink }}">{{ .Name }} - {{ .Title }}</a>
  {{ end}}
  </nav>
{{ end }}

设置语言后,模板文件的搜索会按语言调整,例如加载一个 AMP 页面,index.fr.amp.html 会优先于 index.amp.html 被选中,但 index.fr.html 会作为前两个模板的备选,只有它们缺失时有效。

AMP - Accelerated Mobile Pages 是 Google 联合 8 家科技公司发起的移动页面加速开源项目。它带来的结果就是,你真的可以瞬时打开一个网页了,速度快到第一次使用的人难以相信这竟然是 Web 页面。

从技术方面来说,采用 AMP 技术的网页之所以可以打开的这么快,这主要得益于它剔除了网页代码中各种可能会拖慢速度的部分,比如第三方的脚本文件、一些 HTML 标签、广告追踪器等等,所有脚本按异步执行。

在页面加速这方面,Facebook 开发了交互式媒体内容创建工具 Instant Articles,目标都是要使用户浏览 Web 的体验得到提升,使用户感觉就像在使用本地应用程序一样。

为了获得更好 SEO 效果,多语言页面的 URL 可以在页面中配置扉页的 slug 参数进行相应的修改:

# about.fr.md
title: À Propos
slug: a-propos

# acerda.es.md
title: Acerda
slug: acerda

这样,模板目录结构就有了一些变化,相应在页面 URL 也相应改变:

fr/a-propos/index.html 🇫🇷 👌
es/acerda/index.html   🇪🇸 👌

Taxonomies and Blackfriday 多语言配置:

[Taxonomies]
  tag = "tags"

[blackfriday]
  angledQuotes = true
  hrefTargetBlank = true

[languages]
  [languages.en]
    title = "English"
    weight = 1
    [languages.en.blackfriday]
      angledQuotes = false
  [languages.fr]
    title = "Français"
    weight = 2
    [languages.fr.Taxonomies]
      plaque = "plaques"

数据文件的多语言组织:

data
  ├── en
  │   └── team.yaml
  └── fr
      └── team.yaml

多语言数据的使用,先通过 index 函数获取站点配置的语言对应的数据文件,再使用:

{{ $data := index .Site.Data .Site.Language.Lang }}
{{ range $data.team }}
    <a href="{{ .url }}">{{ .name }}</a>
{{ end }}

多语言主机配置,以下示范根据主机域名使用不同的语言:

[languages]
  [languages.en]
    baseURL = "https://example.com"
    languageName = "English"
    title = "In English"
    weight = 2
  [languages.fr]
    baseURL = "https://example.fr"
    languageName = "Français"
    title = "En Français"
    weight = 1

这两个语言配置对应生成两个发布内容目录:

public
├── en
└── fr

使用主题字符串也能实现内容的多语言转换,具体参考 i18n 函数。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335