Hexo+Next自定义友链界面

写在前面:


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

前期准备

hexo版本:5.4.0

next版本:8.4.0

操作涉及的文件结构:

├── _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

文件内容:

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

格式为

[
  {
    "name": "",
    "site": "",
    "avatar": ""
  },
  {
    "name": "",
    "site": "",
    "avatar": ""
  }
]

name是友链名字,site是网址,avatar是头像

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

渲染页面

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

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

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

修改link.js

// 获取 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并修改内容:

.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

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

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

参考链接

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

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