WordPress分类存档页添加子分类选择列表

这里说的 wordpress 分类存档页,其实就是我们说的分类文章列表页,比如 WordPress 开发。最近有人找倡萌开发了一个分类存档页子分类选择功能,单纯文字说的不太清楚,配合下面的图片做说明吧。

功能说明

当访问一级分类(顶级分类),比如下图的【作文】,就显示【作文】下的子分类列表:
WordPress分类存档页添加子分类选择列表-云模板当访问二级分类,【作文】-【动物作文】时,显示它的子分类,同时还保留和它同级的二级分类,同时高亮显示【动物作文】:
WordPress分类存档页添加子分类选择列表-云模板当访问三级分类,【作文】-【动物作文】-【小鸡】时,显示的分类列表和上面一样,只不过将【动物作文】和【小鸡】高亮显示:
WordPress分类存档页添加子分类选择列表-云模板此外,对子分类做一个高度限制,分类过多就显示一个【点击查看更多】的功能。

功能实现

我们需要通过 php 代码去获取数据,然后配合 js 实现一些交互,以及通过 css 美化一下。php 部分先贴下代码,代码中重要的部分都有注释说明:

  1. if( !class_exists('WPKJ_Get_Terms_List') ) :
  2.     /**
  3.      * 获取当前分类的子分类列表
  4.      */
  5.     class WPKJ_Get_Terms_List{
  6. 
    
  7.         function __construct()
  8.         {
  9.             add_action( 'wp_enqueue_scripts', array( $this, 'wpkj_enqueue_terms_list_scripts'), 10 );
  10.         }
  11. 
    
  12.         public function wpkj_enqueue_terms_list_scripts(){
  13.             if( is_category() || is_tax() ) {
  14.                 wp_enqueue_style( 'terms-list-style', get_template_directory_uri() . 'https://img.2kss.com/assets/css/terms-list.css', array(), filemtime(get_template_directory().'https://img.2kss.com/assets/css/terms-list.css') );
  15.                 wp_enqueue_script( 'terms_list', get_template_directory_uri() . 'https://img.2kss.com/assets/js/terms-list.js', array('jquery'), '', true );
  16.             }
  17.         }
  18. 
    
  19.         public function wpkj_terms_list( $hide_empty = false ){
  20. 
    
  21.             //如果不是分类或自定义分类页面,不执行
  22.             if( !is_category() && !is_tax() ) return;
  23. 
    
  24.             //获取当前查询的对象
  25.             $object = get_queried_object();
  26.             //如果对象不存在,不执行
  27.             if( !$object ) return;
  28. 
    
  29.             $taxonomy = $object->taxonomy; //获取分类法
  30.             $current_id = $object->term_id; //获取分类id
  31. 
    
  32.             if( $current_id ){
  33. 
    
  34.                 //设置一下内容缓冲
  35.                 ob_start();
  36.                 echo '<div class="wpkj-terms-list">';
  37. 
    
  38.                 //获取当前分类对象
  39.                 $current = get_term( $current_id, $taxonomy );
  40.                 //获取当前分类的父级分类
  41.                 $parent_id = $current->parent;
  42. 
    
  43.                 if ( $parent_id ) { // 存在父级分类,说明非顶级分类
  44. 
    
  45.                     $parent = get_term( $parent_id, $taxonomy );
  46.                     $grand_parent_id = $parent->parent;
  47. 
    
  48.                     if( $grand_parent_id ){ //有祖父类,显示父级分类兄弟
  49.                         $this->wpkj_get_term_children( $grand_parent_id, $parent_id, $taxonomy, $hide_empty, 'term-parents' );
  50.                     }
  51. 
    
  52.                     //如果有父类,显示同级分类
  53.                     $this->wpkj_get_term_children( $parent_id, $current_id, $taxonomy, $hide_empty, 'term-brothers' );
  54. 
    
  55.                     //如果有子分类,显示子分类
  56.                     $this->wpkj_get_term_children( $current_id, false, $taxonomy, $hide_empty, 'term-children' );
  57. 
    
  58.                 } else { // 顶级分类时
  59. 
    
  60.                    //如果有子分类,显示子分类
  61.                    $this->wpkj_get_term_children( $current_id, false, $taxonomy, $hide_empty, 'term-children' );
  62. 
    
  63.                 }
  64. 
    
  65.                 echo '</div>';
  66. 
    
  67.                 //输出缓冲内容并清除缓冲
  68.                 echo $result = ob_get_clean();
  69. 
    
  70.             }
  71. 
    
  72.         }
  73. 
    
  74.         /**
  75.          * 通过父级id获取并输入子分类数据
  76.          * $parent_id  为父级id
  77.          * $term_id 为当前分类id,用于对比循环中哪个是当前分类,添加特定的css类名来适配高亮样式
  78.          */
  79.         public function wpkj_get_term_children( $parent_id, $term_id = false, $taxonomy, $hide_empty, $class = '' ){
  80. 
    
  81.             $args = array(
  82.                 'taxonomy' => $taxonomy,
  83.                 'hide_empty' => $hide_empty,
  84.                 'child_of' => $parent_id,
  85.                 'parent' => $parent_id, // child_of 和 parent 指定为同一个id,将只获取一个级别的数据
  86.             );
  87. 
    
  88.             $terms = get_terms( $args );
  89.             if( !is_wp_error( $terms ) ){
  90. 
    
  91.                 $HTML = '<ul class="terms-ul '.$class.'">';
  92.                 foreach ( $terms as $term) {
  93. 
    
  94.                     $id = $term->term_id;
  95. 
    
  96.                     //如果是当前分类,就添加一个类名,用于适配高亮样式
  97.                     if( $term_id && $id === $term_id ){
  98.                         $html .= '<li class="current"><a href="'. get_term_link( $id, $taxonomy ) .'">'. $term->name .'</a></li>';
  99.                     } else {
  100.                         $html .= '<li><a href="'. get_term_link( $id, $taxonomy ) .'">'. $term->name .'</a></li>';
  101.                     }
  102. 
    
  103.                 }
  104.                 $html .= '</ul>';
  105. 
    
  106.                 echo $html;
  107. 
    
  108.             }
  109.         }
  110. 
    
  111.     }
  112. endif;
  113. 
    
  114. new WPKJ_Get_Terms_List();

封装了一个简单的类 WPKJ_Get_Terms_List,为避免可能在以后的项目中有名称冲突,所以在外围判断一下是否存在同名的类。

在 WPKJ_Get_Terms_List 这个类中,除了构造方法以外,包含三个方法:

  • wpkj_enqueue_terms_list_scripts:用于引入功能所需的 css 和 js 文件。当前的设置是将 css 和 js 放在主题的 assets 对应的目录中,如果你的文件放在不同的路径,自己修改路径。
  • wpkj_terms_list:查询和判断当前分类的数据,然后进行输出。参数 $hide_empty 用来设定是否输出不含文章的空分类,默认为 false,即输出,如果不需要输出空分类,在调用时,设置为 true
  • wpkj_get_term_children:用来获取指定分类 id 的子分类数据,里面的前两个参数在注释中有说明,其余参数是为了传递一些必要的参数值。

这次开发,没有找到直接获取同级分类兄弟的方法,所以只能转变方式,先获取到父级分类 id,然后再获取子分类。刚开始尝试过 get_term_children() ,发现它会获取所有子分类,包括子分类的子分类,实在是没有办法仅限定为下一级的子分类。

然后想到了 get_terms() ,它的所有参数继承自 WP_Term_Query 类,里面有参数 child_of ,如果仅仅设置这个参数,会和 get_term_children() 一样包含了子分类的子分类。然后在网上看到有朋友指出,还需要同时设置 parent 参数为同一个父级分类 id,才能限制只显示下一级子分类。

JS 部分

为了实现“点击查看更多”的功能,需要配合 js 代码操作,以下就是 terms-list.js 文件的代码:

  1. jQuery(document).ready(function($) {
  2. 
    
  3.     // 这部分是为了设置哪个部分列表才是显示在下方的第二部分子分类,
  4.     // 以及做一些样式设置,并限定在手机端对父分类列表隐藏
  5.     if( $(".term-parents").length>0 ){
  6.         var ulClass = ".wpkj-terms-list .term-brothers";
  7.         $(".wpkj-terms-list .term-parents li").css("background", "rgb(242,242,242)");
  8.         if ($(window).width() < 860) {
  9.             $(".wpkj-terms-list .term-parents").hide();
  10.         }
  11.     } else if( $(".term-children").length>0) {
  12.         var ulClass = ".wpkj-terms-list .term-children";
  13.         $(".wpkj-terms-list .term-brothers li").css("background", "rgb(242,242,242)");
  14.         if ($(window).width() < 860) {
  15.             $(".wpkj-terms-list .term-brothers").hide();
  16.         }
  17.     } else {
  18.         var ulClass = ".wpkj-terms-list .term-brothers";
  19.     }
  20. 
    
  21.     // 子分类部分超过设置的高度 117px 就显示“点击查看更多”
  22.     $(ulClass).each(function () {
  23.         if ($(this).height() > 117) {
  24.             var moreHtm = '<span class="more-item js_more">点击查看更多</span>';
  25.             $(moreHtm).appendTo($(this).parent());
  26.             $(this).css("height", "117px");
  27.         }
  28.     });
  29.     $(document).on("click", ".wpkj-terms-list > .js_more", function () {
  30.         $(this).prev(ulClass).css("height", "auto");
  31.         $(this).removeClass("js_more").addClass("js_less");
  32.         $(this).html('点击隐藏更多');
  33.     });
  34.     $(document).on("click", ".wpkj-terms-list > .js_less", function () {
  35.         $(this).prev(ulClass).css("height", "117px");
  36.         $(this).removeClass("js_less").addClass("js_more");
  37.         $(this).html('点击查看更多');
  38.     });
  39. 
    
  40. });

注意代码中 23、26、35 三行的数字 117,是高度设置值,你可能需要根据你的需要,修改这个高度,超过这个高度就显示“点击查看更多”,js 是比较弱的,所以逻辑可能有些复杂,见笑了。

CSS 样式

我们还需要为列表添加一些样式,以下就是 terms-list.css 的代码:

  1. .wpkj-terms-list{
  2.     margin: 15px 0;
  3. }
  4. .wpkj-terms-list .terms-ul{
  5.     list-style: none;
  6.     border-top: 1px solid rgba(0,0,0,.04);
  7.     border-left: 1px solid rgba(0,0,0,.04);
  8.     padding: 0;
  9.     overflow-y: hidden;
  10. }
  11. 
    
  12. .wpkj-terms-list .terms-ul li{
  13.     width: 16.66%;
  14.     display: inline-block;
  15.     border-right: 1px solid rgba(0,0,0,.04);
  16.     border-bottom: 1px solid rgba(0,0,0,.04);
  17.     text-align: center;
  18.     background: #fff;
  19. }
  20. 
    
  21. .wpkj-terms-list .terms-ul li a{
  22.     padding: 0;
  23.     display: block;
  24.     line-height: 2;
  25.     color: #333;
  26. }
  27. 
    
  28. .wpkj-terms-list .terms-ul li.current a{
  29.     color: #ff6700;
  30. }
  31. 
    
  32. .wpkj-terms-list .more-item{
  33.     width: 100px;
  34.     margin: 10px auto;
  35.     display: block;
  36.     cursor: pointer;
  37.     color: #ff6700;
  38. }
  39. 
    
  40. @media screen and (max-width:860px){
  41.     .wpkj-terms-list .terms-ul li{
  42.         width: 20%;
  43.     }
  44. }
  45. @media screen and (max-width:640px){
  46.     .wpkj-terms-list .terms-ul li{
  47.         width: 25%;
  48.     }
  49. }
  50. @media screen and (max-width:480px){
  51.     .wpkj-terms-list .terms-ul li{
  52.         width: 33.33%;
  53.     }
  54. }
  55. @media screen and (max-width:360px){
  56.     .wpkj-terms-list .terms-ul li{
  57.         width: 50%;
  58.     }
  59. }

样式不可能适配所有主题,需要大家根据自己的需要去调整。

使用方法

一般来说,我们只需要在分类列表的文件,比如 category.php 的适当位置添加下面的代码即可:

  1. <?php
  2.     if( class_exists('WPKJ_Get_Terms_List') ) {
  3.         $list = new WPKJ_Get_Terms_List();
  4.         $list->wpkj_terms_list(); // 如果需要隐藏空分类,在左边的括号内填入 true
  5.     }
  6. ?>

先判断是否存在我们的类,然后实例化并输出。从一开始,倡萌就考虑到兼容自定义分类法的,也就是说不仅仅可用于文章的分类,还可以是其他自定义文章类型的自定义分类法。你只需要将上面的代码添加到自定义分类法的列表文件中即可。

原创文章,作者:DavidWu,如若转载,请注明出处:https://www.davidwu.net/archives/82388

WordPress安全防护插件
服务项目 服务内容 收费标准(元)
主题/插件汉化 汉化团队WordPress主题/插件,翻译率95% (以标的主题/插件的句子数量为准)
服务器环境配置 基于您现有服务器,搭建配置网站运行环境,结合我们多年来实战经验,可完美支持WordPress等PHP程序运行,并配置伪静态规则、优化目录权限等问题。服务器我们强烈推荐使用Linux系统。 100元/次
网站托管 若贵站目前尚无技术人员,无法完成服务器环境配置,可选择我们的网站托管服务,直接交付正常运行的WordPress站点,并且无需担心服务器的后续维护工作,一切都由我们来帮您完成。 标配套餐:1000元/年/站点 高配套餐:联系客服获取
网站加速优化 从服务器后端配置优化到WordPress数据库缓存、前端页面缓存、JS和CSS压缩合并,全方位优化网站加载速度,实现秒开。(此服务仅针对(云)服务器/VPS) 500元/次(仅站内优化200元/次)
主题配置 本站所有主题均支持,可快速实现,若有任何问题可以咨询客服解决,若您希望我们提供配置服务,可选购此服务。 英文主题安装 60元/次 汉化主题安装 30元/次
HTTPS配置 HTTPS已经不断普及,并且有着更高的安全性以及SEO上的优待。该服务收取的为服务费,SSL证书产生的费用请自行承担。 100元/次
网站搬家 迁移网站所有文件和数据库信息、网站相关配置的调整、以及迁移中的疑难问题故障排除。 标准收费:500元/次 若网站数据量大,需协商
网站运维 提供整站的运维服务,保证网站正常运行。包含:网站故障定位及排除、网站数据备份和恢复、网站攻击及木马等问题的处理等 标准收费:2000元/年 IP 5000以上需协商

发表评论

电子邮件地址不会被公开。 必填项已用*标注

51建站客服微信二维码
点击这里购买