hexo 自动更新文章修改时间


首先,如果你之前没有为文章添加updated字段,需要先添加上。

1.为现有的文章添加updated字段

如果你现有文章已经有updated字段,此步骤可以跳过。

代码参考:批量写入文件的修改时间,原本的只能访问同一目录下的文件,我对其做了补充,能访问所有的文件(包括子文件夹)。

创建js文件:博客根目录/source/_posts/writeupdatetime.js,文件内容如下


#!/usr/bin/env node
/*
批量添加修改时间
用于bolg初始化修改时间
*/

console.log('脚本开始运行..');
var fs = require("fs"); //请求文件系统

var file = "./txt"; //设置读取和写入的文件,当前目录下的test文件
var RegExp=/(updated:\s*)((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s((([0-1][0-9])|(2?[0-3]))\:([0-5]?[0-9])((\s)|(\:([0-5]?[0-9])))))/g;

let toppath="./";//当前文件夹的名字
function fn(path){
	fs.readdir(path,(err,files)=>{
		files.forEach(function(item){
			fs.stat(path+item+'/',(err,data)=>{
				if(data.isFile()){
					if(item.indexOf(".md")>-1){
						writeFileTime(path+item,fs);
					}
				}else{
					fn(path+item+'/')
				}
			})
		})
	})
}
fn(toppath)

/*
file:读取时间的文件以及写入内容的文件
fs: 文件系统
*/
function writeFileTime(file,fs){
	fs.readFile(file, 'utf8',function(err, data) { //读取文件内容
		if (err) return console.log("读取文件内容错误:",err);
		//console.log("文件"+file+"的内容:",data);
		fs.stat(file,function(err, stats) { //读取文件信息,创建时间等
		   if (err) return console.log("读取文件信息错误:",err);
			//console.log("文件"+file+"的信息:",stats);  //打印文件的信息
			//console.log("创建时间是:",stats.mtime);
			//console.log("文件的创建时间是:",getFormatDate(stats.mtime));
            var result= data.replace(RegExp,""); //替换更新时间
			result = result.replace(/categories:/g, "updated: "+getFormatDate(stats.mtime)+"\r"+"categories:");//data:替换为标准化日期
			//console.log("修改后文件内容为:",result);
			fs.writeFile(file, result, 'utf8',function(err) { //写入新的文件内容
				if (err) return console.log("写文件错误:",err);
			});
		});
	});
}

/*
 timeStr:时间,格式可为:"September 16,2016 14:15:05、
 "September 16,2016"、"2016/09/16 14:15:05"、"2016/09/16"、
 '2014-04-23T18:55:49'和毫秒
 dateSeparator:年、月、日之间的分隔符,默认为"-",
 timeSeparator:时、分、秒之间的分隔符,默认为":"
 */
function getFormatDate(timeStr, dateSeparator, timeSeparator) {
    dateSeparator = dateSeparator ? dateSeparator : "-";
    timeSeparator = timeSeparator ? timeSeparator : ":";
    var date = new Date(timeStr),
            year = date.getFullYear(),// 获取完整的年份(4位,1970)
            month = date.getMonth(),// 获取月份(0-11,0代表1月,用的时候记得加上1)
            day = date.getDate(),// 获取日(1-31)
            hour = date.getHours(),// 获取小时数(0-23)
            minute = date.getMinutes(),// 获取分钟数(0-59)
            seconds = date.getSeconds(),// 获取秒数(0-59)
            Y = year + dateSeparator,
            M = ((month + 1) > 9 ? (month + 1) : ('0' + (month + 1))) + dateSeparator,
            D = (day > 9 ? day : ('0' + day)) + ' ',
            h = (hour > 9 ? hour : ('0' + hour)) + timeSeparator,
            m = (minute > 9 ? minute : ('0' + minute)) + timeSeparator,
            s = (seconds > 9 ? seconds : ('0' + seconds)),
            formatDate = Y + M + D + h + m + s;
    return formatDate;
}

博客根目录/source/_posts/打开bash,运行代码:


./writeupdatetime.js

代码的运行原理是寻找categories,在categories字段上方添加updated字段,因此要确保你为每篇文章添加了categories。如果没有添加,请自行修改源码,将categories改成其它字段,比如tags等。

打开你的文章看一下,确保每篇文章都添加了updated

2.修改Front-matter模版

打开博客根目录/scaffolds/post.md文件,修改添加updated字段,以我的模板为例:

title: {{ title }}
date: {{ date }}
updated: {{ date }}
mathjax: false
mermaid: false
summary: 啥都没写,别看了

以后再通过hexo new post新建文章的时候就会有updated字段了。

3.代码实现自动更新文章修改时间

代码参考:自动更新文章的修改时间,做了一些改动,使其能搜索所有文件(包括子目录)。

创建 js 文件:博客根目录/source/updateFileTime.js,文件内容如下

#!/usr/bin/env node

/*

批量更新修改时间

博客自动更新文章的修改时间

*/

console.log('脚本开始运行..');

var fs = require("fs"); //请求文件系统

var file = "./txt"; //设置读取和写入的文件,当前目录下的test文件
var RegExp=/(updated:\s*)((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\s((([0-1][0-9])|(2?[0-3]))\:([0-5]?[0-9])((\s)|(\:([0-5]?[0-9])))))/g;

let toppath="./_posts/";//当前文件夹的名字
function fn(path){
	fs.readdir(path,(err,files)=>{
		files.forEach(function(item){
			fs.stat(path+item+'/',(err,data)=>{
				if(data.isFile()){
					if(item.indexOf(".md")>-1){
						writeFileTime(path+item,fs);
					}
				}else{
					fn(path+item+'/')
				}
			})
		})
	})
}
fn(toppath)

/*

file:读取时间的文件以及写入内容的文件

fs: 文件系统

*/

function writeFileTime(file,fs){

	fs.readFile(file, 'utf8',function(err, data) { //读取文件内容

		if (err) return console.log("读取文件内容错误:",err);

		//console.log("文件"+file+"的内容:",data);

		if(RegExp.test(data)){ //如果匹配到`updated`字段

			fs.stat(file,function(err, stats) { //读取文件信息,创建时间等

				if (err) return console.log("读取文件信息错误:",err);

				var updateds=data.match(RegExp);

				//console.log("updated数组:",updateds);

				if(updateds.length>1) console.log("文件"+file+"匹配到多处update字段");

				var updated=updateds[0].replace("updated: ","").replace(/-/g,"/");  //时间格式化为2018/01/29 21:33:30

				//console.log("updated:",updated);

				if(new Date(stats.mtime).getTime()-new Date(Date.parse(updated))>1000*60*5){ // 只要修改时间和文章内updated时间差大于1000毫秒*60*5=5分钟就触发更新

					var result= data.replace(RegExp,"updated: "+getFormatDate(stats.mtime)); //替换更新时间

					fs.writeFile(file, result, 'utf8',function(err) { //写入新的文件内容

						if (err) return console.log("写文件错误:",err);

						fs.utimes(file,new Date(stats.atime),new Date(stats.mtime),function(err){  //还原访问时间和修改时间

							if (err) return console.log("修改时间失败:",err);

							console.log(file,"成功更新时间");

						});

					});

				}

			});

		}

	});

}


/*

 timeStr:时间,格式可为:"September 16,2016 14:15:05、

 "September 16,2016"、"2016/09/16 14:15:05"、"2016/09/16"、

 '2014-04-23T18:55:49'和毫秒

 dateSeparator:年、月、日之间的分隔符,默认为"-",

 timeSeparator:时、分、秒之间的分隔符,默认为":"

 */

function getFormatDate(timeStr, dateSeparator, timeSeparator) {

	dateSeparator = dateSeparator ? dateSeparator : "-";

	timeSeparator = timeSeparator ? timeSeparator : ":";

	var date = new Date(timeStr),

		year = date.getFullYear(),// 获取完整的年份(4位,1970)

		month = date.getMonth(),// 获取月份(0-11,0代表1月,用的时候记得加上1)

		day = date.getDate(),// 获取日(1-31)

		hour = date.getHours(),// 获取小时数(0-23)

		minute = date.getMinutes(),// 获取分钟数(0-59)

		seconds = date.getSeconds(),// 获取秒数(0-59)

		Y = year + dateSeparator,

		M = ((month + 1) > 9 ? (month + 1) : ('0' + (month + 1))) + dateSeparator,

		D = (day > 9 ? day : ('0' + day)) + ' ',

		h = (hour > 9 ? hour : ('0' + hour)) + timeSeparator,

		m = (minute > 9 ? minute : ('0' + minute)) + timeSeparator,

		s = (seconds > 9 ? seconds : ('0' + seconds)),

		formatDate = Y + M + D + h + m + s;

	return formatDate;

}

4.执行

在 git bash 中执行 updateFileTime.js 即可

补充

  1. 出现乱码就是你复制的问题,确保代码是 utf8 的字符格式
  2. 可以写个 sh 脚本帮忙上传

如果本文帮助到了你,帮我点个广告可以咩(o′┏▽┓`o)


评论
  目录