Hexo框架(四):Next主题文章置顶和公告效果

前言:

本篇设置基于NEXT主题7.7.2版本!!注意:目前我已经更新至最新版本,目前采用了全新的配置方式,这里的主题配置文件,均指hexo/source/_data目录下的next.yml文件,你可以点击这里查看:关于博客主题持续更新的问题和我的新配置方式

此外,由于对于要修改源码的配置方式,目前我均已放弃。

文章置顶

Hexo 本身并没有内置文章置顶功能,因此需要自行安装。不过 Hexo 本身有一个对文章排序的组件,也就是在站点配置文件内的 index_generator 选项,置顶功能其实就是每次排序的时候,把其中的置顶文章排在最前,本质上是一个排序组件,Hexo 默认的是 hexo-generator-index,所以先卸载再重新安装一个可以置顶的排序组件:

1
2
3
4
5
# 先卸载
npm uninstall --save hexo-generator-index

# 再安装
npm install --save hexo-generator-index-pin-top

从插件名字上就能看得出来支持置顶了。该插件的 GitHub 地址:hexo-generator-index-pin-top。插件安装完之后,只需要在文章头部信息栏内设置 top 属性即可:

1
2
3
4
5
---
title: Hexo博客文章置顶
date: 2020-03-31 07:31:04
top: true
---

这样这篇文章就具有置顶效果了。不过,仅仅只是这么做,文章虽然确实置顶了,但是从文章列表上来看,和普通的文章没什么不同。如果不特意去对比文章发布时间,可能会以为只是最新的文章而已。例如一些说明、通知之类的,为了能有个比较突出的标志,可以在 next/layout/_macro/post.swig 文件中找到以下位置并添加代码:

1
2
3
4
5
6
7
8
9
<div class="post-meta">
{%======== 加在这里============%}
{% if post.top %}
<i class="fa fa-thumb-tack" style="color: #EB6D39"></i>
<font color=EB6D39>置顶</font>
<span class="post-meta-divider">|</span>
{% endif %}
{% ============================ %}
{%- set date_diff = date(post.date) != date(post.updated) %}

这里的图标、文字、以及各自对应的颜色都可以自定义。完成后的效果就是:

image-20200331204301994

公告效果

现在文章置顶已经成功实现了,但是还有个问题,比如像我的博客,文章置顶是类似于一个窗格的形式,更符合“置顶消息”这么一个设定,没有标题、没有分类和标签、没有日期等等,但是如果不填写 title 栏,仍然会显示一个默认的“未命名”标题:

image-20200331204713823

而且会导致搜索无法使用,因此如果想实现这种:

文章置顶

就需要在文章的头部信息栏加入一个 header 属性:

1
2
3
4
5
---
title: 谢谢你来看我的博客
date: 2020-01-31 17:09:13
top: true
header: false

这样文章就会变成一个完全没有标题和各种属性的引用块了。

注意:下面的内容,因为涉及到修改源码,目前我已经不再使用了!

从侧边栏去掉文章计数

正常情况下,Next 主题侧栏会有一个显示文章、分类、标签的计数:

侧边栏

但是如果我们创建了一个上文所示的“公告”,而只是用来做一些通知、信息展示等功能,可能就并不想把这些文章算进去。想要减掉这部分的文章数量,可以在 themes/next/layout/_partials/header/menu-item.swig 文件里找到archives:site.posts.length部分并修改,将数量减 1 即可。

1
2
3
4
5
6
{%- set badges = {
archives : site.posts.length - 1,
categories: site.categories.length,
tags : site.tags.length
}
%}

然后找到themes/next/layout/_partials/sidebar/site-overview.swig 文件里找到site.posts.length 进行修改,将length - 1即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{%- if theme.site_state %}
<div class="site-state-wrap motion-element">
<nav class="site-state">
{%- if config.archive_dir != '/' and site.posts.length > 0 %}
<div class="site-state-item site-state-posts">
{%- if theme.menu.archives %}
<a href="{{ url_for(theme.menu.archives.split('||')[0] | trim) }}">
{% else %}
<a href="{{ url_for(config.archive_dir) }}">
{%- endif %}
{%=============================就是这里↓===============================%}
<span class="site-state-item-count">{{ site.posts.length - 1}}</span>
{%=============================就是这里↑===============================%}
<span class="site-state-item-name">{{ __('state.posts') }}</span>
</a>
</div>
{%- endif %}

其实就是直接把 site.posts.length 减掉了 1 而已,方法是笨方法,因为如果删掉了那篇文章,或者新增了一篇,还要再改一次源码,不过这是个备用方法,看看有没有办法能找到 site.posts 统计的地方然后直接不读取指定属性的文章。

从‘归档’中去掉文章

如果选择从侧栏的文章计数中去掉了某篇文章,可能也会希望“归档”里同样不记录,同样,归档里也有一个文章计数,还另有一个所有文章的列表,可以看到我的归档里并不包括置顶那个“信息栏”的文章,修改的方式也很类似,找到 next/layout/archive.swig 文件中 ARCHIVE BLOCK 部分并修改:

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
<div class="post-block">
<div class="posts-collapse">
<div class="collection-title">
{%================下面这行site.posts.length-1即可======================%}
{%- set posts_length = site.posts.length - 1 %}
{%- if posts_length > 210 %}
{%- set cheers = 'excellent' %}
{% elif posts_length > 130 %}
{%- set cheers = 'great' %}
{% elif posts_length > 80 %}
{%- set cheers = 'good' %}
{% elif posts_length > 50 %}
{%- set cheers = 'nice' %}
{% elif posts_length > 30 %}
{%- set cheers = 'ok' %}
{% else %}
{%- set cheers = 'um' %}
{%- endif %}
{%================下面这行site.posts.length-1即可======================%}
<span class="collection-header">{{ __('cheers.' + cheers) }}! {{ _p('counter.archive_posts', site.posts.length - 1) }} {{ __('keep_on') }}</span>
</div>

{{ post_template.render(page.posts) }}

</div>
</div>

同样,直接把 site.posts.length 减掉了 1 来去掉计数。

同样在themes/next/layout/_macro/post-collapse.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
{% macro render(posts) %}
{%- set current_year = '1970' %}
{%- for post in posts.toArray() %}
{%=============添加这一行↓↓↓↓↓↓↓===============%}
{% if not post.topic %}
{%=============添加这一行↑↑↑↑↑↑===============%}
{%- set year = date(post.date, 'YYYY') %}

{%- if year !== current_year %}
{%- set current_year = year %}
<div class="collection-year">
<span class="collection-header">{{ current_year }}</span>
</div>
{%- endif %}

<article itemscope itemtype="http://schema.org/Article">
<header class="post-header">

<div class="post-meta">
<time itemprop="dateCreated"
datetime="{{ moment(post.date).format() }}"
content="{{ date(post.date, config.date_format) }}">
{{ date(post.date, 'MM-DD') }}
</time>
</div>

<div class="post-title">
{%- if post.link %}{# Link posts #}
{%- set postTitleIcon = '<i class="fa fa-external-link"></i>' %}
{%- set postText = post.title or post.link %}
{{ next_url(post.link, postText + postTitleIcon, {class: 'post-title-link post-title-link-external', itemprop: 'url'}) }}
{% else %}
<a class="post-title-link" href="{{ url_for(post.path) }}" itemprop="url">
<span itemprop="name">{{ post.title or __('post.untitled') }}</span>
</a>
{%- endif %}
</div>
</header>
</article>
{%=============添加这一行↓↓↓↓↓↓↓===============%}
{% endif %}
{%=============添加这一行↑↑↑↑↑↑===============%}
{%- endfor %}
{% endmacro %}

这样,只要我们在文章的头部信息栏内增加一个 topic 标签(可以自定义,只要代码里和文章里一致即可),就能从“归档”的列表中去掉这篇文章!同理,也可以增加任意约束,比如去掉日期早于某个时候的文章、去掉带有某个标签的文章等等,只要把约束全部加进 if 里去即可。不过这里的修改只影响到“归档”中的列表,博客首页的所有文章还是会显示的。

一个bug

因为我这是的归档页面,每10篇文章一页,当我的的日志为整数,比如30页的时候,本来只应该显示有3页文章,但是他会显示有4页,且第4页什么也没有。

bug

目前,我还没有找解决办法【囧】

参考资料

Hexo博客DIY:文章置顶和引用式文章

------ 本文结束  感谢阅读 ------