Hexo添加自定义菜单栏

网上已经有很多的教程去教自定义菜单了,但是有一个很明显的问题。新建的菜单栏的内容只能在新建的index.md里写,也就是说内容会全部挤在一页里面。我想要的菜单栏应该是像分类页那种形式或者主页的,于是我着手探索。


自定义菜单栏的原理。

比如我想新创建一个相片页,以此为例子吧。

首先输入命令

1
hexo new page photos

photos是你要创建的菜单栏的名字,不一定要按我的。这时候hexo提示我们已经创建好了一个新的分页,在source文件夹内多了个新的photos文件夹,里面是一个index.md。这个md文件是这个新菜单栏显示的全部信息。你可以当做一个博文来写信息,这样就只能全部显示在一页里。如果只是想写一些短的信息,可以这么做,和写平常文章是一样的。我们不希望用这种方法,所以不对index.md做改变。

接着打开自己主题内的config文件里找到menu相关内容,语法形式是这样的。

1
photos: /URL/||icon

menu里的语法的photos是你刚刚创建菜单栏的名字,//内是分配给这个菜单栏的链接,可以自己自定义。||后填上显示在菜单栏的图标icon。


你不想要在菜单栏显示英文,想显示成中文怎么办呢?打开主题文件夹下的languages文件夹找到zh-Hans.yml。在menu下面添加自己新建的菜单栏名字,然后在后面加上中文。

image-20230218115935632

这个文件的功能相当于一个词典,如果在这个文件内有匹配的英文会把这个英文转换成中文


进阶

打开菜单栏的一个标签或者一个分类页你会发现,每一个标签和分类都会有自己的url,这个url下就是这个标签的全部文章

image-20230218114946396

我先把想加进新菜单栏的文章页头都加上

1
categories: photos

那只要我们在menu把自己新增的页面后的/url/内改成这个photos分类的url,就能把photos分类下的全部文章引到新菜单栏页面来。

image-20230218115653149

但是可能会说,这样不是和标签或者分类页重复了吗?我的做法是平时只使用标签页标记文件,然后去menu把分类页前面加上#号,这样分类页就不会显示在网站里面了。但是在文章头部加上categories: xxxxxx,依旧能使用分类页的功能,但是又能把分类页隐藏起来。另外要加入新菜单栏的文章,不添加标签,这样就避免了和标签页的重复。

而且找到了一个同时支持置顶和隐藏文章的 hexo 生成器插件,这样就可以把主页显示的post隐藏,只在新菜单栏里显示了。

同时支持置顶和隐藏文章的 hexo 生成器插件(hexo-generator-index-custom)_0o酱的博客-

而且这个支持两个级别的置顶,不过注意使用前要卸载hexo-generator相关的模组

在根目录的config下

1
2
3
4
5
index_generator:
path: ''
per_page: 10
order_by: -date
pagination_dir: page

在config中已经有相关设置内容的不要再次添加(hexo自带的hexo-generator会把这些添加到config)否则会报错,建议先在config内找找有没有这些选项。


改成和next主页一样显示文章标题+摘要的形式

这是我个人的解决方案,但我又看到了一个大佬的方法:把新建的页面改成了和next主页一样显示文章标题+摘要的形式

添加自定义分类菜单项并定制页面布局 作者finisky

这里进行一个摘录,怕以后找不到原文了。

为显示某分类下所有文章的标题+摘要,从而和站点的主页风格一致,可以写一个Hexo扩展customcategory.js,放在Hexo的scripts目录(如果没有则创建一个):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var pagination = require('hexo-pagination');

const filteredCategory = 'XXX';

hexo.extend.generator.register('customcategory', function(locals){
var realestatePosts = locals.posts.filter(function(x) {
return x.categories.data[0].name == filteredCategory;
});

return pagination('url', realestatePosts, {
perPage: 10,
layout: ['customcategory']
});
});

xxx要和你输入hexo new page 里的名字一样,url是你添加自定义菜单时在menu的链接,两个出现的customcategory可以自己改名字,但改后的名字要一样

Pagination的用法:pagination(base, posts, [options]),详见:# hexo-pagination

这个实现比修改hexo-generator-category插件来得更方便,注入一个新的Generator叫做customcategory,把所有post locals.posts过滤一下,只留下分类为filteredCategory的文章,再用hexo-pagination将它们渲染成customcategory的layout。下一节介绍如何新建这个页面模板(注意下面的customcategory.njk和这里的文件名需要一致)。

添加分类页面模板

默认分类页面布局在主题目录的layout/category.njk,生成的每个post的为posts-collapse,即时间线形式,而我们希望这个页面是posts-expand的状态。于是需要在layout目录定制一个新的模板文件customcategory.njk:(如果在前面更改了customcategory的名字,把customcategory.njk的名字改成自己改后的)然后打开文件,输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{% extends '_layout.njk' %}
{% import '_macro/post-collapse.njk' as post_template with context %}
{% import '_macro/sidebar.njk' as sidebar_template with context %}

{% block title %}{{ __('title.category') }}: {{ page.category }} | {{ title }}{% endblock %}

{% block class %}index posts-expand{% endblock %}

{% block content %}

{%- for post in page.posts.toArray() %}
{{ partial('_macro/post.njk', {post: post, is_index: true}) }}
{%- endfor %}

{%- include '_partials/pagination.njk' -%}

{% endblock %}

{% block sidebar %}
{{ sidebar_template.render(false) }}
{% endblock %}