Hexo-Next主题-添加与修改-功能与样式

Hexo-Next主题-添加与修改-功能与样式·

NexT version :8.14.0

文章加密访问·

打开 themes/next/layout/_partials/head/head.njk文件,在 {% if theme.pace.enable %} 标签下面插入代码,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{%- if theme.pace.enable %}
<script>
(function(){
if('{{ page.password }}'){
if (prompt('请输入文章密码') !== '{{ page.password }}'){
alert('密码错误');
history.back();
}
}
})();
</script>
{{ next_vendors('pace_css') }}
{{ next_vendors('pace_js') }}
{%- endif %}

在文章的 Front-matter 上添加新项password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
title: Hexo-Next主题-添加与修改-功能与样式
date: 2022-03-29 16:43:37
categories:
- [IT,博客]
- [IT,软件,搭建与配置]
tags:
- hexo
- Next
- 主题
- 配置
comments: true
description:
password: 123456
---

头像链接至首页·

修改 themes\next\layout\_partials\sidebar\site-overview.njk 文件,原位置如下:

1
2
3
4
{%- if theme.avatar.url %}
<img class="site-author-image" itemprop="image" alt="{{ author }}"
src="{{ url_for(theme.avatar.url) }}">
{%- endif %}

在 <img> 标签前后,用 <a> 标签囊括,href 指向 {{ config.root }}

1
2
3
4
 {%- if theme.avatar.url %}
<a href="{{ config.root }}"><img class="site-author-image" itemprop="image" alt="{{ author }}"
src="{{ url_for(theme.avatar.url) }}"></a>
{%- endif %}

首页不显示文章的分类信息·

文章设置了很多分类时,在首页会显示过长的分类信息,影响观感。所以我只在点开具体文章时才显示详细分类。

修改 themes\next\layout\_partials\post\post-meta.njk 文件,原位置如下:

1
{%- if post.categories and post.categories.length and theme.post_meta.categories %}

将其修改为:

1
{%- if not is_index and post.categories and post.categories.length and theme.post_meta.categories %}

或者为了增强观感,可以将这些标签信息进行换行操作:

修改 themes\next\layout\_partials\post\post-meta.njk 文件,原位置如下:

1
{%- if theme.leancloud_visitors.enable %}

在其下添加代码,如:

1
2
{%- if theme.leancloud_visitors.enable %}
<span class="post-meta-break"></span>

允许本地刷新增加阅读量·

本项修改仅针对使用 leancloud 进行文章阅读量统计的人,而且好像也修复了 leancloud 不能用的问题。

修改 themes\next\source\js\third-party\statistics\lean-analytics.js 文件,原位置如下:

1
2
3
4
5
6
if (CONFIG.page.isPost) {
if (CONFIG.hostname !== location.hostname) return;
addCount(Counter);
} else if (document.querySelectorAll('.post-title-link').length >= 1) {
showTime(Counter);
}

注释掉if (CONFIG.hostname !== location.hostname) return;,即可

1
2
3
4
5
6
if (CONFIG.page.isPost) {
// if (CONFIG.hostname !== location.hostname) return;
addCount(Counter);
} else if (document.querySelectorAll('.post-title-link').length >= 1) {
showTime(Counter);
}

文章时效性提示·

技术性文章往往存在时效性的问题,比如某些文章会介绍一些临时解决方案,但随着时间推移可能已经失效了。我们可以通过判断发布时间(即文章设置的 date)与当前时间的间隔,来为文章开头插入一条提示。

效果如下:

文章时效性提示·

这是一篇发布于 xxx 天前的文章,部分信息可能已发生改变,请注意甄别。

  1. 首先在hexo根目录/source文件夹中创建js文件夹,并在js文件夹中创建date_to_now.js文件。

  2. date_to_now.js文件中添加以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    (function() {
    var times = document.getElementsByTagName('time');
    if (times.length === 0) { return; }
    var posts = document.getElementsByClassName('post-body');
    if (posts.length === 0) { return; }

    var updateTime = new Date(times[1].dateTime).getTime(); /* 文章发布时间戳 */
    var nowTime = Date.now() /* 当前时间戳 */
    var interval = parseInt(nowTime - updateTime)
    /* 发布时间超过指定时间(毫秒)(30天) */
    if (interval > 30*24*60*60*1000){
    var days = parseInt(interval / 86400000)
    posts[0].innerHTML = '<div class="note warning"><p>' +
    '<h4>文章时效性提示</h4><p>这是一篇发布于 ' + days + ' 天前的文章,部分信息可能已发生改变,请注意甄别。' +
    '</p></p></div>' + posts[0].innerHTML;
    }
    })();
  3. 然后在hexo根目录创建文件夹 scripts,hexo会自动使用该文件夹下的脚本

  4. scripts文件夹中创建文件injector.js ,添加以下代码:

    1
    2
    3
    hexo.extend.injector.register('body_end', `
    <script src="/js/date_to_now.js"></script>
    `)

添加代码折叠功能·

原文

实现折叠的主代码·

themes\next\source\js 文件夹下,新建文件 code-unfold.js ,添加以下代码:

代码折叠view raw
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
var CODE_MAX_HEIGHT = 500;
var containers = [];

// 展开
$('body').on('click', '.js_unfold_code_btn', function () {
$(this).closest('.js_highlight_container').addClass('on');
});
// 收起
$('body').on('click', '.js_retract_code_btn', function () {
var $container = $(this).closest('.js_highlight_container').removeClass('on');
var winTop = $(window).scrollTop();
var offsetTop = $container.offset().top;
$(this).css('top', 0);
if (winTop > offsetTop) {
// 设置滚动条位置
$('body, html').animate({
scrollTop: $container.offset().top - CODE_MAX_HEIGHT
}, 600);
}
});
// 滚动事件,触发动画效果
$(window).on('scroll', function () {
var scrollTop = $(window).scrollTop();
var temp = [];
for (let i = 0; i < containers.length; i++) {
var item = containers[i];
var { $container, height, $hide, hasHorizontalScrollbar } = item;
if ($container.closest('body').length === 0) {
// 如果 $container 元素已经不在页面上, 则删除该元素
// 防止pjax页面跳转之后,元素未删除
continue;
}
temp.push(item);
if (!$container.hasClass('on')) {
continue;
}
var offsetTop = $container.offset().top;
var hideBtnHeight = $hide.outerHeight();
// 减去按钮高度,减去底部滚动条高度
var maxTop = parseInt(height - (hasHorizontalScrollbar ? 17 : 0) - hideBtnHeight);
let top = parseInt(
Math.min(
Math.max(scrollTop - offsetTop, 0), // 如果小于 0 ,则取 0
maxTop,// 如果大于 height ,则取 height
)
);
// 根据 sin 曲线设置"收起代码"位置
var halfHeight = parseInt($(window).height() / 2 * Math.sin((top / maxTop) * 90 * (2 * Math.PI/360)));
$hide.css('top', Math.min(top + halfHeight, maxTop));
}
containers = temp;
});

// 添加隐藏容器
function addCodeWrap($node) {
var $container = $node.wrap('<div class="js_highlight_container highlight-container"><div class="highlight-wrap"></div></div>').closest('.js_highlight_container');

// 底部 "展开代码" 与 侧边栏 "收起代码"
var $btn = $(`
<div class="highlight-footer">
<a class="js_unfold_code_btn show-btn" href="javascript:;">展开代码<i class="fa fa-angle-down" aria-hidden="true"></i></a>
</div>
<a class="js_retract_code_btn hide-btn" href="javascript:;"><i class="fa fa-angle-up" aria-hidden="true"></i>收起代码</a>
`);

$container.append($btn);
return $container;
};

function codeUnfold () {
$('.highlight').each(function () {
// 防止重复渲染
if (this.__render__ === true) {
return true;
}
this.__render__ = true;
var $this = $(this);
var height = $(this).outerHeight();
if (height > CODE_MAX_HEIGHT) {
// 添加展开&收起容器
var $container = addCodeWrap($this, height);
containers.push({
$container,
height,
$hide: $container.find('.js_retract_code_btn'),
hasHorizontalScrollbar: this.scrollWidth > this.offsetWidth,
});
}
});
};

启用Jquery·

  • 方案一:

    修改配置:在 Next 主题配置文件中,将 fancybox 项设为 true 。如下:

    1
    fancybox: true

    因为fancybox会依赖jquery,所以设置成true时,就会启用jquery。

  • 方案二:在next主题全局引用jquery

引用 code-unfold.js·

修改文件themes/next/layout/_scripts/index.njk,在最后面添加以下代码:

1
2
3
4
{# 代码折叠 #}
{%- if theme.code_unfold %}
{{- next_js('code-unfold.js') }}
{%- endif %}

修改文件themes/next/source/js/next-boot.js,仿造如下格式,添加代码:

1
2
3
NexT.boot.refresh = function () {
// 代码折叠
codeUnfold();

添加样式·

theme/next/source/css/_common/components目录下,新建文件 highlight.styl ,添加以下代码:

样式view raw
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
// 展开收起效果
.highlight-container
position: relative
background-color: highlight-background
&.on
.highlight-footer
display: none
.hide-btn
display: flex
.highlight-wrap
max-height: none
.highlight-wrap
overflow: hidden
max-height: 508px
.highlight-footer
position absolute
width: 100%
left: 0
bottom: 0
height: 60px
background-image: 'linear-gradient(-180deg, rgba(255,255,255,0) 0%, %s 65%)' % highlight-background;
text-align: center
.show-btn
font-size: 20px
color: #fff
position: absolute
left: 50%
transform: translateX(-50%)
bottom: 0
line-height: 2em
text-decoration: none
padding: 0 0.8em
text-align: center
border-radius: 4px 4px 0
&:hover
text-decoration: none
.hide-btn
color: #fff
font-size: 20px
width: 28px
position: absolute
left: -28px
top: 0
line-height: 1em
text-decoration: none
text-align: center
display: none
flex-direction: column
background-color: highlight-background
border-radius: 4px 0 0 4px
padding: 0.1em 0 0.6em
transition: top ease 0.35s
.fa-angle-up,
.fa-angle-down
font-style: normal
color: #fff
.fa-angle-up:before
content:"\f106"
.fa-angle-down:before
content:"\f107"
margin-left: 0.5em
.js_unfold_code_btn, .js_retract_code_btn
background: rgba(0,0,0,0.5)
border-bottom: none !important
&:hover
border-bottom-color: none !important

引用样式·

修改文件themes/next/source/css/_common/components/index.styl,在最后面添加以下代码:

1
2
// 代码折叠按钮样式
@import 'highlight'

启用代码折叠功能·

Next 主题配置文件中,在最后面添加以下代码:

1
2
3
# 代码折叠
# 因为需要jquery,所以需要同时启用 fancybox
code_unfold: true

更换渲染器·

在 Hexo 根目录下执行以下操作。

  1. 卸载 Hexo 默认自带的 Markdown 渲染器

    npm uninstall hexo-renderer-marked --save

  2. 更换成markdown-it渲染器,安装 hexo-renderer-markdown-it 插件

    npm install hexo-renderer-markdown-it --save

为文章标题添加锚点·

1
2
# Extensions
## Plugins: https://hexo.io/plugins/

在hexo根目录下的 _config.yml## Plugins: https://hexo.io/plugins/下面添加以下代码

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
# Markdown-it 渲染器设置
## Docs: https://github.com/celsomiranda/hexo-renderer-markdown-it/wiki
markdown:
render:
# 控制 Markdown 文档中的 HTML 内容是否直接渲染, 如果为 true 则表示直接使用 HTML 输出, 如果为 false 则表示对 HTML 内容转意为纯文本.
html: true
# HTML 输出时将其兼容为 XHTML.
xhtmlOut: true
breaks: true
linkify: false
typographer: true
quotes: '“”‘’'
plugins:
- markdown-it-abbr # <abbr>标签支持
- markdown-it-footnote # 脚注
- markdown-it-ins # 支持插入标签<del></del><ins></ins>/~~~~++++
- markdown-it-sub # 支持下标
- markdown-it-sup # 支持上标
#- markdown-it-emoji # 支持emoji表情
# - markdown-it-checkbox # 本行启用了 checkbox 插件
anchors:
# 将从设置的数值的标题开始添加锚点
level: 1
# 处理重复ID
# collisionSuffix: 'v':如果这样设置假设markdown文档中有两个#### 1则对应的锚点为http://example.com/#1和http://example.com/#1-v2
collisionSuffix: ''
# 将在标题处创建锚点
permalink: true
permalinkClass: header-anchor
# 设置为left则锚点符号将出现在标题前,而如果设置为right则锚点符号将出现与文章后。
permalinkSide: 'left'
permalinkSymbol: '.'
# 转换锚点 ID 中的字母为大写或小写 # "0" 不转换, "1" 为小写, "2" 为大写.
case: 0
# 用于替换空格的符号. # 默认为 "-"
separator: '-'

添加emoji表情支持·

下载 markdown-it 的 markdown-it-emoji 插件:

1
npm install markdown-it-emoji --save

在hexo根目录下的 _config.ymlmarkdown - plugins 项下添加以下代码:

1
- markdown-it-emoji       # 支持emoji表情

样式的添加与修改·

要进行样式的编辑,首先需要在 Next 主题配置文件中,取消 custom_file_path 项中 style 的注释。如下:

1
2
custom_file_path:
style: source/_data/styles.styl

然后在 hexo根目录/source 目录下创建 _data/ 文件夹,并在其目录下创建 styles.styl 文件,具体路径:source/_data/styles.styl

添加背景图·

source/_data/styles.styl 文件中插入如下代码:

1
2
3
4
5
6
7
body {
background:url(/images/background.jpg);
background-repeat: no-repeat; // 不重复
background-attachment:fixed; // 填充
background-size: cover; // 覆盖
background-position:50% 50%; // 定位
}

source/images 文件夹下,添加一张名为 backgroud.jpg 的图片

添加透明样式·

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
// 亮色模式下的样式设置
@media (prefers-color-scheme: light) {
// 文章内容的透明度设置
.post-block {
background: rgba(255, 255, 255, 0.85) none repeat scroll !important;
}

// 侧边框的透明度设置
.sidebar {
opacity: 0.9;
}

// 菜单栏的透明度设置
.header-inner {
background: rgba(255, 255, 255, 0.85);
}

// 搜索框(local-search)的透明度设置
.popup {
opacity: 0.95;
}
}

// 深色模式下的样式设置
@media (prefers-color-scheme: dark) {
.post-block {
background: rgba(51, 51, 51, 0.85) none repeat scroll !important;
}
.sidebar {
opacity: 0.85;
}
.header-inner {
background: rgba(42, 42, 42, 0.85);
}
}

返回顶部 按钮变大·

source/_data/styles.styl 文件中插入如下代码:

1
2
3
4
5
// 把返回顶部的按钮变大
.back-to-top {
font-size: 18px;
height: 40px;
}

为 Hexo 博客添加隐藏文章功能·

在博客中隐藏指定的文章,并使它们仅可通过链接访问。

当一篇文章被设置为「隐藏」时,它不会出现在任何列表中(包括首页、存档、分类页面、标签页面、Feed、站点地图等),也不会被搜索引擎索引(前提是搜索引擎遵守 noindex 标签)。

只有知道文章链接的人才可以访问被隐藏的文章。

Github地址:https://github.com/printempw/hexo-hide-posts

Hexo 如何隐藏文章 - yangstar - 博客园 (cnblogs.com)

为 Hexo 博客添加隐藏文章功能 - PRIN BLOG (prinsss.github.io)

安装·

在站点根目录下执行npm install hexo-hide-posts --save

配置·

在站点目录下的_config.yml中如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
# hexo-hide-posts,文章隐藏,仅通过链接访问
# 当一篇文章被设置为「隐藏」时,它不会出现在任何列表中(包括首页、存档、分类页面、标签页面、Feed、站点地图等),也不会被搜索引擎索引(前提是搜索引擎遵守 noindex 标签)。
# 只有知道文章链接的人才可以访问被隐藏的文章。
hide_posts:
enable: true
# front-matter 变量名,可以改成其他你喜欢的名字
filter: hidden
# 指定你想要传递隐藏文章的 generator,比如让所有隐藏文章在存档页面可见
# 常见的 generators 有:index, tag, category, archive, sitemap, feed, etc.
public_generators: [tag]
# 为隐藏的文章添加 noindex meta 标签,阻止搜索引擎收录
noindex: true

举个例子:设置 filter: secret 之后,你就可以在 front-matter 中使用 secret: true 来隐藏文章了。

使用·

在文章的 front-matter 中添加 hidden: true 即可隐藏文章。

1
2
3
4
5
---
title: '需要隐藏的文章'
date: '2023-01-25 15:49:15'
hidden: true
---

虽然首页上被隐藏了,但你仍然可以通过 http://localhost:4000/2023/01/需要隐藏的文章 链接访问它。(如果想要完全隐藏一篇文章,可以直接将其设置为草稿

你可以在命令行运行 hexo hidden:list 来获取当前所有的已隐藏文章列表。

插件也在 Local Variables 中添加了 all_postshidden_posts 变量,供自定义主题使用。