Hexo NexT 自動更新文章修改時間

主要是因為換電腦,想要同步在不同的作業系統時,所發現的更新時間問題!

前言

這次是在新電腦新增文章,並且使用部署完 Github Action 後,發現所有的文章的更新時間都會改變。
但是文章更新日期是對於讀者非常重要的資訊,因此開啟了我的解謎之路。

Hexo 版本

  • hexo:6.3.0
  • hexo-server:3.0.0

NexT 版本

  • NexT:^8.12.1

修改 Front-matter 範本

1
2
3
4
5
6
7
8
9
10
---
title: {{ title }}
date: {{ date }}
updated: {{ date }} # 新增這一行
categories:
- category
tags:
- tag1
- tag2
---

這樣未來的文章都會有更新時間!

更新已經發佈的文章加入 updated

  1. ./source/ 新增 modify.sh
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/bash

    dir="_posts"
    for file in `ls ${dir} | grep '.md'`;do
    content=$(cat ${dir}/${file}| head -n 10 | grep 'date: ')
    datestr=$(echo "$content" | awk '{print $2" "$3}')
    newcontent="updated: "$datestr
    sed -i "/$content/a\\$newcontent" ${dir}/${file}
    done
  2. 執行指令 cd ./source && sh modify.sh && cd - (Windows bask)
  3. 即可看到目前的 post.md 都新增上 updated 字樣

肉身實測,如果你已經做過一次更新舊文章,接下來就不用碰到這個指令!因為會重新新增 updated 字樣。

之後自動更新時間

  1. ./source/_posts 新增 updateFileTime.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    #!/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;

    fs.readdir("./", function (err, files) {
    var len = files.length;
    var file = null;
    for (var i = 0; i < len; i++) {
    file = files[i];
    //console.log("读取文件:",file);
    if (file.indexOf(".md") > -1) {
    console.log("正在處理文件:", file);
    writeFileTime(file, fs);
    }
    }
    });

    /*
    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;
    }

    因為我找到的解法是簡中的,若有介意的話可以手動改成繁體或是其他語系。

  2. 修改 .gitignore 新增 source/_posts/*.js

  3. 執行指令 cd source/_posts/ && ./updateFileTime.js && cd -

  4. 清除 chache git rm --cached source/_posts/ -r 再 run 一次 3

參考資料:hexo自动更新文章修改时间Hexo Next主题显示文章更新时间