遇到了一个坑,把主页的顺序搞乱了

问题描述

我突然想把我 Blog 的主页上的排序换一下, 因为一直以来都是按 create_at 排序的, 所以我想换成 update_at, 然后我搜索了一下, 发现有一个配置可以满足这个需求.

就是这个:

1
2
3
4
5
6
7
8
# Home page setting
# path: Root path for your blogs index page. (default = '')
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
path: ""
per_page: 5
order_by: -updated # 这个地方

然后我修改了这个配置, 本地跑一下 hexo s 嗯. 完美!
然后推送到 CloudFlare 自动部署.

嗯…部署出来, 我的主页顺序是乱的. 并且每次部署的结果都不一致.

什么原因

查来查去没有发现有人有这个问题. 就很奇怪.
后面也改了部署的配置版本, 也不行.
我还修改了 hexo-generator-index 的源码, 也不行.

只能问 AI 了, 我问了 grok. grok说可能本地使用的是文件的mtime.

原来原因在这!

如何解决

我查到在 hexo里, front matter里面有一个update可以添加, 所以我写了一个脚本:

update-timestamp.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
const fs = require("fs");
const path = require("path");

const postsDir = "./source/_posts";

function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

fs.readdirSync(postsDir).forEach((file) => {
if (file.endsWith(".md")) {
const filePath = path.join(postsDir, file);
const stats = fs.statSync(filePath);
const mtime = stats.mtime;
const formattedMtime = formatDate(mtime);
let content = fs.readFileSync(filePath, "utf-8");
if (content.match(/updated:/)) {
content = content.replace(/updated:.*\n/, `updated: ${formattedMtime}\n`);
} else {
content = content.replace(/---\n/, `---\nupdated: ${formattedMtime}\n`);
}
fs.writeFileSync(filePath, content, "utf-8");
console.log(`Updated ${file} with timestamp ${formattedMtime}`);
}
});

然后运行

1
node update-timestamp.js

嗯. 完美!

然后我修改了一下 time format. 又运行了一次.
炸了.

这次是彻底的炸了.

因为第一次运行的时候, 我的文件的 mtime 更新了, 导致运行两次, 直接所有的文件写入的 update 都是同一个时间了.

而且后续如果我切换了一台新的电脑, 这个方法会按照 git clone的时间把我的 update 给更新了.

所以, 这个脚本是一次性的, 我只能后续去维护每个单独的文件了.