从Hexo迁移到Hugo后,我发现了一个默认分类问题,对中文用户造成了一定的影响。
Hugo分类器
Hugo具有自定义Taxonomy(分类器)功能。为了方便用户使用,系统默认提供了两个预设分类:Category(类别)和Tag(标签)供快捷配置1。用户无需手动编写分类器,只需在配置文件中如下填写即可启用两个分类标准。
taxonomies:
category: catName
tag: tagName
系统会自动增加两个名为catName和tagName的分类标准。然后在文章里的Front Formatter中增加配置
catName:
- name1
- name2
tagName:
- name1
- name2
即可通过访问/catName和/tagName查看到两个分类下的所有类别。分类页面标题为设置的catName或tagName。
中文问题
这个方便的功能对于中文用户来说却存在一个问题。如果我们设置了如下分类标准
taxonomies:
category: 分类
tag: 标签
我们需要访问的页面地址,就变成了/分类和/标签,在地址栏中并不美观。如果使用英文作为分类名,页面上显示的就不是中文标题,而是英文标题。
对于一些人来说,这或许不是一个问题。但我的博客配置了多语言,在纯中文界面上显示英文标题对我来说不可接受,所以我一直在寻找解决办法。
解决方案一
我首先想到的方案是,为中文单独设置一个分类名称,然后自定义它的显示逻辑。根据官方文档2,Hugo渲染页面时有一套加载顺序,用户自定义配置可新建对应文件。
首先创建一个名称为zhTags的分类名,然后在博客目录下新建layouts/zhTags目录并创建terms.html.html的文件,即可自定义该分类的渲染逻辑。我稍微修改了博客主题paperMod的分类渲染配置,并写死名称为“标签”,如下所示。
{{- define "main" }}
{{- if .Title }}
<header class="page-header">
<h1>标签</h1>
{{- if .Description }}
<div class="post-description">
{{ .Description }}
</div>
{{- end }}
</header>
{{- end }}
<ul class="terms-tags">
{{- $type := .Type }}
{{- range $key, $value := .Data.Terms.Alphabetical }}
{{- $name := .Name }}
{{- $count := .Count }}
{{- with site.GetPage (printf "/%s/%s" $type $name) }}
<li>
<a href="{{ .Permalink }}">{{ .Name }} <sup><strong><sup>{{ $count }}</sup></strong></sup> </a>
</li>
{{- end }}
{{- end }}
</ul>
{{- end }}{{/* end main */ -}}
看起来解决了中文分类的问题,但是我却并不满意。这个分类器的访问路径是/zh/zhTags,和英文不一致,代码里还写死了名称。有没有办法让中英文使用同一套分类标准,根据语言代码不同,显示不同的名称呢?
解决方案二
Hugo原生支持多语言功能,在又查阅了一遍文档后,我发现了一个好用的函数:lang.Translate3, 只需要配置好多语言,它可以自动按配置渲染不同的内容。
删除原来的配置,统一中英文分类名成为categories,新建layouts/categories目录并创建terms.html.html的文件,内容只需稍作修改。
{{- define "main" }}
{{- if .Title }}
<header class="page-header">
<h1>{{ lang.Translate .Title }}</h1>
{{- if .Description }}
<div class="post-description">
{{ .Description }}
</div>
{{- end }}
</header>
{{- end }}
<ul class="terms-tags">
{{- $type := .Type }}
{{- range $key, $value := .Data.Terms.Alphabetical }}
{{- $name := .Name }}
{{- $count := .Count }}
{{- with site.GetPage (printf "/%s/%s" $type $name) }}
<li>
<a href="{{ .Permalink }}">{{ .Name }} <sup><strong><sup>{{ $count }}</sup></strong></sup> </a>
</li>
{{- end }}
{{- end }}
</ul>
{{- end }}{{/* end main */ -}}
上述代码仅仅修改了<h1>{{ lang.Translate .Title }}</h1>这一段。
然后根目录下新增翻译配置文件/i18n/zh.yaml和/i18n/en.yaml,配置内容分别如下:
Categories: 分类
Tags: 标签
Categories: Categories
Tags: 标签
这样在中文页面中,当标题是Categories时会自动翻译成分类,页面显示终于正常了,不同语言文章也都使用同一个分类器,无需单独创建新的分类。