最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

functions - Create a Woocommerce product widget with category filter

programmeradmin2浏览0评论

I'd like to create a WooCommerce products widget like the standard WooCommerce products widget, but with the option to filter on category. I know there is a shortcode for displaying products of a certain category, but I don't like the standard thumbnail view, but like to have a list like in the WooCom products widget.

On Github, I have found the following code which allows to add a WooCom products widget with a filter on product ID:

<?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: /
*/


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' );
} );

Can any of you Wordpress Guru's help me to adapt this so I can filter on category instead of product ID? I'll do an attempt myself, but definitely can use your help.


Own attempt: I think I should change my WP_query arguments to retrieve the category ID's instead of the post ID's. However, I tried this & this is not working.

    $query_args = array(
        'post_status'    => 'publish',
        'post_type'      => 'product',
        'no_found_rows'  => 1,
        'cat'        => $'arr_id'
    ); 

    $r = new WP_Query( $query_args );

Full solution as provided by LWS-Mo Many many many thanks! You made my day. I would like to accept and upvote your comment but since I am new on the forum, my reputation is not high enough for that :(. Anyone else who is able to use the solution, give the man some credits ;). Again thanks!

<?php
/*
Plugin Name: Products by category
Description: This plugin displays a list of products of a certain category on your website.
*/


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

class Bi_Widget_Product extends WP_Widget
{

    function __construct()
    {
        parent::__construct(
                'woocommerce_ndbProducts',
                __( 'Products by category', 'ndb' ),
                array('description' => __( 'This plugin displays a list of products of a certain category 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,
            'posts_per_page' => -1, //-1 needed for displaying all posts of the category
            'tax_query' => array(
                array(
                    'taxonomy' => 'product_cat', //the taxonomy we want to query
                    'field' => 'term_id', //we use the term_id tp find our terms
                    'terms' => $arr_id //our comma seperated list of ID´s
                )
            )
        );

        $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('Category:'); ?></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' );
} );

I'd like to create a WooCommerce products widget like the standard WooCommerce products widget, but with the option to filter on category. I know there is a shortcode for displaying products of a certain category, but I don't like the standard thumbnail view, but like to have a list like in the WooCom products widget.

On Github, I have found the following code which allows to add a WooCom products widget with a filter on product ID:

<?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/
*/


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' );
} );

Can any of you Wordpress Guru's help me to adapt this so I can filter on category instead of product ID? I'll do an attempt myself, but definitely can use your help.


Own attempt: I think I should change my WP_query arguments to retrieve the category ID's instead of the post ID's. However, I tried this & this is not working.

    $query_args = array(
        'post_status'    => 'publish',
        'post_type'      => 'product',
        'no_found_rows'  => 1,
        'cat'        => $'arr_id'
    ); 

    $r = new WP_Query( $query_args );

Full solution as provided by LWS-Mo Many many many thanks! You made my day. I would like to accept and upvote your comment but since I am new on the forum, my reputation is not high enough for that :(. Anyone else who is able to use the solution, give the man some credits ;). Again thanks!

<?php
/*
Plugin Name: Products by category
Description: This plugin displays a list of products of a certain category on your website.
*/


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

class Bi_Widget_Product extends WP_Widget
{

    function __construct()
    {
        parent::__construct(
                'woocommerce_ndbProducts',
                __( 'Products by category', 'ndb' ),
                array('description' => __( 'This plugin displays a list of products of a certain category 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,
            'posts_per_page' => -1, //-1 needed for displaying all posts of the category
            'tax_query' => array(
                array(
                    'taxonomy' => 'product_cat', //the taxonomy we want to query
                    'field' => 'term_id', //we use the term_id tp find our terms
                    'terms' => $arr_id //our comma seperated list of ID´s
                )
            )
        );

        $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('Category:'); ?></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' );
} );
Share Improve this question edited Oct 4, 2017 at 12:50 BarrieO 992 silver badges12 bronze badges asked Oct 4, 2017 at 10:05 BarrieOBarrieO 11 silver badge1 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 1

The plugin you posted creates a new widget with 2 input fields. One field for the title of the widget, another field to enter a comma separated list of product ID´s.

You can change the provided code, to be able to enter a comma separated list of product_cat ID´s. (instead of product ID´s)

You only need to change the $query_args for the WP_Query.

First, remove the line 'post__in' => $arr_id. Instead we are gonna add the $arr_id(containes the list of ID´s) to a new tax_query.

Change the code:

$query_args = array(
  'post_status'    => 'publish',
  'post_type'      => 'product',
  'no_found_rows'  => 1,
  'posts_per_page' => -1, //-1 needed for displaying all posts of the category
  'tax_query' => array(
     array(
      'taxonomy' => 'product_cat', //the taxonomy we want to query
      'field' => 'term_id', //we use the term_id tp find our terms
      'terms' => $arr_id //our comma seperated list of ID´s
     )
  )
);

Now you can enter a comma separated list of product_cat ID´s in the widget. All products which are in these cats will be displayed.

P.S.
Codex for tax_query: WP_Query #Taxonomy_Parameters.
Limit the displayed posts with 'posts_per_page' => -1. WP_Query #Pagination_Parameters
Also take a look at order and orderby args. WP_Query #Order_Orderby_Parameters
And also watch your commas on the $query_args list!

发布评论

评论列表(0)

  1. 暂无评论