Hexo Matery 主题添加多级分类
有同学提出 Matery 主题的 标签 和 分类 的展示太相似,可以说基本上是一样的。于是有了本文,尝试改成多级分类的。 假如要自己从零开始学习又不太现实, 所以就借鉴移植了 Fluid 主题的多级分类功能。为了给也想折腾的人,特此记录修改过程。
多级分类添加流程
Matery 主题是卡片式结构,为了保持原来的整体结构,新建多级分类的模块。
1、新建 category-list.ejs
在主题目录 /layout/_widget/
目录下新建 category-list.ejs
文件。 内容如下:
<% var orderBy = 'name' ; %>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<style>
.category:not(:last-child) {
margin-bottom: 1rem;
}
.category-item {
font-size: 1.25rem;
font-weight: bold;
display: flex;
align-items: center;
}
.category-subitem {
font-size: 1rem;
font-weight: bold;
}
.category-collapse {
margin-left: 1.25rem;
width: 100%;
}
.category-count {
font-size: 0.9rem;
font-weight: initial;
min-width: 1.3em;
line-height: 1.3em;
display: flex;
align-items: center;
}
.category-count i {
padding-right: 0.25rem;
}
.category-count span {
width: 2rem;
}
.category-item-action:not(.collapsed) > i {
transform: rotate(90deg);
transform-origin: center center;
}
.category-item-action i {
transition: transform 0.3s ease-out;
display: inline-block;
margin-left: 0.25rem;
}
.category-item-action:hover {
z-index: 1;
color: #38ACDF;
text-decoration: none;
background-color: #F8F9FA;
}
.category .row {
margin-left: 0;
margin-right: 0;
}
.list-group-item:first-child {
border-top-left-radius: .25rem;
border-top-right-radius: .25rem;
}
.category-item {
font-size: 1.25rem;
font-weight: 700;
display: flex;
align-items: center;
}
.list-group-item {
background-color: transparent;
border: 0;
}
.list-group-item {
position: relative;
display: block;
padding: .75rem 1.25rem;
background-color: #fff;
/* border: 1px solid rgba(0,0,0,.125); */
}
#card-list-zzy .list-group-item:hover {
color: #38ACDF;
background-color: #F8F9FA;
/* border: 1px solid rgba(0,0,0,.125); */
}
.category-item-action i {
transition: transform .3s ease-out;
display: inline-block;
margin-left: .25rem;
}
card-categories-list-spcail > div:hover{
color:#38ACDF;
background-color: #F8F9FA;
}
.fa {
font-size: 1rem;
line-height: 1;
}
.category-count {
font-size: .9rem;
font-weight: initial;
min-width: 1.3em;
line-height: 1.3em;
display: flex;
align-items: center;
}
.collapse:not(.show) {
display: none;
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
@include transition($transition-collapse);
}
#card-list-zzy{
position: relative;
/* margin-top: -2rem; */
transition: background-color .2s ease-in-out;
border-radius: .5rem;
z-index: 3;
}
</style>
<% function render_categories(cats, depth) { %>
<% depth = depth || 0 %>
<% return cats.each(function(cat){ %>
<% var subCats = site.categories.find({parent: cat._id}).sort(orderBy).filter(cat => cat.length) %>
<% var collapsed = subCats.length === 0 %>
<div class="<%= depth <= 0 ? 'category' : 'category-sub' %> row">
<a
class="<%= depth <= 0 ? 'category-item' : 'category-subitem' %> <%= collapsed ? 'collapsed' : '' %> list-group-item category-item-action col-10 col-md-11"
id="heading-<%= cat._id %>" role="tab" data-toggle="collapse" data-target="#collapse-<%= cat._id %>"
aria-expanded="<%= collapsed ? 'false' : 'true' %>"
>
<%= cat.name %>
<i class="fas fa-chevron-right"></i>
</a>
<a href="<%= url_for(cat.path) %>" class="category-count col-2 col-md-1">
<i class="fa fa-list"></i>
<span><%= cat.posts.length %></span>
</a>
<div class="category-collapse">
<% if (subCats.length > 0) { %>
<%- render_sub_categories(subCats, cat, depth + 1) %>
<% } else { %>
<%- render_posts(cat) %>
<% } %>
</div>
</div>
<% }) %>
<% } %>
<% function render_sub_categories(cats, parent, depth) { %>
<div id="collapse-<%= parent._id %>" class=" collapse in show" role="tabpanel"
aria-labelledby="heading-<%= parent._id %>">
<%- render_categories(cats, depth) %>
</div>
<% } %>
<% function render_posts(cat) { %>
<div id="collapse-<%= cat._id %>" class="collapse in" role="tabpanel"
aria-labelledby="heading-<%= cat._id %>">
<% var limit = 100 ; %>
<% var posts = cat.posts.sort(config.index_generator.order_by || '-date') %>
<% for (var idx = 0; idx < posts.length; idx++) { %>
<% var post = posts.data[idx] %>
<% if (idx && limit && idx >= limit) { %>
<a href="<%- url_for(cat.path) %>" class="list-group-item list-group-item-action">
<span class="category-post">More...</span>
</a>
<% break %>
<% } else { %>
<a href="<%- url_for(post.path) %>" class="list-group-item list-group-item-action">
<span class="category-post"><%= post.title %></span>
</a>
<% } %>
<% } %>
</div>
<% } %>
<div class="container" data-aos="fade-up">
<div class="card card-categories-list-spcail">
<div class="card-content col-12 col-md-10 m-auto ">
<div id="card-list-zzy" class="">
<div class="category-list">
<% cats = site.categories.find({parent: {$exists: false}}).sort(orderBy).filter(cat => cat.length) %>
<%- render_categories(cats) %>
</div>
</div>
</div>
</div>
</div>
2、引入 category-list.ejs
找到主题目录下 /layout/categories.ejs
, 添加以下代码:
<%- partial('_widget/category-list') %>
加了之后,大概是这样子:
<%- partial('_partial/bg-cover') %>
<main class="content">
<%- partial('_widget/category-cloud') %>
<% if (site.categories && site.categories.length > 0) { %>
<%- partial('_widget/category-radar') %>
<% } %>
<%- partial('_widget/category-list') %>
</main>
3、使用
在文章的头部写 categories
多级的写法:
categories:
- 收藏资源
- 工具网站
显示分级则依次从上到下。
最后启动看效果吧~
hexo clean
hexo g
hexo s
好吧,如果你不是歌追求完美的人,现在其实已经可以使用了。
咳~ 咳~ 该说正事了
接下来跟我的提示去瞧瞧,看看你这个页面的 baner 上的子标题,是不是有像右点跑偏的一点, 再看看这个页面的 footer 是不是没有原来规整了?
其实是因为这个页面引入了 bootstrap.min.css
造成了。
因为 Materialize
和 bootstrap
存在冲突。
4、重头再来
经过六个小时的摸索, 查看 Materialize
的官网用法,搞个 Demo
, 然后把刚才上面的代码重新修改调试, 达到了几本可以用, 且不再冲突,因为用的是 Materialize
的样式,好吧~ 不知不觉,又折腾了一遍 bootstrap
和 Materialize
。
新的 category-list.ejs
长这样:
<% var orderBy = 'name' ; %>
<style>
/*
.category:not(:last-child) {
margin-bottom: 1rem;
}
*/
.category-item {
font-size: 1.25rem;
font-weight: bold;
display: flex;
align-items: center;
}
.category-subitem {
font-size: 1rem;
font-weight: bold;
}
.category-collapse {
margin-left: 1.25rem;
width: 100%;
}
.category-count {
font-size: 0.9rem;
font-weight: initial;
min-width: 1.3em;
line-height: 1.3em;
display: flex;
align-items: center;
}
.category-count i {
padding-right: 0.25rem;
}
.category-count span {
width: 2rem;
}
.category-item-action:not(.collapsed) > i {
transform: rotate(90deg);
transform-origin: center center;
}
.category-item-action i {
transition: transform 0.3s ease-out;
display: inline-block;
margin-left: 0.25rem;
}
.category-item-action:hover {
z-index: 1;
color: #38ACDF;
text-decoration: none;
background-color: #F8F9FA;
}
.list-group-item:first-child {
border-top-left-radius: .25rem;
border-top-right-radius: .25rem;
}
.category-item {
font-size: 1.25rem;
font-weight: 700;
display: flex;
align-items: center;
}
.list-group-item {
background-color: transparent;
border: 0;
}
.list-group-item {
position: relative;
display: block;
padding: .75rem 1.25rem;
background-color: #fff;
/* border: 1px solid rgba(0,0,0,.125); */
}
#card-list-zzy .list-group-item:hover {
color: #38ACDF;
background-color: #F8F9FA;
/* border: 1px solid rgba(0,0,0,.125); */
}
/*
.category-item-action i {
transition: transform .3s ease-out;
display: inline-block;
margin-left: .25rem;
}
*/
card-categories-list-spcail > div:hover{
color:#38ACDF;
background-color: #F8F9FA;
}
.fa {
font-size: 1rem;
line-height: 1;
}
.category-count {
font-size: .9rem;
font-weight: initial;
min-width: 1.3em;
line-height: 1.3em;
display: flex;
align-items: center;
}
.category-content{
border-left:0px;
padding: .75rem 1.25rem;
}
.category-content a{
color: black;
}
.category-content a:hover{
color:#38ACDF;
background-color: #F8F9FA;
}
.category-row {
border-color: #F8F9FA;;
border-bottom:none;
}
#card-list-zzy{
position: relative;
/* margin-top: -2rem; */
transition: background-color .2s ease-in-out;
border-radius: .5rem;
z-index: 3;
}
.collapsible-header{
boder: none;
}
</style>
<% function render_categories(cats, depth) { %>
<% depth = depth || 0 %>
<% return cats.each(function(cat){ %>
<% var subCats = site.categories.find({parent: cat._id}).sort(orderBy).filter(cat => cat.length) %>
<% var collapsed = subCats.length === 0 %>
<li class="<%= subCats.length > 0 ? 'active' : '' %>" >
<div class="<%= depth <= 0 ? 'category-row' : 'category-row category-sub' %> row collapsible-header">
<a
class=" <%= depth <= 0 ? 'category-item' : 'category-subitem' %> <%= subCats.length > 0 ? '' : 'collapsed' %> list-group-item category-item-action col s10 m9"
id="heading-<%= cat._id %>"
>
<%= cat.name %>
<i class="fas fa-chevron-right"></i>
</a>
<a href="<%= url_for(cat.path) %>" class="category-count col s2 m3">
<i class="fa fa-list"></i>
<span><%= cat.posts.length %></span>
</a>
</div>
<% if (subCats.length > 0) { %>
<div class="category-content collapsible-body">
<%- render_sub_categories(subCats, cat, depth + 1) %>
</div>
<% } else { %>
<%- render_posts(cat) %>
<% } %>
</li>
<% }) %>
<% } %>
<% function render_sub_categories(cats, parent, depth) { %>
<ul class="collapsible category-row" data-collapsible="expandable">
<%- render_categories(cats, depth) %>
</ul>
<% } %>
<% function render_posts(cat) { %>
<div id="collapse-<%= cat._id %>" class="category-content collapsible-body" >
<% var limit = 20 ; %>
<% var posts = cat.posts.sort(config.index_generator.order_by || '-date') %>
<% for (var idx = 0; idx < posts.length; idx++) { %>
<% var post = posts.data[idx] %>
<% if (idx && limit && idx >= limit) { %>
<a href="<%- url_for(cat.path) %>" class="list-group-item list-group-item-action">
<span class="category-post">More...</span>
</a>
<% break %>
<% } else { %>
<a href="<%- url_for(post.path) %>" class=" list-group-item list-group-item-action">
<span class="category-post"><%= post.title %></span>
</a>
<% } %>
<% } %>
</div>
<% } %>
<div class="container" data-aos="fade-up">
<div class="card card-categories-list-spcail">
<div class="card-content col s12 m12">
<div id="card-list-zzy" class="container ">
<ul class="category-list collapsible " data-collapsible="expandable">
<% cats = site.categories.find({parent: {$exists: false}}).sort(orderBy).filter(cat => cat.length) %>
<%- render_categories(cats) %>
</ul>
</div>
</div>
</div>
</div>
<script>
$('.list-group-item').click(function(){
var id = $(this).attr('href');
if($(this).hasClass('collapsed')){
$(this).removeClass('collapsed');
$(this).attr("aria-expanded",true);
}else{
$(this).addClass('collapsed');
$(this).attr("aria-expanded",false);
}
var val = $(id).css('display');
if(val == 'block'){
//$(id).hide();
//$(id).slideUp();
}else{
//$(id).show();
//$(id).slideDown();
}
});
$(document).ready(function(){
$('.collapsible').collapsible();
});
</script>
5、重新编译启动
可能还有一些样式问题,不过要睡觉了。
就自己调调吧~ 尽量用内联样式
后面调好了,文章再更新。
6、重新更新一版
重新调整样式, 添加了标题, 去掉了调试 Demo , 理论上不限制级别深, 添加了自定义显示多少最近多少篇配置参数。
新的 category-list.ejs
长这样:
<% var orderBy = 'name' ; %>
<style>
/*
.category:not(:last-child) {
margin-bottom: 1rem;
}
*/
.category-item {
font-size: 1.25rem;
font-weight: bold;
display: flex;
align-items: center;
}
.category-subitem {
font-size: 1rem;
font-weight: bold;
}
.category-collapse {
margin-left: 1.25rem;
width: 100%;
}
.category-count {
font-size: 0.9rem;
font-weight: initial;
min-width: 1.3em;
line-height: 1.3em;
display: flex;
align-items: center;
}
.category-count i {
padding-right: 0.25rem;
}
.category-count span {
width: 2rem;
}
.category-item-action:not(.collapsed) > i {
transform: rotate(90deg);
transform-origin: center center;
}
.category-item-action i {
transition: transform 0.3s ease-out;
display: inline-block;
margin-left: 0.25rem;
}
.category-item-action:hover {
z-index: 1;
color: #38ACDF;
text-decoration: none;
background-color: #F8F9FA;
}
.list-group-item:first-child {
border-top-left-radius: .25rem;
border-top-right-radius: .25rem;
}
.category-item {
font-size: 1.25rem;
font-weight: 700;
display: flex;
align-items: center;
}
.list-group-item {
background-color: transparent;
border: 0;
}
.list-group-item {
position: relative;
display: block;
padding: .75rem 1.25rem;
background-color: #fff;
/* border: 1px solid rgba(0,0,0,.125); */
}
#card-list-zzy .list-group-item:hover {
color: #38ACDF;
background-color: #F8F9FA;
/* border: 1px solid rgba(0,0,0,.125); */
}
.category-item-action i {
transition: transform .3s ease-out;
display: inline-block;
margin-left: .25rem;
}
.category-item-action a{
display: block;
padding: .75rem 1.25rem;
}
card-categories-list-spcail > div:hover{
color:#38ACDF;
background-color: #F8F9FA;
}
.fa {
font-size: 1rem;
line-height: 1;
}
.category-count {
font-size: .9rem;
font-weight: initial;
min-width: 1.3em;
line-height: 1.3em;
display: flex;
align-items: center;
}
.category-content{
border-left:0px;
padding: .75rem 1.25rem;
}
.category-content a{
color: black;
}
.category-content a:hover{
color:#38ACDF;
background-color: #F8F9FA;
box-shadow:none;
}
.category-row {
border-color: #F8F9FA;;
border-bottom:none;
box-shadow: none;
}
#card-list-zzy{
position: relative;
/* margin-top: -2rem; */
transition: background-color .2s ease-in-out;
border-radius: .5rem;
z-index: 3;
}
.collapsible-header{
boder: none;
}
.collapsible{
box-shadow:none !important;
-webkit-box-shadow: none !important;
border-left:none !important;
border-right:none !important;
border-bottom:none !important;
}
.categories-title{
padding-top: 20px;
/* padding-bottom: 5px; */
margin-bottom: -10px;
}
</style>
<% function render_categories(cats, depth) { %>
<% depth = depth || 0 %>
<% return cats.each(function(cat){ %>
<% var subCats = site.categories.find({parent: cat._id}).sort(orderBy).filter(cat => cat.length) %>
<% var collapsed = subCats.length === 0 %>
<li class="<%= subCats.length > 0 ? 'active' : '' %>" >
<div class="<%= depth <= 0 ? 'category-row' : 'category-row category-sub' %> row collapsible-header">
<a
class=" <%= depth <= 0 ? 'category-item' : 'category-subitem' %> <%= subCats.length > 0 ? '' : 'collapsed' %> list-group-item category-item-action col s11 m11"
id="heading-<%= cat._id %>"
>
<%= cat.name %>
<i class="fas fa-chevron-right"></i>
</a>
<a href="<%= url_for(cat.path) %>" class="category-count col s1 m1">
<i class="fa fa-list"></i>
<span><%= cat.posts.length %></span>
</a>
</div>
<% if (subCats.length > 0) { %>
<div class="category-content collapsible-body">
<%- render_sub_categories(subCats, cat, depth + 1) %>
</div>
<% } else { %>
<%- render_posts(cat) %>
<% } %>
</li>
<% }) %>
<% } %>
<% function render_sub_categories(cats, parent, depth) { %>
<ul class="collapsible expandable category-row" data-collapsible="expandable">
<%- render_categories(cats, depth) %>
</ul>
<% } %>
<% function render_posts(cat) { %>
<div id="collapse-<%= cat._id %>" class="category-content collapsible-body" >
<% var limit = theme.category.list || 10 ; %>
<% var posts = cat.posts.sort(config.index_generator.order_by || '-date') %>
<% for (var idx = 0; idx < posts.length; idx++) { %>
<% var post = posts.data[idx] %>
<% if (idx && limit && idx >= limit) { %>
<a href="<%- url_for(cat.path) %>" class="list-group-item list-group-item-action">
<span class="category-post">More...</span>
</a>
<% break %>
<% } else { %>
<a href="<%- url_for(post.path) %>" class=" list-group-item list-group-item-action">
<span class="category-post"><%= post.title %></span>
</a>
<% } %>
<% } %>
</div>
<% } %>
<div class="container" data-aos="fade-up">
<div class="card card-categories-list-spcail">
<div class="categories-title center-align">
<i class="fas fa-bookmark"></i> 文章多级分类
</div>
<div class="card-content col s12 m12">
<div id="card-list-zzy" class="container ">
<ul class="category-list collapsible expandable" data-collapsible="expandable">
<% cats = site.categories.find({parent: {$exists: false}}).sort(orderBy).filter(cat => cat.length) %>
<%- render_categories(cats) %>
</ul>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script>
<script>
$('.list-group-item').click(function(){
if($(this).hasClass('collapsed') ){
$(this).removeClass('collapsed');
//$(this).parent().next().slideDown();
}else{
$(this).addClass('collapsed');
//$(this).parent().next().slideUp();
}
});
var elem = document.querySelector('.collapsible .expandable');
var instance = M.Collapsible.init(elem, {
accordion: false
});
</script>
然后在主题配置中添加配置参数:
category:
list: 10
该值表示多级分类展开时显示最近的10篇文章列表, 不设置默认会显示10篇,修改该值即可实现自定义设置显示多少条。
效果在我的分类里,自己看看吧~
category-list.ejs
中引入了另一个版本的js
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script>
如果去掉了这个 js 引入, 那么需要放开 js 中注释了的 $(this).parent().next().slideDown();
和 $(this).parent().next().slideUp();
, 然后将 <li class="<%= subCats.length > 0 ? 'active' : '' %>" >
修改成 <li>
,只是效果略显不同。 展开后不再自动折叠。 如果你愿意动手,自己加个按钮, 可以搞个全部展开的按钮, 事件的关键代码如下:
function openOrClose(){
var disVal = $(".collapsible-body").css("display");
disVal =='none' ? $(".collapsible-body").css("display","block"); :$(".collapsible-body").css("display","none");
}
先备份,然后大胆的折腾,大胆的改~
相关文章
- Hexo搭建静态博客(一)——基础搭建
- Hexo搭建静态博客(二)——创建页面
- Hexo搭建静态博客(三)——主题更换
- Hexo搭建静态博客(四)——插件安装
- Hexo搭建静态博客(五)——踩坑问题
- Hexo搭建静态博客(六)——项目部署
- Hexo搭建静态博客(七)——客服与推送
- Hexo添加Live2D二次元老婆
- Hexo博客Valine-Admin踩坑记录
- Hexo博客Matery主题valine升级与优化
- Hexo博客Matery主题新手常见问题
- Hexo博客Matery主题添加多级分类
- Hexo博客添加思维导图渲染
- Hexo博客Matery主题添加说说Artitalk教程
- 静态博客-字体更换教程