Hexo NexT 添加友链页面

关于如何给 NexT 主题添加友链页面,在网上能够搜到很多,但是基本上都已经过时了。

要么是没有把数据文件和主题分离,还在修改主题中的文件(而且是旧版的文件,新版的主题结构和内容都有变化);要么是给出的代码还依赖 jQuery。

而新版的 NexT 主题除了 Fancybox 外,其它功能都已经不再依赖 jQuery 了。由于 Fancybox 和我的 WebP 检测代码冲突,所以我切换到了 medium-zoom,这样就不再引入 jQuery 了。

因此,网上找到的代码就不能拿过来直接用了。

这里主要需要修改的是 link.js 文件。

1. 涉及到的文件

1
2
3
4
5
6
7
8
9
10
11
12
.
├── _config.next.yml
└── source
├── _data
│ └── body-end.njk
├── css
│ └── link.css
├── js
│ └── link.js
└── links
├── index.md
└── linklist.json

2. 步骤

2.1. 建立页面

运行

1
hexo new page links

这会创建 source/links/index.md 文件。

文件示例:

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
---
title: 友情链接
type: links
toc:
enable: false
---

<link rel="stylesheet" href="/css/link.css">

{% note info %}

排名不分先后,每次刷新会随机排列。

{% endnote %}

<div>
<div class="links-content">
<div class="link-navigation" id="links1"></div>
</div>
</div>

------

<div style="text-align:center;">
<span class="with-love" id="animate1"><i class="fa fa-heart"></i></span>
留言互换友链 o ((>ω<)) o
<span class="with-love" id="animate2"><i class="fa fa-heart"></i></span>
</div>

------

{% note success %}

## 友链格式

- 名称:如鱼饮水,冷暖自知
- 网址:[https://wangjiezhe.com](https://wangjiezhe.com)
- 头像:[https://gravatar.loli.net/avatar/e09cf54e933e5a690716e68961ff3b1c?s=512](https://gravatar.loli.net//avatar/e09cf54e933e5a690716e68961ff3b1c?s=512)

{% endnote %}

注意在 Front-Matter 里一定要有 type: links

这里我还关闭了侧边栏的目录。

2.2. 存储数据

所有友链的数据都放在 source/links/linklist.json 里,其格式为:

1
2
3
4
5
6
7
8
9
10
11
12
[
{
"name": "",
"site": "",
"avatar": ""
},
{
"name": "",
"site": "",
"avatar": ""
}
]

其中 name 为网站的名字,site 为网址,avatar 为头像。

头像可以使用 Gravatar,这样可以保证始终可用的。

2.3. 渲染页面

source/_data/body-end.njk 中,引入 link.js

1
2
3
{% if page.type === 'links' %}
{{- next_js('link.js', true) }}
{% endif %}

其中 source/js/link.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
// 随机排列
function shuffle(arr) {
let i = arr.length;
while (i) {
let j = Math.floor(Math.random() * i--);
[arr[j], arr[i]] = [arr[i], arr[j]];
}
}

// 渲染数据
function renderlink(data) {
var name, avatar, site, li = "";
shuffle(data);
for (var i = 0; i < data.length; i++) {
name = data[i].name;
avatar = data[i].avatar;
site = data[i].site;
li += '<div class="card">' + '<a href="' + site + '" target="_blank">' + '<div class="thumb" style="background: url( ' + avatar + ');">' + '</div>' + '</a>' + '<div class="card-header">' + '<div><a href="' + site + '" target="_blank">' + name + '</a></div>' + '</div>' + '</div>';
}
document.querySelector(".link-navigation").innerHTML = li;
}

// 获取 json 文件
fetch('/links/linklist.json')
.then(response => response.json())
.then(res => renderlink(res));

2.4. 创建样式

创建 source/css/link.css,其内容为(这个文件完全来自于网络):

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
.links-content {
margin-top: 1rem
}

.link-navigation::after {
content: " ";
display: block;
clear: both
}

.card {
width: 130px;
font-size: 1rem;
padding: 0;
border-radius: 4px;
transition-duration: .15s;
margin-bottom: 1rem;
display: block;
float: left;
box-shadow: 0 2px 6px 0 rgba(0,0,0,.12);
background: #f5f5f5
}

.card {
margin-left: 16px
}

@media(max-width:567px) {
.card {
margin-left: 16px;
width: calc((100% - 16px)/2)
}

.card:nth-child(2n+1) {
margin-left: 0
}

.card:not(:nth-child(2n+1)) {
margin-left: 16px
}
}

@media(min-width:567px) {
.card {
margin-left: 16px;
width: calc((100% - 32px)/3)
}

.card:nth-child(3n+1) {
margin-left: 0
}

.card:not(:nth-child(3n+1)) {
margin-left: 16px
}
}

@media(min-width:768px) {
.card {
margin-left: 16px;
width: calc((100% - 48px)/4)
}

.card:nth-child(4n+1) {
margin-left: 0
}

.card:not(:nth-child(4n+1)) {
margin-left: 16px
}
}

@media(min-width:1200px) {
.card {
margin-left: 16px;
width: calc((100% - 64px)/5)
}

.card:nth-child(5n+1) {
margin-left: 0
}

.card:not(:nth-child(5n+1)) {
margin-left: 16px
}
}

.card:hover {
transform: scale(1.1);
box-shadow: 0 2px 6px 0 rgba(0,0,0,.12),0 0 6px 0 rgba(0,0,0,.04)
}

.card .thumb {
width: 100%;
height: 0;
padding-bottom: 100%;
background-size: 100% 100%!important
}

.posts-expand .post-body img {
margin: 0;
padding: 0;
border: 0
}

.card .card-header {
display: block;
text-align: center;
padding: 1rem .25rem;
font-weight: 500;
color: #333;
white-space: normal
}

.card .card-header a {
font-style: normal;
color: #2bbc8a;
font-weight: 700;
text-decoration: none;
border: 0
}

.card .card-header a:hover {
color: #d480aa;
text-decoration: none;
border: 0
}

2.5. 添加侧栏

在主题的配置文件(目前默认为 _config.next.yml)中,添加

1
2
3
4
5
6
menu:
home: / || fa fa-home
tags: /tags/ || fa fa-tags
categories: /categories/ || fa fa-th
archives: /archives/ || fa fa-archive
+ links: /links/ || fa fa-link

大功告成!


参考:

  • Hexo-NexT 新增友链
  • You (Might) Don't Need jQuery