【问题标题】:Create a Woocommerce product widget with category filter使用类别过滤器创建 Woocommerce 产品小部件
【发布时间】:2025-12-04 00:55:01
【问题描述】:

我想创建一个类似于标准 WooCommerce 产品小部件的 WooCommerce 产品小部件,但可以选择按类别进行过滤。我知道有一个用于显示某个类别的产品的简码,但我不喜欢标准的缩略图视图,但喜欢在 WooCom 产品小部件中拥有一个列表。

在 Github 上,我找到了以下代码,它允许添加带有产品 ID 过滤器的 WooCom 产品小部件:

<?php
/*
Plugin Name: Woocommerce Custom Widget Product
Description: This plugin help display a list of customs products on your website
Author: Binh Nguyen
Version: 1.0
Author URI: http://vietcomic.net/
*/


if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

class Bi_Widget_Product extends WP_Widget
{

    function __construct()
    {
        parent::__construct(
                'woocommerce_ndbProducts',
                __( 'WP Customs Products', 'ndb' ),
                array('description' => __( 'This plugin help display a list of customs products on your website.', 'ndb' )) 
                );
    }

    public function widget( $args, $instance ) {

        extract( $args );
        $title = apply_filters( 'widget_title', $instance['title']);
        $ids   = $instance['ids'];
        $arr_id = explode(',',$ids);
        $query_args = array(
            'post_status'    => 'publish',
            'post_type'      => 'product',
            'no_found_rows'  => 1,
            'post__in'       => $arr_id
        ); 

        $r = new WP_Query( $query_args );
        if ( $r->have_posts() ) {

            echo $before_widget;

            if ( $title )
                echo $before_title . $title . $after_title;

            echo '<ul class="product_list_widget">';

            while ( $r->have_posts()) {
                $r->the_post();
                global $product;
                 ?>
                    <li>
                        <a href="<?php echo esc_url( get_permalink( $product->id ) ); ?>" title="<?php echo esc_attr( $product->get_title() ); ?>">
                            <?php echo $product->get_image(); ?>
                            <?php echo $product->get_title(); ?>
                        </a>
                        <?php if ( ! empty( $show_rating ) ) echo $product->get_rating_html(); ?>
                        <?php echo $product->get_price_html(); ?>
                    </li>
                <?php
            }

            echo '</ul>';

            echo $after_widget;
        }

        wp_reset_postdata();

        echo $content;

    }
    // Widget Backend

    public function form($instance){
        $title = (isset($instance['title'])) ? $instance['title'] : __( 'Products', 'ndb' );
        $ids = $instance['ids'];
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title :'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>"  name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('ids'); ?>"><?php _e('IDs :'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('ids'); ?>"  name="<?php echo $this->get_field_name( 'ids' ); ?>" type="text" value="<?php echo esc_attr( $ids ); ?>" />
        </p>
        <?php

    }

    public function update( $new_instance, $old_instance ) {
        $instance = array();
        $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
        $instance['ids'] = ( ! empty( $new_instance['ids'] ) ) ? strip_tags( $new_instance['ids'] ) : '';
        return $instance;
    }


}



add_action( 'widgets_init', function(){
    register_widget( 'Bi_Widget_Product' );
} );

你们中的任何一位 Wordpress Guru 都可以帮助我调整这一点,以便我可以过滤类别而不是产品 ID 吗?我会自己尝试,但绝对可以使用您的帮助。

【问题讨论】:

    标签: php wordpress woocommerce


    【解决方案1】:

    如果您正在寻找类别,您需要使用 get_terms() 查询,例如

     <?php
        $terms = get_terms( array ( 'taxonomy' => 'product_cat', 'hide_empty' => false, 'parent' => 0, 'orderby' => 'description', 'order' => 'ASC' ));
    
        foreach ($terms as $term) {
           echo $name = $term->name;
        }
    ?>
    

    解决方案 2:

    <?php
    
    //loop the names of the slugs for the country_categories
    $terms = get_terms( array ( 'taxonomy' => 'country_categories', 'hide_empty' => false, 'parent' => 0, 'orderby' => 'date', 'order' => 'DESC' ));
    foreach ($terms as $term) {
      //get category slug variables to use in your loop args
      $slug = $term->slug;
    
      $posts_args = array(
        'post_type'         => 'product',
        'posts_per_page'    => -1,
        'tax_query'         => array(
          'relation' => 'AND',
          array (
              'taxonomy' => 'product_cat',
              'field' => 'slug',
              'terms' => $slug,
          )
        ),
      );
    
      $posts_query = new WP_Query( $posts_args );
      if( $posts_query->have_posts() ):
    
        //Each div will have the particular category and its posts. The id and class will also have the slug name
        echo '<div id="' . $slug . '" class="' . $slug . '">
                <h1 class="text-center">' . $term->name . '</h1>
                while( $posts_query->have_posts() ): $posts_query->the_post();
                  get_template_part( 'template-parts/content', get_post_format() );
                endwhile;
      echo '</div>';
      endif;
      }
      ?>
    

    【讨论】:

    • 感谢您的回复@omukiguy。那么我应该如何在小部件中实现这一点以获得具有特定类别的产品? & 为什么分类方法不起作用?我是通过 WP codex 找到的:codex.wordpress.org/Class_Reference/WP_Query --> 请参阅类别参数的段落。
    • 确切地说,上面的方法会查找分类,并会为您提供术语的详细信息。如果您var_dump(),您可以看到这些但是您可以使用此代码共享特定类别的特定产品帖子。字符限制不允许我,但请检查上面的答案以获取解决方案 2。我已对其进行了编辑。
    【解决方案2】:

    我已经生成了这个小部件,你可以在我的 GitHub 上找到代码: https://github.com/Petasos/WC_ProductsByCategory

    【讨论】: