Hexo NexT 主题 6.x 版本的使用配置与美化

0. 前述

Hexo NexT 6.x 推出已经有一段时间了,相比于 5.x 版本的众多功能,6.x 版本有如下提升:

  • 优化配置项
  • 将众多特性合并到主题当中,例如:顶部展示加载进度条,头像滚动,工信部备案信息等。
  • 代码快支持复制功能
  • 支持 Valine 评论系统
  • 部分功能优化,一些功能之前是使用修改源代码方式,现在可以使用 “包 / 插件引入 + 选项配置” 的方式激活该功能。

被开源组织接手的 NexT 更加好看好用,但依然有一些地方不尽如人意,需要小小修改以更好的满足个性化的需要。本文将以我自己的网站为例,分享我对 NexT 的配置和修改的一些心得。

我自己使用的,修改后的 NexT 版本已经开源到 Github,欢迎 star,follow。同时由于水平有限,做的还不是很完美。需要大家的帮助。从 Github来的朋友可以直接查看我做了哪些修改,欢迎提交 issue 和 pull。

1. 安装与使用

安装好 Hexo 后,将 NexT 主题文件克隆或者拷贝到 hexo/theme 目录下即可。如果之前已经存在 5.0 版本的 NexT 文件夹,需要建立一个新文件夹。

1
2
cd hexo
git clone https://github.com/theme-next/hexo-theme-next themes/next6

2. 配置功能

1. 可以直接使用的特性

在 6.0 版本的 NexT 中,许多特性被合并到主分支,比如:

特性配置属性说明
缓存cache允许缓存内容生成。 在 NexT v6.0.0 中引入。
展示 Hexo 与 next 版本copyright.powered,copyright.theme可以选择是否开启,选择是否展示版本
备案beian展示备案信息。这个样式我不太满意,下面会提到修改
版权信息creative_commons可以自己选择权利协议,展示的地方。
SEO 优化seoCanonical,在您的 hexo 中设置规范链接标记,您可以将它用于您的博客搜索引擎优化。
首页标题展示副标题index_with_subtitle打开后,首页标题展示样式如标题 - 副标题
外链加密exturl自动将外链使用 BASE64 encrypt 与 decrypt 加密
代码块提示复制按钮codeblock.copy_button打开后,代码块右上角出现复制按钮
数学公式math数学公式
百度推送baidu_push更好的 SEO

2. 需要安装插件的功能

另外,新版本的 NexT 还对部分功能的使用做了优化。我们除了要在主题的_config.yml 中启用功能,还要在 NexT 目录下安装相应的插件。
我启用的功能有:

功能插件配置项可以进行的配置
字数、阅读时间统计 hexo-symbols-count-timetheme.symbols_count_time 单词长度,阅读速度
图片浏览 theme-next-fancybox3theme.fancybox
顶部进度条 theme-next-pacetheme.pace 进度条的样式
Algolia 搜索 algolia_searchalgolia_search 需要在 hexo\_config.yml 中配置 api_key 等信息
相关文章 hexo-related_postsrelated_posts 展示关键词相同的文章
懒加载 theme-next-lazyloadlazyloadJquery - 懒加载

其他可以配置,但我没有启用的功能

功能插件配置项可以进行的配置
Canvas 背景 theme-next-canvas_nestcanvas_nest 颜色,深度等样式
JavaScript 3D librarytheme-next-threethree_waves

安装插件后,请务必执行 hexo clean 命令,重新编译。

3 我做的修改

1. 备案信息补充与位置调整

每一个中国的合法网站都需要进行 ICP 备案,现在还增加了公安网安备案。虽然 NexT 6.x 已经提供了 ICP 备案方案。但缺少公安备案,同时显示的位置我不是很满意,进行了一些改动。

  1. 打开 themes/next/_config.yml 添加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # Beian icp information for Chinese users. In China, every legal website should have a beian icp in website footer.
    # http://www.miitbeian.gov.cn
    beian:
    enable: true
    icp: 赣ICP备 - 18012283
    # 以下是我增加的内容。
    # 公安网备案 for Chinese users. local mean 京 or 赣
    gongan:
    enable: true
    local: 赣
    num: 36010202000154
  2. 打开 themes\next6\layout\footer.swig,首先前面删除
    1
    <div class="copyright">{#
    1
    #}{% set current = date(Date.now(), "YYYY") %}
    之间的备案代码,然后在文件底部增加如下代码
    1
    2
    3
    4
    5
    6
    7
     {% if theme.footer.beian.enable %}{#
    #} {{ next_url('http://www.miitbeian.gov.cn', theme.footer.beian.icp ) }}
    {% endif %}
    {% if theme.footer.gongan.enable %}{#
    #} {{' | '}}<span style="padding-left:25px;background:url(https://s1.ax1x.com/2018/09/29/ilmwIH.png) no-repeat left center" rel="nofollow"># 这张国徽图片可以自行更换
    {{ next_url('http://www.beian.gov.cn/portal/registerSystemInfo?recordcode='+theme.footer.gongan.num, theme.footer.gongan.local+'公网安备'+theme.footer.gongan.num+'' ) }}</span>{#
    #}{% endif %}
  3. 结束。刷新网页查看效果。

2. 页面底部添加网站运行时间

  1. 打开 themes/next/_config.yml,添加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     # -------------------------------------------------------------
    # web run time
    # 这是网站开始运行的时间,展示网站运行了多长时间。
    # 格式, 2018-02-13 15:00:00. 如果个数只有一位,需要补零。
    runtime:
    enable: true
    year: 2018
    month: 02
    day: 13
    hour: 15
    minute: 00
    second: 00
  2. themes\next6\layout\ 下新建 web-runtime.swig,写入如下内容,保存。
    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
     <div>
    <span id="sitetime"></span>
    // 这里我没有好办法吧swig的值传到JavaScript代码中。如果您会,请帮我改进。
    <span id="year" style="display:none">{{theme.footer.runtime.year}}</span>
    <span id="month" style="display:none">{{theme.footer.runtime.month}}</span>
    <span id="day" style="display:none">{{theme.footer.runtime.day}}</span>
    <span id="hour" style="display:none">{{theme.footer.runtime.hour}}</span>
    <span id="minute" style="display:none">{{theme.footer.runtime.minute}}</span>
    <span id="second" style="display:none">{{theme.footer.runtime.second}}</span>
    <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 = document.getElementById("year").innerHTML;
    var month = document.getElementById("month").innerHTML;
    var day = document.getElementById("day").innerHTML;
    var hour = document.getElementById("hour").innerHTML;
    var minute = document.getElementById("minute").innerHTML;
    var second = 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=" Website has run "/*+diffYears+" year "*/+diffDays+" days "+diffHours+" h "+diffMinutes+" min "+diffSeconds+" s";
    } else{
    document.getElementById("sitetime").innerHTML=" Website has run "+diffYears+" year "+diffDays+" days "+diffHours+" h "+diffMinutes+" min "+diffSeconds+" s";
    }
    }
    //siteTime(document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,document.getElementById("year").innerHTML,0);
    siteTime();
    </script>
    </div>
  3. 打开 themes\next6\_layout\footer.swig,在您想展示的位置,比如备案代码之前,加入如下内容。
    1
    2
    3
    {% if theme.footer.runtime.enable %}
    {% include 'web-runtime.swig' %}
    {% endif %}
  4. 结束,刷新网页查看效果。

3. 文章结束处添加感谢阅读的提示

  1. 打开 themes/next/_config.yml,添加

    1
    2
    3
    4
    5
    6
     # At the end of the article, show thanks for reading
    end_info:
    enable: true
    start_info: -------The end of this article
    icon: paw
    end_info: Thank you for your reading-------
  2. themes\next6\_macro\ 下新建 passage-end-tag.swig,写入如下内容,保存。

    1
    2
    3
    4
    5
    <div>
    {% if not is_index %}
    <div style="text-align:center;color: #ccc;font-size:14px;">{{theme.end_info.start_info}}&nbsp;<i class="fa fa-{{ theme.end_info.icon }}"></i>&nbsp;{{theme.end_info.end_info}}</div>
    {% endif %}
    </div>
  3. 打开 themes\next6\_macro\post.swig,在如下代码 (相关文章) 之前,

    1
    2
    3
    {% if theme.related_posts.enable and (theme.related_posts.display_in_home or not is_index) %}
    {% include 'post-related.swig' with { post: post } %}
    {% endif %}

    加入

    1
    2
    3
    4
    5
    <div>
    {% if not is_index and theme.end_info.enable %}
    {% include 'passage-end-tag.swig' %}
    {% endif %}
    </div>
  4. 结束,刷新网页查看效果

4. 文章中添加对应的多语言版本的链接

这个功能需要手动设置对应文章的 abbrlink 一致。建议在本地先编译一个语言版本的文件,然后手动修改另一个版本的文章的链接。

  1. 打开 themes/next/_config.yml,添加
    1
    2
    3
    4
    5
    6
    7
    # Go to another language Page
    translation:
    enable: true
    language: English # language name
    icon: globe
    info: 英文版本
    url: https://en.xian6ge.cn # Destination URL
  2. themes\next6\_partials\ 下新建 post-tran.swig,写入如下内容,保存。
    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
    <div>
    <ul class="post-copyright">
    <li class="post-copyright-link">
    <strong><i class="fa fa-{{ theme.translation.icon }}"></i> {{ theme.translation.language + __('symbol.colon') }}</strong>
    <span id="url" style="display:none">{{theme.translation.url}}</span>
    <span id="path" style="display:none">{{post.permalink}}</span>
    <span id="info" style="display:none">{{theme.translation.info}}</span>
    <span id="goto"></span>
    </li>
    </ul>

    //我不知道怎么整理链接,所以只能用JavaScript重写。
    <script language=javascript>
    var url = document.getElementById("url").innerHTML;
    var path = document.getElementById("path").innerHTML;
    var info = document.getElementById("info").innerHTML;
    path=GetUrlRelativePath(path);
    if(info.length==0){
    infos= url+path;
    }
    else{
    infos=info;
    }
    var str = "<a href='"+url+path+"'>"+infos+"</a>"
    console.log(str);
    document.getElementById("goto").innerHTML=str;

      function GetUrlRelativePath()
      {
        var url = document.location.toString();
        var arrUrl = url.split("//");

        var start = arrUrl[1].indexOf("/");
        var relUrl = arrUrl[1].substring(start);//stop省略,截取从start开始到结尾的所有字符

        if(relUrl.indexOf("?") != -1){
          relUrl = relUrl.split("?")[0];
        }
        return relUrl;
      }
    </script>
  3. 打开 themes\next6\_macro\post.swig,在 POST BODY 之前,加入
    1
    2
    3
    4
    5
    6
    {% if theme.translation.enable and not is_index %}
    <div>
    {% include '../_partials/post-tran.swig' with { post: post } %}
    <br/>
    </div>
    {% endif %}
  4. 结束,刷新网页查看效果

5. 其他的一些小修改

1. 不蒜子统计提示语

NexT6 走简洁风格,许多地方只展示图标而略去了文字说明。但因为我在网站底部添加了太多信息,最低端的访客数提示未免显得头重脚轻。

打开 theme\next6\layout\_third-party\analytics\busuanzi-counter.swig,修改如下

1
2
3
4
5
6
7
8
9
10
11
12
13
{% if theme.busuanzi_count.total_visitors %}
<span class="site-uv" title="{{ __('footer.total_visitors') }}">
<i class="fa fa-{{ theme.busuanzi_count.total_visitors_icon }}"></i>
网站总访客数 <span class="busuanzi-value" id="busuanzi_value_site_uv"></span> 人次. |
</span>
{% endif %}

{% if theme.busuanzi_count.total_views %}
<span class="site-pv" title="{{ __('footer.total_views') }}">
&nbsp;<i class="fa fa-{{ theme.busuanzi_count.total_views_icon }}"></i>
总访问量 <span class="busuanzi-value" id="busuanzi_value_site_pv"></span> 次.
</span>
{% endif %}

2. 解决左边工具栏上无法跳转到外部链接的问题

由于 NexT6 做了设置,左边工具栏上的所有链接将会自动在前面添加上当前域名。对于,“首页”,“关于” 这样的链接没有问题。但如果要添加上外链,例如英文页面:https:\\en.xian6ge.cn,会被自动编译为 https:\\xian6ge.cn\https\en.xian6ge.cn,造成跳转出错。为此,我们可以采用一个折中的办法。

hexo\source 下建立一个 en.html 文件,在里面通过 JavaScript 代码跳转。但这样会遇到一个问题,Hexo 会编译所有文件,造成其中的 Js 代码失效。因此,在前面添加 layout: false 设置,告诉编译器不要编译该 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
layout: false
title: "XianliuGe - Eternal charm, Endless sound."
date: 2018-11-13 09:12:12
---
<!--上述title采用对应网站的title,以减少跳转时的突兀感。-->
<!DOCTYPE html>
<html lang="en">

<head>

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>XianliuGe - Eternal charm, Endless sound.</title>
<script type="text/javascript">
window.location.href = "https://en.xian6ge.cn";
</script>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

<!--[if gte IE 9]>
<style type="text/css">
.gradient {
filter: none;
}
</style>
<![endif]-->

<!-- Favicon and touch icons -->
<!-- <link rel="shortcut icon" href="assets/ico/favicon.png">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png"> -->

</head>

<body>

<!-- Loader -->
<h1>前往『贤柳阁』英文版</h1>
<h2>Go to XianliuGe for English</h2>

</body>

</html>

3. 修改背景,颜色样式等

打开 theme\hexo-theme-next\source\css\_custom\custom.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
//添加背景图片
body { background:url(/images/backGround.jpg)}
//改掉题头颜色
.site-meta {
background: #F0D784; //修改为自己喜欢的颜色
}
//主标题颜色
.brand{
color: #2f9833
}
//副标题颜色
.site-subtitle{
color: #47b54a
}
//页脚统计文字颜色
.footer{
color: #F0D784
}
//修改页脚备案链接颜色
.footer a{
color: #F0D784
}
//修改页脚统计人数的颜色
.footer .with-love{
color: #F0D784
}

更多修改样式的方法请查看为你的博客换上新年皮肤,NexT 主题个性化样式详解