Hexo+Next自定义友链界面

写在前面:


周末准备跟同学(dalao)交换友链,发现next主题的友链是在侧边的标签栏直接加超链接,觉得会使标签栏冗杂,于是上网找其他方法,由于太菜,不懂前端,折腾了很久

前期准备

hexo版本:5.4.0

next版本:8.4.0

操作涉及的文件结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
├── _config.yml  //hexo的配置文件
└── source
    ├── _data
    │   └── body-end.njk
    ├── css
    │   └── links.css
    ├── js
    │   └── link.js
    └── links
        ├── index.md
        └── linklist.json

操作过程

创建页面

在hexo根目录下运行命令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
---
title: 友情链接
type: links
toc:
  enable: false
---



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

<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 %}

## 友链格式

- 名称:McLaren888
- 网址:[https://mclaren888.cn](https://mclaren888.cn)
- 头像:[https://mclaren888.cn/images/cool.jpg](https://mclaren888.cn/images/cool.jpg)

{%endnote%}

注意要在front-matter里标明type,

<link rel="stylesheet" href="/css/links.css"> 是引入css文件;

<div><div class="links-content"><div class="link-navigation" id="links1"></div></div></div>是显示友链内容

创建json数据文件

友链的数据存储在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是头像

注意每一块数据之间用,隔开

渲染页面

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

1
2
3
{% if page.type === 'links' %}
  <script src="/js/link.js"></script>
{% endif %

如果没有body-end.njk文件或_data文件,创建一个就好

修改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
// 获取 json 文件
fetch('/links/linklist.json')
    .then(response => response.json())
    .then(res => renderlink(res));
// 随机排列
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].nickname;
        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>';
    }
    if (document.querySelector(".link-navigation") !== null) {
        document.querySelector(".link-navigation").innerHTML = li;
    }
}

创建CSS样式

创建source/css/links.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
}

修改配置文件

主题的配置文件中(即next的_config.yml),找到custom_file_path

选中body-end.njk文件如下:

接着找到menu,添加侧栏

接着找到mediumzoom

注意fancyboxmediumzoom不能同时选中

找到并修改mediumzoom的CDN

1
2
# Medium-zoom
  mediumzoom: //cdn.jsdelivr.net/npm/medium-zoom@1.0.6/dist/medium-zoom.min.js

hexo clean;hexo g -d重新部署即可

参考链接

版本较新的可以参考这一篇 (使用mediumzoon)

版本较旧的可以参考这一篇 (使用fancybox)