嘘~ 正在从服务器偷取页面 . . .

Matery 主题添加多级分类


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 造成了。

因为 Materializebootstrap 存在冲突。

4、重头再来

经过六个小时的摸索, 查看 Materialize 的官网用法,搞个 Demo , 然后把刚才上面的代码重新修改调试, 达到了几本可以用, 且不再冲突,因为用的是 Materialize 的样式,好吧~ 不知不觉,又折腾了一遍 bootstrapMaterialize

新的 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>&nbsp;&nbsp; 文章多级分类
        </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");
}

先备份,然后大胆的折腾,大胆的改~

相关文章




版权声明: 本博客所有文章除特別声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明来源 Small-Rose / 张小菜 !
评论
  目录