切换到fluid主题的记录

文章记录了切换到fluid过程、遇到的问题、解决的方案。
主要包括配置覆盖、文字统计、访问量统计、fluid少部分代码解析。

背景

最近用上gcp,准备把blog恢复,不知是nodejshexo,hexo-cli的版本问题还是hexo-generator-index插件的问题,在public文件中index.hmtl就是无法生成。通过开debughexo g --debug也没找到原因。
加上hexo已经升级了好几个版本,之前用的Next主题也升级了很多版本。
准备这次把Hexo及next主题都升级下。升级后觉得新版本Next主题没以前好看了。于是寻找一个新主题,

用上Fluid主题

用户手册[1]非常详细,我采取的是第二种方式,直接解压relase颁布的方式。目前使用的版本为1.9.2

阅读完配置指南及进阶用法,其实

特点分析

Fluid 相比 Next,个人的使用感受:

  • 文章顶部大图,及文章内容图片的展示效果较好。(之前不喜欢在文章中加图,但现在发现加个图阅读体验会提升的)
  • 导航菜单支持二级菜单(下拉菜单)。展示更多内容比较好分类。
  • 对于脚注TAG的支持。主题原生支持最好。当然hexo-renderer-markdown-it也可以实现相同功能。
  • 打字机效果很花哨。
  • 集成hexo-generator-search本地搜索。以前没用过插件,现在集成上去之后真香。
  • 有扩展性,支持注入代码。(应该是依托于Hexo的新版本特性吧)

在一天的使用过程中,对于些配置文件。Fluid相对国产些,考虑了大部分国区的服务,比如用的js,icon。
对于公共的服务比如字数统计,也支持的较少。

这是一个便签的示例

覆盖配置

这个设计的确是非常棒,更新主题再也不用再去theme的config改一次配置。

主要遇到的问题:

_config.fluid.yml不生效。

通过在source/_data/fluid_config.yml这里创建配置解决的。
文档上是说Hexo 低于 5.0.0 版本点的处理方法。但我的版本是Hexo 6.2.0

字数统计

因为我通过第二种方法下的解压relase的方式。在fluid_config.yml打开wordcount 之后,还是不法显示字数。

后来查到原因,原来是根目录下的hexo-wordcount依赖没装。

语言的选项

最开始配置的这个主题一直是英文。参考配置文档[2],在主题的配置文件中加language: zh-CN 也没用。

最后找到原因,之前Next的主题语言是language: zh-Hans,不是zh-CN。于是fluid就按默认的主题去展示了。在配置文件中加了language可能有限没有根目录下的高。像这类情况,我觉得代码中应该留一行警告,配置的语言未找到,不能啥都不提示,就按默认的走了。

后来加了自定义页,然后显示的是英文。这个也需要在source/_data/languages/zh-CN.yml 按fluid的模板补充对应的key。

访问量的展示

目前fluid只支持两家busuanzileancloud。统计支持多家。
但我用到的是firebase,就要自己去处理。
要分两部分,1,访问时,进行统计。2,对统计的内容进行展示

统计处理方案

按Fluid注入代码[3] 的方法。根目录下增加scripts/theme_inject.js

1
2
3
hexo.extend.filter.register('theme_inject', function(injects) {
injects.bodyEnd.file('default', 'source/_inject/firebase-visit.ejs', { key: 'value' }, -1);
});

source/_inject/firebase-visit.ejs中创建相关访问统计的代码。
代码可以参考之写的一篇文章[4]里的方法。
只不过要用上ejs模板的相关语法。当然这里也会在配置文件中增加开关。

主要的原理:

  • 页面被访问时,firebase的js请求服务器,在实时数据库中增加计数。
  • firebase-visit同时也获取服务器中每项的数量,通地js设置到对应的dom中。
  • 所谓的实时数据库,其实就是一个key-value的服务。

展示的处理方案

对于底部全局的访问量,直接在/firebase-visit.ejs写就行。

对于单文章的访问量展示就比较麻烦。

\themes\hexo-theme-fluid-1.9.2\layout\_partials\post\meta-top.ejs是处理访问量等信息的。
其中leancloudbusuanzi的处理都在这里。

于是依葫芦画瓢写了一个source/_inject/show_wordcount_total.ejs如下

1
2
3
4
5
6
7
8
9
10
<%# 处理每篇文章的阅读次数 #%>
<% if ( theme.web_analytics.firebase.show_detail ) { %>
<div class="mt-1">
<span id="firebase-page-views-container" class="post-meta" >
<i class="iconfont icon-eye" aria-hidden="true"></i>
<span id="detail_cnt">NA</span>
</span>
</div>
<% } %>

然后在scripts/theme_inject.js增加注入

1
2
3
hexo.extend.filter.register('theme_inject', function(injects) {
injects.bodyEnd.file('showword', 'source/_inject/show_wordcount_total.ejs', { key: 'value' }, -1);
});

这里只管挂dom。里面的值会在firebase-visit.ejs中动态获取,并更新。

遇到的问题

最开始,我直接用injects.footer.file注入文件,然后发现原页面footer中的内容都没。
为什么会没呢,因为我用的default做为注入的键名,表格下面说对于footer的注入点,fluid已经用过default键,就会直接覆盖。
所以读文档要仔细。

全站字数统计

这个主题的issues下,有个人提问[5]

下面有人回答

footer.ejs 文件添加下面这句代码,即可实现统计全站字数

<span><%= wordtotal(site) %></span>

这个方法,可以解决问题,但不优雅。
如果这个blog有很多文章,相当于每次生成的时候,因为下面的总站字数有变化,都会把全局的html改一次。
运行hexo g时就会很慢。

我的做法是把这个字数放js里。然后动态去改dom。

还是用上面的Fluid注入代码方式

1
2
3
hexo.extend.filter.register('theme_inject', function(injects) {
injects.bodyEnd.file('showword', 'source/_inject/show_wordcount_total.ejs', { key: 'value' }, -1);
});

然后在source/_inject/show_wordcount_total.ejs中写入相应的字数。g-post-count-id是在footer中加一空span就行。

1
2
3
<script type="text/javascript">
document.getElementById("g-post-count-id").innerHTML = "共<%= wordtotal(site) %>字";
</script>

参考


切换到fluid主题的记录
https://blog.fengcl.com/2022/08/20/fluid-theme/
作者
frank
发布于
2022年8月21日
许可协议