Sukka's Blog

童话只美在真实却从不续写

给「Suka」主题写文档,考虑到要做双语的文档,所以语言的切换就挺头疼,在这里卡了很久。

Hexo 本身支持同时生成不同语言版本的站点(可见 Hexo 官方文档中关于 国际化(i18n) 的配置样例),这样我只要做好文档主题的 i18n,然后只需要一套主题就可以生成不同语言的文档。

所以我选择把侧边栏里的条目写死在 layout 里,然后侧边栏里条目的文字通过 Hexo 的 i18n 解决。简体中文的文档就放在根目录下面,然后把英文版本的文档放在 en 子目录下面,只要每篇文档的 markdown 文件带上一个 permalinkFront-Matter 就行。

 文档的渲染以后的 HTML 文件目录结构大概像这样:
.
├── config
| └── index.html
├── dev
| └── index.html
├── en
| ├── dev
| | └── index.html
| ├── config
| | └── index.html
| └── index.html
└──index.html

然后就侧边栏文档目录的问题了。由于有文档的内容是放在文档的根目录的,而且中文和英语下的路径不一样,所以不能简单的使用相对路径问题解决。

当然可以写两套主题、甚至生成两次文档组合多语言也是可以的,但是这样不仅不方便、过于 Dirty,而且不适合交给持续集成来做。
我刚开始想法是,写两个侧边栏的组件分别用于中文和英文,通过判断当前页面语言决定用哪一个渲染,后来回过头来想,如果都能判断当前页面的语言了,为啥不直接通过判断决定输出路径呢?

不论怎么样,至少需要一个能判断当前页面语言的 API。在 Hexo 文档里翻来覆去去找有没有判断当前页面是以何种语言渲染的 API,但是没有找到;如果直接调用 config.language 会直接返回站点配置文件中设置的数组。

好吧,官方没有给这个 API,我就去 Hexo 的官方文档其它地方看看,找找有没有类似的能用的 API。然后看到一个 page.path,可以输出当前页面相对于 config.root 的相对路径,霎时灵光一闪——我只需要判断当前页面的路径中有没有 /en/,就可以判断当前页面的语言是不是英语了。

定义一个常量 en 负责判断当前页面的语言,并输出不同的路径前缀。

const en = page.path.indexOf('en') == -1 ? '' : 'en/';

然后为了像 url_for() 一样自动生成相对路径,我定义了一个 i18n_url_for() 的 function,调用这个 function 就可以生成路径,最终代码就像这样:

<%
const en = page.path.indexOf('en') == -1 ? '' : 'en/';
function i18n_url_for(uri) {
return config.root + en + uri
}
%>

用同样的思路,可以解决文档的语言切换问题。
首先还是定义一个 en 常量用来判断,然后通过判断 en 的值是 false 还是 true 决定是输出 跳转到简体中文 还是输出 跳转到英语 的按钮。至于按钮的 href 属性,也依赖 page.path 的方法,通过 replace() 方法替换 URL 中的字符串添加、去掉语言路径前缀。

实现代码:

<%
const en = page.path.indexOf('en') == -1;
%>

<% if (en === true) { %>
<a href="<%- url_for(page.path).replace('docs','docs/en').replace('index.html','') %>">English</a>
<% } else if (en === false) { %>
<a href="<%- url_for(page.path).replace('docs/en', 'docs').replace('index.html', '') %>"> 简体中文 </a>
<% } %>

本文作者 : Sukka
本文采用 CC BY-NC-SA 4.0 许可协议。转载和引用时请注意遵守协议!
本文链接 : https://blog.skk.moe/post/suka-docs-themes-i18n/

本文最后更新于 天前,文中所描述的信息可能已发生改变