给Freemind主题增加显示博文修改时间的功能. 用hexo-browsersync实现server模式实时预览.

背景

在网上浏览博文的时候, 经常可以看到一些Hexo生成的站点文章有最后修改时间的属性, 所以一直以来都想给自己的博文增加这样的功能. 可惜拖着拖着到现在才想着实践. 原本想着只要在front matter上增加类似update属性, 然后修改ejs让它像date一样在边栏显示就可以了. 但是这样想的时候出现了一点问题, 因为直接从front matter提取的update是字符串, 没有format方法, 也不能传给date()函数. 在看了一些文章后才知道需要先将其转换为moment对象. 那么问题就变成了找到date是在哪里变成moment对象的即可. 另外还想实现的需求是: 如果front matter有updated属性, 则以updated为最后修改时间; 如果没有, 则获取文件的最后修改时间.

搜索date moment对象化代码

采用正则表达式, findgrep搜索js文件, 寻找date属性的moment实例化

1
2
3
$ find . -regex ".*\.js" | xargs grep -E "moment\(.*date)" --color -RnH
./node_modules/hexo/lib/plugins/helper/date.js:9: if (!isMoment(date)) date = moment(isDate(date) ? date : new Date(date));
./node_modules/hexo/lib/hexo/post.js:40: data.date = data.date ? moment(data.date) : moment();

可以看到date实例化在post.js的40行. 接下来在post.js中加入如下代码使data获得moment对象updated.

1
2
3
if (data.updated) {
data.updated = moment(data.updated);
}

但这样还不能满足我们的要求, 即要求updated属性不存在时获取文件最后修改时间, 作为文章最后修改时间. 根据参考资料1, 为获取文件路径, 除了post.js中已经引入的path外, 需要引入child_process库来调用系统的date命令.

1
const execSync = require('child_process').execSync;

于是修改上一步中的实例化if语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var lastMod = '';
if (data.updated) {
data.updated = moment(data.updated);
}
else {
// 对data.source进行判断, 否则在新建post时会报错
if (data.source) {
fp = pathFn.resolve(config.source_dir, data.source);
lastMod = execSync(`date -r ${fp} "+%Y-%m-%d %H:%M:%S"`).toString().trim();
data.updated = moment(lastMod);
}
else {
data.updated = data.date;
}
}

这样就使得每一个post对象获得了updated属性.

修改meta.ejs

得到updated属性后, 只要简单修改layout/_partial/post下的meta.ejs文件即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- date -->
<% if (item.date) { %>
<div class="meta-widget">
<i class="fa fa-clock-o"></i>
<%= item.date.format(config.date_format) %> created
</div>
<% if (item.updated) { %>
<% if (date(item.date) != date(item.updated)) { %>
<div class="meta-widget">
<i class="fa fa-pencil"></i>
<%= item.updated.format(config.date_format) %> last modified
</div>
<% } %>
<% } %>
<% } %>

这里额外要求只有当dateupdated两者日期不同时, 才显示updated的时间. 效果如下图所示

完工 (ง •̀_•́)ง

Server模式实时预览

每次修改博文都要重新hexo generate再server挺麻烦的. 原来用的hexo-livereload已被归档, 现在可以用hexo-browsersync

1
2
npm install -g browsersync
npm install hexo-browsersync --save

之后再运行server模式. 当md文件有改动时, localhost页面会自动更新.

相关文章

Hexo笔记(一)——安装, Markdown写作与主题

参考资料

  1. hexo-filter-date-from-git/index.js
  2. SO - Print a file’s last modified date in Bash
  3. grep 递归指定文件遍历方法
  4. Hexo利用browsersync进行自动刷新

Comments