Hexo NexT 主题 8.x 版本的使用配置与美化
0. 前述
将近两年时间了,Hexo NexT 主题升级到了 8.13。本来早就应该进行例行更新了,但因为学业的原因,一直拖到了现在。NexT 主题再 7.x 版本进行了非常多的更新,但历史总是惊人地相似。原团队再次放弃了 NexT 仓库的维护,为此,NexT 主题再次进行了分支。
相比于 NexT 7.x 版本,NexT 8.2+ 再次进行了大量的更新,并且不再支持之前的版本。Hexo 与 NexT 兼容性以及 NexT 各版本间的差异可以查阅官方说明
相比于当初对 NexT 7.7 主题的少量修改,NexT 8.x 内置了更多的样式与功能,同时提供了非侵入式的修改方法。接着科研的间隙,我再次将 Hexo 和 NexT 主题的版本进行了升级,并将用到的功能和改动介绍如下,做一个备忘。由于 Next 8.x 的功能已经非常完善,建议先阅读官方文档。然后,我所应用到的功能都会尽量提供非侵入式的修改,以保证代码的纯洁。
1. 安装与使用
安装好 Hexo 后,将 NexT 主题文件克隆或者拷贝到 hexo/theme
目录下即可。NexT 8.x 中做了很多修改,与之前版本相差较大,请进行全新安装。
1 | cd hexo |
2. 配置功能
1. 可以直接使用的特性
Next 8.x 中实现了大量特性或将大量功能通过插件实现,具体的用法与特点官方文档写的很详细,请自行对照查看。下面,我列举几条本站的主要修改。
2. 相关文章
NexT 依赖的 hexo-related-posts插件暂时不支持 Hexo 6, 要等待官方修复。
另外,另一款类似的插件 hexo-related-popular-posts倒是没限制 Hexo 版本,但在 NexT 不生效。
3 . 不蒜子统计提示语
在主题的_config.yml
中,已经内置了单词统计
4. 媒体播放器
Hexo 是静态博客,不支持媒体文件的播放。之前一直是使用[网易云音乐][l4]和[哔哩哔哩][l5]提供的ifream作为媒体播放器,但网易云音乐支持的歌越来越少了。而且用ifream引用也会遇到因为加载速度不一致报错的问题。因此在去年的新年贺词中,就首先使用了Aplayer播放器,不过`mmedia`插件也不错,综合了Aplayer和Dplayer(一款插入B站视频的脚本),后期会进行迁移。
安装方法:
1
2
3
4
5
6
7
8
// 安装aplayer,https://github.com/MoePlayer/APlayer
npm install --save hexo-tag-aplayer
// 安装mmedia, https://github.com/MonoLogueChi/hexo-tag-mmedia
// 如果安装了aplayer或者dplayer,需要先卸载
npm uninstall hexo-tag-dplayer
npm uninstall hexo-tag-aplayer
// 安装
npm install hexo-tag-mmedia --save
# 3. 我做的修改
1. 文章结束处添加感谢阅读的提示
在
$NexT-ROOT/_config.yml
中取消postBodyEnd
的注释1
2custom_file_path:
postBodyEnd: source/_data/post-body-end.njk在
$Site-ROOT/source/_data/
下新建post-body-end.njk
,写入如下内容,保存。1
2
3<div>
<div style="text-align:center;color: #ccc;font-size:14px;">-----文章到此结束 <i class="fa fa-paw"></i> 感谢您的阅读------</div>
</div>结束,重新编译并刷新网页查看效果
2. 引入自定义的 JS 脚本
NexT 8.x 提供了非侵入式的修改方法,并且推荐使用这种方法对主题进行修改。在本文中,我们尽量地使用这种方法进行修改。在 3.1 中已经进行了尝试。本节将介绍如何引入自定义的 JS 脚本。在之后的教程中所有用到的 JS 脚本都会被引入并独立存放在网站目录。
在
$NexT-ROOT/next/_config.yml
中取消head.njk
的注释1
2custom_file_path:
head: source/_data/head.njk在
$Site-ROOT/source/_data/
下新建head.njk
,写入如下内容,保存。1
<script type="text/javascript" src="example.js"></script>
这里写入的
<script>
标签其实就是正常的引入 JS 脚本的标签,example.js
是需要引入的自定义 JS 脚本文件的路径。在后续的修改中,遇到需要应用 JS 的脚本,只要在head.njk
文件中添加一行<script>
标签进行引入即可。3. 可选:关于引用本站 JS 脚本发生注入导致失效
当 <script>
标签中 JS 脚本的路径缺省为当前站点时,如 assets\js\example.js
时,可能被其他插件引用的 JS 文件注入,既在 example.js
中的第一行插入一句 <script>
标签。这是非法的,会导致 JS 出错并阻挡网站后续所有的 JS 脚本执行,造成网站的崩溃。目前发现 Aplayer
插件会发生这样的问题。
在进行诸多尝试后,本站决定绕过这一问题。将 JS 脚本托管在其他域名下,如 github.io
,或者去 freenom申请同名的 tk
域名等,然后将 JS 脚本放在其他域名下。当跨域时,插件注入就不会发生,从而避免冲突。
3. 页面底部的部分部分内容调整。
在页脚可以展示阅读时间、访问人数、网站版权等信息,但是和第一行的备案内容相比,显得头重脚轻。
因此通过修改底部的布局来调整。打开 $SNexT-Path\layout\_partials\footer.njk
,将
1 | <div class="wordcount">...</div> |
代码段调整到
1 | <div class="copyright">...</div> |
之前,然后,把
1 | <div class="busuanzi-count">.{.}.</div> |
中间的内容添加到 wordcount 中,不包括最外层的 <div>
。最后,就是效果啦。
2. 文章中添加对应的多语言版本的链接
这个功能其实之前几个版本都有实现过。如今,NexT 官方提供了动态的切换按钮,不过位置比较尴尬,在页面的底部,不好看。
我其实想用一种非侵入的方法将其调整一下,不过后来发现臣妾做不到啊。这个比较复杂,我之前在 8.11.1 上测试的,后来升级到 8.12.3 都忘记了改了哪里。所以记录的比较详细,大家按照步骤来即可。
NexT 官方提供的仅是切换到对应语言的主页,不支持切换到对应的文章页面。为了实现能够切换到对应语言的文章页。我这里按照以前的思路进行了修改,这个功能仍然需要手动设置相对应文章的 abbrlink
一致。建议在本地先编译一个语言版本的文件,然后手动修改另一个版本的文章的链接。
下面开始操作。
打开
$Site-ROOT/_config.yml
,添加1
2
3language:
- zh-CN
- en打开
$NexT-ROOT/_config.yml
中找到language_switcher:
标签,打开,并添加两个新字段。1
2
3language_switcher: true
in_footer: false
link_format: true # Whether to modify the language link format找到
$NexT-ROOT\layout\_layout.njk
,找到{%- include '_partials/languages.njk' -%}
,修改为:1
2
3{%- if theme.in_footer %}
{%- include '_partials/languages.njk' -%}
{%- endif %}4 . 打开
$NexT-ROOT\layout/_partials/languages.njk
,找到1
2
3
4
5{% for language in languages %}
<option value="{{ language }}" data-href="{{ i18n_path(language) }}" selected="">
{{ language_name(language) }}
</option>
{% endfor %},修改为:
1
2
3
4
5
6
7
8
9
10
11{% for language in languages %}
{%- if theme.in_footer.link_format %}
<option value="{{ language }}" data-href="{{ i18n_path(language) }}" selected="">
{{ language_name(language) }}
{% else %}
<span id="language" style="display:none">{{ language }}</span>
<option value="{{ language }}" data-href="{{ i18n_path(language) }}" selected="">
{{ language_name(language) }}
{%- endif %}
</option>
{% endfor %}打开
$Next-ROOT\layout\_macro/sidebar.njk
,找到site-overview-wrap
部分,1
2
3
4<div class="site-overview-wrap sidebar-panel">
{{ partial('_partials/sidebar/site-overview.njk', {}, {cache: theme.cache.enable}) }}
{{- next_inject('sidebar') }}
</div>,修改为:
1
2
3
4
5
6
7
8
9
10
11
12<div class="site-overview-wrap sidebar-panel">
{{ partial('_partials/sidebar/site-overview.njk', {}, {cache: theme.cache.enable}) }}
{{- next_inject('sidebar') }}
<!--language_switcher-->
{%- if theme.in_footer %}
{% else %}
<div class="site-overview-item">
{%- include '_partials/languages.njk' -%}
</div>
{%- endif %}
<!--/language_switcher-->
</div>至此,所有的模块都已经整理完成了,接下来还要对语言选择器中的链接进行劫持。新建
$Site-ROOT/assets\js\language.js
,写入如下内容。
1 | window.onload=function(){ |
- 结束,重新编译运行,查看效果。
2. 修改颜色样式,并添加时效背景
本站支持根据节气自动更换相关的主题壁纸,与一般的动态背景不同,带来新鲜感的同时也减轻了网站的负担。
自定义背景与样式
打开
$Next-ROOT/_config.yml
,找到custom_file_path
,打开style
处的注释在
$Site-ROOT/source/_data/
下新建styles.styl
,写入如下内容,保存。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//添加背景图片
body {
background-image:url(/images/backGround.jpg);
background-repeat: no-repeat;
background-attachment:fixed;
background-position:50% 50%;
// background-size: 100% 100%;
background-size: cover;
-webkit-background-size: cover;
-o-background-size: cover;
-moz-background-size: cover;
-ms-background-size: cover;
}
//改掉题头颜色
.site-meta {
background: #F0D784; //修改为自己喜欢的颜色
}
//主标题颜色
.brand{
color: #2f9833
}
//副标题颜色
.site-subtitle{
color: #47b54a
}
//页脚添加透明灰色背景
.beian, .copyright, .wordcount{
background: #999999b8
color: #fff
}
// 修改页脚的超连接颜色与
.beian a{
text-decoration:none;
}
.beian a:link,
.beian a:active,
.beian a:visited{
color:#fff;
}
.beian a:hover{
color:#5bdf27;
}结束,重新编译运行,查看效果。
根据时间更换背景
本站根据农历节气更换背景。思路是首先设定自定义的背景,然后使用 JS 劫持
background-image
的链接,换成需要的背景。本文中以 24 节气为例。同样的思路也可以实现 24 小时轮换壁纸或 12 时辰轮换壁纸,可参考旗下网站时光。因为需要节气日期,使用一个工具 JS 来根据当天日期获取农历日期与所在节气。在
$Site-ROOT/source/_data/head.njk
写入如下内容,保存。1
<script type="text/javascript" src="//time.luov.top/assets/js/calendar.min.js"></script>
新建
$Site-ROOT/assets\js\jieqi_background.js
,写入如下内容。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var jieqiImgArr = [
, "../images/0.jpg" //1 小寒
...//省略
, "../images/23.jpg" //24 冬至
];
// 设立一个数组存储图片的路径,从小寒开始。
window.onload=function(){
var now=new Date();
var lunar = calendar.solar2lunar(now.todayYear, now.todayMonth, now.todayDate);// 根据今天的日期获取农历对象
var dayth=getDateNum();
img=jieqiImgArr[lunar.TermInx ]
var mybody = document.body
mybody.style.backgroundImage="url("+img+")"
}
其他小修改
1. 解决左边工具栏上无法跳转到外部链接的问题
由于 NexT6 做了设置,左边工具栏上的所有链接将会自动在前面添加上当前域名。对于,“首页”,“关于” 这样的链接没有问题。但如果要添加上外链,例如英文页面:https:\\en.xian6ge.cn
,会被自动编译为 https:\\xian6ge.cn\https\en.xian6ge.cn
,造成跳转出错。为此,我们可以采用一个折中的办法。
在 hexo\source
下建立一个 en.html
文件,在里面通过 JavaScript 代码跳转。但这样会遇到一个问题,Hexo 会编译所有文件,造成其中的 Js 代码失效。因此,在前面添加 layout: false
设置,告诉编译器不要编译该 HTML 文件。具体代码如下。
1 | layout: false |
2. 增加网站运行时间统计
这次没有在页脚处增加统计,避免过多的 js 代码拖累网站速度,将这段统计的代码放到关于中。但这个页面是由 Markdown 文件编译的,无法执行 js 代码。又不想单独重写这一页面,于是使用 ifream 的技术方法。
- 在
about/
文件夹下新建timer.html
,写入如下内容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
77layout: false
title: "网站运行计时器"
comments: false
permalink:
---
<html lang="en">
<style type="text/css">
*{margin:0;padding:0}
.post-body{overflow-wrap:break-word;line-height:2;text-align:justify;font-size:1.125em}
@media(min-width:992px){
.post-body{text-align:justify}}
@media(min-width:1200px){
.post-body{font-size:1.125em}}
div{display:block}
.note{margin-bottom:20px;position:relative;border-radius:3px;padding:15px;border-width:1px;border-style:solid;border-image:initial}
.success{color:#3c763d;background:#dff0d8;border-color:#d0e6be}
.primary{background:#f3daff;border-color:#e1c2ff;color:#6f42c1}
p{letter-spacing:normal;margin:0 0 20px}
p:last-child{margin-bottom:0}
p:first-child{margin-top:0}
</style>
<script language=javascript>
function siteTime(){
window.setTimeout("siteTime()", 1000);
var seconds = 1000;
var minutes = seconds * 60;
var hours = minutes * 60;
var days = hours * 24;
var years = days * 365;
var today = new Date();
var todayYear = today.getFullYear();
var todayMonth = today.getMonth()+1;
var todayDate = today.getDate();
var todayHour = today.getHours();
var todayMinute = today.getMinutes();
var todaySecond = today.getSeconds();
/* Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
year - 作为date对象的年份,为4位年份值
month - 0-11之间的整数,做为date对象的月份
day - 1-31之间的整数,做为date对象的天数
hours - 0(午夜24点)-23之间的整数,做为date对象的小时数
minutes - 0-59之间的整数,做为date对象的分钟数
seconds - 0-59之间的整数,做为date对象的秒数
microseconds - 0-999之间的整数,做为date对象的毫秒数 */
var year = 2018//document.getElementById("year").innerHTML;
var month = 02//document.getElementById("month").innerHTML;
var day = 13//document.getElementById("day").innerHTML;
var hour = 00//document.getElementById("hour").innerHTML;
var minute = 00//document.getElementById("minute").innerHTML;
var second = 00//document.getElementById("second").innerHTML;//北京时间2018-2-13 00:00:00
var t1 = Date.UTC(year,month,day,hour,minute,second);
var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
var diff = t2-t1;
var diffYears = Math.floor(diff/years);
var diffDays = Math.floor((diff/days)-diffYears*365);
var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
if(diffYears==0){
document.getElementById("sitetime").innerHTML=/*+diffYears+" year "*/+diffDays+" 日 "+diffHours+" 小时 "+diffMinutes+" 分 "+diffSeconds+" 秒";
} else{
document.getElementById("sitetime").innerHTML=diffYears+" 年 "+diffDays+" 日 "+diffHours+" 小时 "+diffMinutes+" 分 "+diffSeconds+" 秒";
}
}
//siteTime(document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,0);
siteTime();
</script>
</head>
<body class="post-body">
<div class="note primary">
<p>『贤柳阁』已经运行了 <span id="sitetime">已经运行了一年多了</span></p>
</div>
</body>
</html> - 打开
about\index.md
,在需要展示的地方增加其中,1
2
3<span style="width:100%; height:260;border:none;text-align:center">
<iframe allowtransparency="yes" frameborder="0" width="100%" height="88" src="/about/timer.html"/>
</span>iframe
的src
标签中指向的是需要展示的 Html 文件,注意文件中要添加layout: false
,避免文件被编译。
至此,所有的修改完成,效果可以查看本站。未尽与错漏之处还请包含,欢迎在邮件或 Github与我联系。