到 ICARUS 中去 —— 记对 Icarus 主题的使用及微调
伊卡洛斯乘风飞跃迷楼,Icarus 倚水谈笑生风
写写迁移到 Icarus 后做的一点微小工作
动机
大约 16 年左右吧,我开了自己的个人博客,打算记录一下各种事情。从 Wordpress 到 Typecho,最终还是归於 Hexo。
在还用着 Typecho 的时候,发掘到了 Hexo-Theme-Typecho 这个主题。直到现在我也依然觉得它足够惊艳。后来作者转坑到了 Hexo 上。自然地,我也到了 Hexo 这个平台,继续用 Hexo-Theme-Material 这个主题,也误打误撞提交了一些 PR。慢慢地,包括作者在内的协作者团队全部解散,这个主题终於寿终正寝。虽说小修小补也不是不能用,但其过於臃肿的资源库是不可逆转的问题。自己小修小补又用了三年,还是换了吧。
这两三年也因为各种原因,写的博客没有传上来。还是留下自己看为好,就不上传啦。
这次换到了 Icarus,也在这记录一下对它做的一点调整和功能定制吧(一点微小的工作)。
老规矩先分享一首歌 —— 陈奕迅《失忆蝴蝶》
改动概要
所改动的几乎都是一些实用但小的地方,具体胪列如下:
- 新增 网站备案号
- 新增 版权声明
- 调整 文章发布时间的显示格式
- 调整 黏性目录
- 调整 Valine 评论的样式
- 调整 个人资料卡片的按钮
- 新增 对个人主页的 DNS-Prefetch
- 新增 个人映像图库页面(开发中)
- 新增 夜间模式(开发中)
改动详情
在自己动手前亦查阅过一些前辈们的资料,但几乎都是在 Icarus 2.0 时代写就的。2.0 版本的 Icarus 依赖是采用 .ejs
文件的,而作者在 3.0 版本采用了 .jsx
进行重构,因而这些教程已不再适用。
虽然代码结构已经天差地别,但大致思路仍然相似,因而写就了这篇文章以供参考吧。
新增 网站备案号
众所周知,若果希望在国内比较舒心地建站(如欲使用 CDN 或者 OSS 对象存储等服务),备案是必不可少的。
可惜的是,Icarus 並未集成该功能,所以需要自己加上。
源码改动胪列如下:
themes\icarus\layout\common\footer.jsx
1 | <!-- 第 28 行 - Line 28 --> |
新增 版权声明
版权声明不仅仅是对作者著作权的保护,同时亦保障用户可以更方便地进行转载、演绎等。更重要的是,以自身为起点逐步培养起全体社会的版权意识,由此促进文化的交流,看到思想碰撞产生的动人火花。
Icarus 的作者已经将这项功能纳入 Todo 清单,相信不久的将来就能体验到。
此处我简要阐述下自己的实现思路:获取当前文章页信息,並在每篇文章页的最后位置添加模块,同时使用 CSS 对其进行样式渲染。
Icarus 内部采用的时间标记为 ISO 标准时间,其广泛采用於各种跨时区的应用系统中。同时这套系统兼顾了一些历史因素,了解后有用的知识增加了,详情参阅:
以一个 ISO 标准时间为例:2020-04-13T05:04:39.000Z
。显然,其並不适合直接显示在前端上,因而我们需要对其进行处理。我的解决思路是将其转化为一个 Date 对象,再使用其自带的方法对其进行格式化输出。
由于 JavaScript
的 Date 类型可以接受 ISO 标准时间为参数,当对象新建完毕后,就能够对其进行相应的操作了。这里给出一点关於 Date 类型的方法:
方法 | 描述 |
---|---|
getDate() | 从 Date 对象返回一个月中的某一天 (1 ~ 31) |
getDay() | 从 Date 对象返回一周中的某一天 (0 ~ 6) |
getMonth() | 从 Date 对象返回月份 (0 ~ 11) |
getFullYear() | 从 Date 对象以四位数字返回年份 |
getTimezoneOffset() | 返回本地时间与格林威治标准时间 (GMT) 的分钟差 |
toUTCString() | 根据世界时,把 Date 对象转换为字符串 |
toLocaleString() | 根据本地时间格式,把 Date 对象转换为字符串 |
toLocaleTimeString() | 根据本地时间格式,把 Date 对象的时间部分转换为字符串 |
toLocaleDateString() | 根据本地时间格式,把 Date 对象的日期部分转换为字符串 |
更多方法请参阅 W3School - JavaScript Date 对象。
惟须改动若干处,源码改动胪列如下:
themes\icarus\layout\common\article.jsx
1 | /* 第 27 行 - Line 27 */ |
1 | <!-- 第 81 行 - Line 81 --> |
实际上可见,我仅仅是使用了 DateUTC.toTimeString()
方法获取时间,而年月日的获取则是采用 themes\icarus\layout\common\article.jsx
中自带的时间生成方法 {date(page.date)}
,通过二者的拼接生成形如 2020-04-13 13:04:39 GMT+0800 (中国标准时间)
的时间标签。
好了,到这里,版权模块的添加已经完成,剩下的就是采用 CSS 样式表对其进行渲染了。
themes\icarus\source\css\style.styl
1 | /* 第 19 行 - Line 19 */ |
实际上,.styl
文件的本质是一个公共样式表。简单而言即是一个抽象的 CSS 样式表模板,因而直接书写 CSS 代码亦无任何问题。
做完这些工作后,就可於文章页末尾处看到以下样式的版权声明:
- 本文标题:到 ICARUS 中去 —— 记对 Icarus 主题的使用及微调
- 本文作者:Kitcham
- 本文链接:https://blog.uiharu.top/archives/use-and-tune-for-hexo-icarus-theme.html
- 发布时间:2020-08-13 11:55:24 GMT+0800 (中国标准时间)
- 版权声明:如非特别声明,本博客文章均依据 CC BY-NC-SA 4.0 协议发行。详情请参阅 相关说明
调整 文章发布时间的显示格式
Icarus 自带的文章时间解析器会显示为一个约数,如几日前,3年前等。这无论对作者抑或是读者都是一个不太友好的设计。
一开始我认为时间格式是在渲染阶段就已经确定好的了,於是乎我翻遍了所有渲染代码,也未曾发现对应的代码。最后,我用 Chrome 查看生成好页面的源代码,发现关於时间的标识是这样的:
https://blog.uiharu.top/index.html
1 | <div class="level-left"> |
嗯~ o( ̄▽ ̄)o???好像有甚么地方不对。
你确实没看错,源码里的时间格式是 2020-08-13
这样很人性化的,但为什么显示出来就是几日前,几年前。我初步判断,应该是某个 JS 函数控制了这个字段。於是我带着目标寻找这个函数,最后证实了在 main.js
中存在这个转换函数。
该函数事先获取了当前本地时间,再与文章页标签中的 ISO 标准时间进行比较,转换为一个时间约数。
themes\icarus\source\js\main.js
1 | /* 第 19 行 - Line 19 */ |
此处仅需将该函数注释或删除即可显示正常时间格式。
调整 黏性目录
因 Icarus 自带的目录並不具备黏性,在 PC 等宽屏终端浏览时,目录会随之滚动。细思一下,还是将目录设定为黏性较好,便於读者随时切换章节。
Icarus 的作者将 Icarus 相关挂件插件剥离,存放於 node_modules\hexo-component-inferno\lib\view\widget
中,便於移植及更新,同时缩减主题的体积。而这与 2.0 版本的 Icarus 主题目录结构相异甚远。
此处需对两个文件进行调整,胪列如下:
Hexo\node_modules\hexo-component-inferno\lib\view\widget\toc.js
1 | /* 第 195 行 - Line 195 */ |
修改好 JS 之后,还需对 CSS 样式表进行处理,仅在宽屏设备上开启黏性目录,以免在手机等设备上因列数为 1 而无法正常弹出目录。
themes\icarus\source\css\style.styl
1 | /* 第 29 行 - Line 29 */ |
调整 Valine 评论的样式
如惟须调整默认文字提示、表单项等,请参照 Valine 配置文档 在 Icarus 配置文件中配置相应项目即可。
以调整默认文字提示为例,修改如下:
themes\icarus\_config.yml
1 | /* 第 141 行 - Line 141 */ |
调整 个人资料卡片的按钮
因个人资料卡片的“关注我”似乎对我用处不大,因此修改成“关于我”吧。
此处亦需对文件进行调整,胪列如下:
themes\icarus\languages\zh-CN.yml
1 | /* 第 19 行 - Line 19 */ |
可谓是这里最简单粗暴的修改了。
新增 对个人主页的 DNS-prefetch
在 HTTP 1.0/1.1 协议中,浏览器的並发请求数量是受到限制的。於此同时,用户打开一个新页面后,势必会先浏览当前页面,再行点击打开新页面。而其中的“空白时间”如果不加以利用,则显得略微浪费了。
为对我个人主页和博客之间的跳转体验进行提升,我采用了 DNS-prefetch
。
域名的 DNS 解析是需要耗费一定时间的,通常约为 10-120 ms 左右。如果我们可以如上所述对“空白时间”加以利用,则可以免于发送 DNS fetch
请求从而节省掉这 10-120 ms,一定程度上提升用户的浏览体验。这个加以利用的方法即采用 DNS-prefetch
。
考虑到前端需要考虑不同浏览器的兼容问题,我们需要调查 DNS-prefetch
对不同浏览器的兼容性。那么,甚么浏览器可以支持该特性呢?我可以用 DNS-prefetch
提升用户的浏览体验吗?下图是一个来自 Can I use - Dns-Prefetch? 的兼容性报告,其列出了主流浏览器对其的兼容性。
可见,绝大多数浏览器甚至 IE ~都能够兼容,那么马上开始动工。
此处惟须修改一处地方:
themes\icarus\layout\common\head.jsx
1 | /* 第 150 行 - Line 150 */ |
仅需简单地添加 <link rel="dns-prefetch" href="https://example.com/">
,你就可以感受到 DNS-Prefetch 的强大。
新增 个人映像图库页面
开发中 - Developing…
请参照 印记 | 无垠映像 - Boundless Image
新增 友链页面夜间模式
请参照 Kitcham的友链页面,没人比我更懂方便 —— 透过 Github Action 优雅生成友链数据 及 为 ICARUS 而生的友情链接页面。
新增 夜间模式
开发中 - Developing…
结语
虽说 .ejs
和 .jsx
均为 JavaScript
的扩展,但二者的确是性格迥异。在这里感谢一些前辈们资料的帮助。接下来的时间就让我继续慢慢钻研 .jsx
吧。
参考资料
到 ICARUS 中去 —— 记对 Icarus 主题的使用及微调
https://blog.uiharu.top/archives/use-and-tune-for-hexo-icarus-theme.html