Hexo的文章计数转移到JS上

背景

因为服务上的资源有限,在服务器上生成静态资源会死机,所以静态资源都是在本地生成,并加入git管理。
这样,每次发布新文章时,public文件夹下所有的页面都会有修改记录。
修改的内容就只有文章数目,类别数,标签数。

于是构想能把这部分经常变化的集中起来。
让增加新文章的时候,这些变化不要影响到以前的页面。

思路

很容易想到这部分数据放js统修改页面dom。
但这个js还得是外部的js,如果是页面内部的js,对js的修改也会反映到html页面文件的修改的。

同时这个js中,还得有hexo统计的信息。

实现

增加js

在所有页面中增加一个js,还是比较容易的。

以Next主题为例:
页面布局的文件是themes\next\layout\_layout.swig
文件中的include '_scripts/boostrap.swig'
包含了script中的boostrap.swig模板。
模板中,

1
2
3
4
5
6
7
8
9
10
{%
set boot_scripts = [
'src/bootstrap.js',
'src/articleCount.js'
]
%}

{% for bs in boot_scripts %}
<script type="text/javascript" src="{{ url_for(theme.js) }}/{{ bs }}?v={{ theme.version }}"></script>
{% endfor %}

增加src/articleCount.js,这个js应该放到themes\next\source\js\src目录下

移除原来的计数

修改文件themes\next\layout\_macro\sidebar.swig
搜索site-state-item-count类名的div。
把后面的

1
2
3
{{ site.categories.length }}
{{ site.posts.length }}
{{ site.tags.length }}

移除
这样,原来显示计数的位置就会是空的。

当然为了让js可以写入,要给这个div加一个id。比如:

1
<span id="site.categories.length" class="site-state-item-count"></span>

把数据转放到主页的标签内

现在sidebar中已经没有文章计数了。
现在问题中在swig文件中可以引用hexo中的变量。但js文件中不行。
没有想到有什么好方法。于是用个粗暴的方法:
把数据存index页面。用python解析数据,生成js。

修改themes\next\layout\_partials\footer.swig文件
增加下面代码

1
2
3
{% if is_home() %}
<div style="display: none;" id="countdata">{{ site.posts.length }},{{ site.categories.length }},{{ site.tags.length }}</div>
{% endif %}

只有主页有,建一个隐藏的 div,div中放数据。

读取标签内的数据,生成js

再写一个python脚本。提取出index.html中的数据。
脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#encoding:utf-8
import re
import string

inputfile= "public/index.html"
inputf= open(inputfile,'r')
text= inputf.readlines()
array = re.findall(r'id="countdata">(\d*),(\d*),(\d*),(\d{2}.\d)k',str(text))
print array
keyvalue = {'posts':array[0][0],'categories':array[0][1],'tags':array[0][2],'count':array[0][3]}

outputfile = "public/js/src/articleCount.js"
tempaltestr= '''
document.getElementById("site.posts.length").innerHTML= ${posts};
document.getElementById("site.categories.length").innerHTML =${categories}
document.getElementById("site.tags.length").innerHTML = ${tags};
document.getElementById("post-count-id").innerHTML = "共${count}k字";
'''
tpl = string.Template(tempaltestr)
f = open(outputfile,'w')
f.write(tpl.substitute(keyvalue))
f.close()

功能就是读取index.html中的数据,生成js文件。
js文件会在页面中引用。
于是js文件会修改页面dom,把文章计数等数据更新到dom中。

总结

这只能算是一个临时的解决方案。
在做这个过程中了解页面的一些组织方案。


使用过几次之后,增加的:
经过改造之后,生成文件的速度明显变快。原来要1min,现在20s就可以完成。
猜想是因为有很多页面没有变化,不用重新生成,不用再统计字数据。