hexo automatically updates the article modification time

1, Problem description

After Github Action is deployed to automatically deploy blogs, there is a problem. During each update, due to the deployment of cloud functions, the update time of all articles will change. At present, this can only be avoided by adding the updated field to the articles and submitting them.

But every time you update an article, you have to modify the updated manually. Of course, such a troublesome thing should be left to the program to do. I thought about using python, but considering that some people may not have a python environment, and those who use hexo to deploy blogs must have a node environment, so js is used to complete it.

2, Solution

First, if you haven't added the updated field for the article before, you need to add it first.

1 add the updated field to the existing article

If your existing article already has an updated field, this step can be skipped.

Code reference: Modification time of batch write file , when the original code runs many times, fields are added repeatedly. I have optimized it. Repeated runs will only add an updated field.

Create js file: blog root directory / source/_posts/writeupdatetime.js, the contents of the file are as follows

#!/usr/bin/env node
/*
Batch add modify time
 Modification time for bolg initialization
*/

console.log('The script starts running..');
var fs = require("fs"); //Request file system
var file = "./txt"; //Set the read and write files, and the test file in the current directory
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])))))\r/g;

fs.readdir("./",function(err,files){
	var len=files.length;
	var file=null;
	for(var i=0;i<len;i++){
		file=files[i];
		//console.log("read file:", file);
		if(file.indexOf(".md")>-1){
			console.log("Processing file:",file);
			writeFileTime(file,fs);
		}
	}
    console.log("Run over!");
});
/*
file:File for reading time and file for writing content
fs: file system
*/
function writeFileTime(file,fs){
	fs.readFile(file, 'utf8',function(err, data) { //Read file contents
		if (err) return console.log("Error reading file contents:",err);
		//console.log("content of file" + file + ":, data);
		fs.stat(file,function(err, stats) { //Read file information, creation time, etc
		   if (err) return console.log("Error reading file information:",err);
			//console.log("information of file" + file + ":, stats)// Print file information
			//console.log("creation time is:", stats.mtime);
			//console.log("file creation time is:", getFormatDate(stats.mtime));
            var result= data.replace(RegExp,""); //Replace update time
			result = result.replace(/categories:/g, "updated: "+getFormatDate(stats.mtime)+"\r"+"categories:");//data: replace with standardized date
			//console.log("modified file content is:", result);
			fs.writeFile(file, result, 'utf8',function(err) { //Write new file contents
				if (err) return console.log("Write file error:",err);
			});
		});
	});
}

/*
 timeStr:The format of time can be: "September 162016 14:15:05
 "September 16,2016","2016/09/16 14:15:05","2016/09/16",
 '2014-04-23T18:55:49'And milliseconds
 dateSeparator: The separator between year, month and day is "-" by default,
 timeSeparator: The separator between hour, minute and second. The default is ":
 */
function getFormatDate(timeStr, dateSeparator, timeSeparator) {
    dateSeparator = dateSeparator ? dateSeparator : "-";
    timeSeparator = timeSeparator ? timeSeparator : ":";
    var date = new Date(timeStr),
            year = date.getFullYear(),// Get the full year (4 digits, 1970)
            month = date.getMonth(),// Get the month (0-11, 0 represents January, remember to add 1 when using)
            day = date.getDate(),// Acquisition date (1-31)
            hour = date.getHours(),// Get hours (0-23)
            minute = date.getMinutes(),// Get minutes (0-59)
            seconds = date.getSeconds(),// Get seconds (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;
}

In the blog root directory / source/_posts / open bash and run the code:

./writeupdatetime.js

The code works by looking for categories and adding the updated field above the categories field, so make sure you add categories for each article. If not, please modify the source code and change the categories to other fields, such as tags.

Open your article and make sure that updated is added to each article.

2. Modify the front matter template

Since I have not set the front matter template before, there is no updated field in each article, so I need to modify the template.

Open the blog root directory / Scaffolding / post MD file, modify and add the updated field. Take my template as an example:

title: {{ title }}
date: {{ date }}
updated: {{ date }}
tags:
  -
categories:
  -
sticky: 

When creating a new article through hexo new post in the future, there will be an updated field.

3 code to automatically update the article modification time

Code reference: Automatically update the modification time of the article , some changes have been made.

Create js file: blog root directory / source/_posts/updateFileTime.js, the contents of the file are as follows

#!/usr/bin/env node
/*
Batch update modification time
 The blog automatically updates the modification time of the article
*/

console.log('The script starts running..');
var fs = require("fs"); //Request file system
var file = "./txt"; //Set the read and write files, and the test file in the current directory
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;

fs.readdir("./",function(err,files){
	var len=files.length;
	var file=null;
	for(var i=0;i<len;i++){
		file=files[i];
		//console.log("read file:", file);
		if(file.indexOf(".md")>-1){
			console.log("Processing file:",file);
			writeFileTime(file,fs);
		}
	}
});

/*
file:File for reading time and file for writing content
fs: file system
*/
function writeFileTime(file,fs){
	fs.readFile(file, 'utf8',function(err, data) { //Read file contents
		if (err) return console.log("Error reading file contents:",err);
		//console.log("content of file" + file + ":, data);
		if(RegExp.test(data)){ //If it matches the 'updated' field
			fs.stat(file,function(err, stats) { //Read file information, creation time, etc
				if (err) return console.log("Error reading file information:",err);
				var updateds=data.match(RegExp);
				//console.log("updated array:", updates);
				if(updateds.length>1) console.log("file"+file+"Match to multiple places update field");
				var updated=updateds[0].replace("updated: ","").replace(/-/g,"/");  //The time is formatted as 21:33:30, January 29, 2018
				//console.log("updated:",updated);
				if(new Date(stats.mtime).getTime()-new Date(Date.parse(updated))>1000*60*5){ // As long as the difference between the modification time and the updated time in the article is greater than 1000 milliseconds * 60 * 5 = 5 minutes, the update will be triggered
					var result= data.replace(RegExp,"updated: "+getFormatDate(stats.mtime)); //Replace update time
					fs.writeFile(file, result, 'utf8',function(err) { //Write new file contents
						if (err) return console.log("Write file error:",err);
						fs.utimes(file,new Date(stats.atime),new Date(stats.mtime),function(err){  //Restore access time and modification time
							if (err) return console.log("Failed to modify time:",err);
							console.log(file,"Successful update time");
						});
					});
				}
			});
		}	
	});
}

/*
 timeStr:The format of time can be: "September 162016 14:15:05
 "September 16,2016","2016/09/16 14:15:05","2016/09/16",
 '2014-04-23T18:55:49'And milliseconds
 dateSeparator: The separator between year, month and day is "-" by default,
 timeSeparator: The separator between hour, minute and second. The default is ":
 */
function getFormatDate(timeStr, dateSeparator, timeSeparator) {
    dateSeparator = dateSeparator ? dateSeparator : "-";
    timeSeparator = timeSeparator ? timeSeparator : ":";
    var date = new Date(timeStr),
            year = date.getFullYear(),// Get the full year (4 digits, 1970)
            month = date.getMonth(),// Get the month (0-11, 0 represents January, remember to add 1 when using)
            day = date.getDate(),// Acquisition date (1-31)
            hour = date.getHours(),// Get hours (0-23)
            minute = date.getMinutes(),// Get minutes (0-59)
            seconds = date.getSeconds(),// Get seconds (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 shell auto run code

Create a new update in the blog root directory SH file, as follows:

#!/bin/sh
cd source/_posts/ && ./updateFileTime.js && cd .. && cd .. && git add . && git commit -m "uptate" && git push origin master
# If your branch is not a master, remember to replace it

5 modify gitignore

We need to ignore_ In the js file under posts, open the blog root directory / gitignore file, add a:

source/_posts/*.js

When you're done, you just need to run update sh

./update.sh

You can automatically write the update time into the updated field of the article before submitting the code, and then submit it to the remote source code warehouse for automatic deployment.

Added by agravayne on Wed, 12 Jan 2022 07:35:06 +0200