【笔记】Hexo配置多语言

前言

Hexo 6.3 在 NexT 8.18 主题下配置多语言支持(i18n)

安装渲染首页的插件

  • 只安装hexo-generator-index插件的情况下,_config.yml中的language选项无法同时配置多个值,所以无法为站点同时配置多个语言
1
yarn add hexo-generator-index

安装允许多语言的插件

  • 安装了hexo-generator-i18n插件后,_config.yml中的language选项才允许同时配置多个值,所以可以为站点同时配置多个语言
1
yarn add hexo-generator-i18n

配置多种语言

hexo/_config.yml
1
2
3
language:
- zh-CN
- en

配置翻译的页面(可选)

  • 在安装了hexo-generator-i18n插件后,可以配置哪些路径的页面或者哪些类型的页面会自动翻译,如果不配置只有首页会被翻译

i18n.type:指定哪些类型的文件会自动翻译

post:所有文章页面
page:所有非文章页面

i18n.generator:指定哪些路径的文件会自动翻译

index:首页
archive:归档页面
category:分类页面
tag:标签页面

hexo/_config.yml
1
2
3
4
5
6
7
8
9
i18n:
type:
- post
- page
generator:
- index
- archive
- category
- tag

配置翻译(可选)

  • 即便是不配置,NexT也提供了多语言的翻译缺省值

传送门

hexo/source/language.yml
1
2
3
4
5
6
7
zh-CN:
menu:
links: 友链

en:
menu:
links: friends

安装单语言首页的插件

  • 没有安装hexo-generator-index-i18n插件之前,虽然站点能同时显示两种语言的文章,但是不会将多种语言的文章分开,而是全部显示在主页
1
yarn add hexo-generator-index-i18n

配置单语言主页

  • 让主页只显示一种语言,从而将多种语言的文章分开为不同语言的主页
hexo/_config.yml
1
2
index_generator:
single_language_index: true

重新定义资源访问路径

  • 配置完成后,之前访问资源请求URL路径从http://localhost:4000/年/月/日/文章名变为http://localhost:4000/语言/年/月/日/文章名
hexo/_config.yml
1
permalink: :lang/:year/:month/:day/:title/

将旧的文章按照语言重新划分

  • 为所有文章添加lang标签

lang:配置当前文章的语言,由于已经修改了permalink配置,所以访问资源时自动根据当前的文章语言进行划分资源路径

1
2
3
4
---
title: 文章名
lang: zh-CN
---

批量添加语言标签脚本

hexo/source/scripts/SearchIsOrNotExistLangTagInFile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import os

# 计数器
exec_count = 0

script_src = os.getcwd()
os.chdir("../_posts")
base_src = os.getcwd()
filename_list = os.listdir("../_posts")

# 待处理的数据
file_src_list = []

# 寻找所有待处理的数据
for filename in filename_list:
if filename == ".DS_Store":
continue
# 获取文件绝对路径
file_src = f"{base_src}/{filename}"
# 读取文件
with open(file_src) as f:
content = f.read()
# 判定文件是否以存在lang标签
if content.find("lang: ") == -1:
# 记录这个文件的绝对路径
file_src_list.append(file_src)


# 将所有待处理的文件添加lang标签
for file_src in file_src_list:
# 读取到的文件内容
with open(file_src) as f:
content = f.read()
# 将文件添加lang标签,插入在date标签之前
content = content.replace("\ndate: ", "\nlang: zh-CN\ndate: ")
# 重新写入文件
with open(file_src, mode="w") as f:
f.write(content)
exec_count += 1
# DEBUG
print(f"== 添加lang标签完成 {file_src} ==")
print(f"== 完成进度 {exec_count}/{len(file_src_list)} ==")

将文章根据语言分开存储(可选)

  • 为配置完lang标签后,虽然可以实现资源请求URL路径的划分,但是在本地存储的文件仍旧全部在hexo/source/_post目录下,并没有根据语言分类
  • 手动将不同语言的文章文件放到对应语言目录下
    • 改操作并不会改变资源请求URL路径,只是方便管理,实际资源请求URL路径中的语言以文章内的lang标签为准
1
2
3
4
5
6
7
+ hexo
+ source
+ _post
+ zh-CN
- 中文文章.md
+ en
- 英文文章.md

为新文章配置默认的lang标签

hexo/scaffolds/post.md
1
2
3
4
---
title: {{ title }}
lang: zh-CN
---
  • 自此通过hexo new创建的新文章都会默认添加lang标签
    • 由于默认指定的是zh-CN,所以当创建文章后默认就是中文文章,想要改变为英文文章,只需要将zh-CN改为en即可

创建文章时存放到对应语言的目录(可选)

  • 配置完默认的lang标签后,虽然可以实现资源请求URL路径的划分,但是还是不能自动将新创建的文章移动到对应的目录下,hexo new创建文章时还是会在hexo/source/_post目录下

  • 通过修改配置实现新创建的文件自动存放到对应的语言目录下

hexo/_config.yml
1
new_post_name: :lang/:title.md
  • 只是配置完成后,当使用hexo new创建新文章时,将自动存放到hexo/source/_post/undefined目录下,因为没有指定语言目录,只有在创建文章时指定文章语言的参数才能放到对应目录下
1
hexo new --lang zh-CN 文章名

针对NexT主题优化

开启语言切换下拉列表

hexo/_config.next.yml
1
language_switcher: true

修复BUG

  • 如果切换回中文,URL中默认没有语言前缀,会跳转到无效页面
  • 手动强制添加/zh-CN作为URL前缀
hexo/source/rewrite_i18n_path.js
1
2
const element_for_i18n = document.querySelector("option[value='zh-CN']");
element_for_i18n.setAttribute("data-href", "/zh-CN" + element_for_i18n.getAttribute("data-href"));
hexo/source/_data/footer.njk
1
<script type="text/javascript" src="/rewrite_i18n_path.js" data-pjax=""></script>
hexo/_config.next.yml
1
2
custom_file_path:
footer: source/_data/footer.njk

完成

  • 至此,本文完成了对Hexo站点配置多语言的介绍,与网络上其他人不同的是,其他人采用为第二语言建立额外的项目,虽然也能解决问题,但是总体来说不是很优雅
  • 不过本案例也有不太完美的地方,例如英文文章需要手写,在这里提供两种解决方案,感兴趣的小伙伴请自己挖坑自己填
  1. 完全不采用本文的案例进行部署,而是在页面添加一个翻译按钮,实现浏览器在线翻译
  2. 通过脚本批量向ChatGPT发送请求进行Markdown文档翻译,在要求中如下编写
1
请帮我将如下Markdown文档翻译为英文,请不要修改任何Markdown格式,文章内容如下:

不过缺陷是ChatGPT回复的内容是限定字数的,也就是说内容较多的文章会无法翻译完全,解决方案如下(关于如何记录ChatGPT的回复内容,请参阅Openai官方API文档)

1
请继续回复

参考文献

Hexo——永久链接
Hexo——国际化
CSDN——PGzxc
xcatliu/hexo-generator-index-i18n
W.T.的博客
Jamling的博客