这篇文章讨论如何在 Hexo 中方便地实现文章置顶功能。

最初我采用了Hexo 文章置顶的方法。这个方法还是非常简单有效,不过存在一个问题:即不支持使用负数的top值将文章放在末尾。因此我做了 一点修改。

1 原始方法

原始方法的核心思想是在 Front-Matter 中添加一个自定义的top字段,然后在hexo-generator-index中使用这一字段来实现排序。具体操作为,修改文件node_modules/hexo-generator-index/lib/generator.js,添加 如下代码:

1
2
3
4
5
6
7
8
9
10
11
posts.data = posts.data.sort(function(first, second) {
if (first.top && second.top) { // 两篇文章top都有定义
return first.top == second.top ? second.date - first.date : second.top - first.top //若top值一样则按照文章日期降序排, 否则按照top值降序排
} else if (first.top && !second.top) { // 以下是只有一篇文章top有定义,将有top的排在前面
return -1;
} else if (!first.top && second.top) {
return 1;
} else {
return second.date - first.date; // 都没定义top,按照文章日期降序排
}
});

更改后的完整代码如下:

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
'use strict';
var pagination = require('hexo-pagination');
module.exports = function(locals) {
var config = this.config;
var posts = locals.posts.sort(config.index_generator.order_by);
posts.data = posts.data.sort(function(first, second) {
if (first.top && second.top) { // 两篇文章top都有定义
return first.top == second.top ? second.date - first.date : second.top - first.top //若top值一样则按照文章日期降序排, 否则按照top值降序排
} else if (first.top && !second.top) { // 以下是只有一篇文章top有定义,将有top的排在前面
return -1;
} else if (!first.top && second.top) {
return 1;
} else {
return second.date - first.date; // 都没定义top,按照文章日期降序排
}
});
var paginationDir = config.pagination_dir || 'page';
var path = config.index_generator.path || '';
return pagination(path, posts, {
perPage: config.index_generator.per_page,
layout: ['index', 'archive'],
format: paginationDir + '/%d/',
data: {
__index: true
}
});
};

然后在需要置顶的文章的 front-matter 中添加 top 字段。top 值越大,则文章越靠前。top 值一样的文章则根据日期排序。front-matter 设置的一个例子如下:

1
2
3
4
5
6
7
8
9
10
11
title: Hexo文章置顶方法研究
date: 2019-06-26 22:51:15
tags:
- 教程
- hexo
author: MinHow
tags:
- 博客
- 开源项目
cover_picture: https://cloud.minhow.com/images/miho/theme/github-second.jpg
top: 1

2 解决“置底”的问题

无法置底的原因很简单,即在上面的 js 代码修改中,没有设置 top 值的文章的 top 变量是未定义的,且规定未定义 top 的文章总是比定义了 top 值的文章要靠后。我们赋予未定义 top 值的文章一个默认的 0 值,即可解决这个问题的。具体的操作是将修改代码内容替换成

1
2
3
4
5
6
7
8
9
posts.data = posts.data.sort(function(first, second) {
var a = first.top || 0
var b = second.top || 0
if (a != b) {
return b - a
} else {
return second.date - first.date
}
}