skip to Main Content

I am trying to insert a WooCommerce element to display "products" (courses) from a specific category into a page.

I had also to hide these products for this specific category and it worked as expected. I just added a a filter inside functions.php and was it:

/*
 * Exclude "packages" category from "Archive Products" on page 811
 * Ref. URL: https://docs.woocommerce.com/document/exclude-a-category-from-the-shop-page/
 */
function exclude_category_archive_products( $q ) {
   $tax_query = (array) $q->get( 'tax_query' );

    $tax_query[] = array(
           'taxonomy' => 'product_cat',
           'field' => 'slug',
           'terms' => array( 'packages' ),
           'operator' => 'NOT IN'
    );


    $q->set( 'tax_query', $tax_query );

}
if( $current_post_id != "811" ) {
    add_filter( 'woocommerce_product_query', 'exclude_category_archive_products' );
}
/* END Exclude "packages" category from "Archive Products" on page 811 */

I have searched for ways to to achieve the opposite and I did not find anything "from this year or close". I’ve tried to use the "IN" or "=" operator but it didn’t work (it displays everything):

/*
 * Display "packages" category only
 */
function show_only_category_in_page( $q ) {
    var_dump("It reaches the function");
    $tax_query = (array) $q->get( 'tax_query' );

    $tax_query[] = array(
           'taxonomy' => 'product_cat',
           'field' => 'slug',
           'terms' => array( 'packages' ),
           'operator' => '='
    );

    $q->set( 'tax_query', $tax_query );
}
if( $current_post_id == "811" ) {
    var_dump("It reaches the page");
    add_filter( 'woocommerce_product_query', 'show_only_category_in_page' );
}
/*  END Display "packages" category only */

The previous code writes the string(23) "It gets reachs the page" only. What am I doing wrong?

2

Answers


  1. You should try this for that you can get products from a specific category

    Solution 1:

    $prod_categories = array(1, 2,3);
    $product_args = array(
      'numberposts' => $limit,
      'post_status' => array('publish', 'pending', 'private', 'draft'),
      'post_type' => array('product', 'product_variation'),
      'orderby' => 'ID',
      'suppress_filters' => false,
      'order' => 'ASC',
      'offset' => 0
    );
    
    if (!empty($prod_categories)) {
       $product_args['tax_query'] = array(
          array(
            'taxonomy' => 'product_cat',
            'field' => 'id',
            'terms' => $prod_categories,
            'operator' => 'IN',
       ));
     }
    
     $products = get_posts($product_args);
    

    Where 1,2,3 your category id.

    Solution 2

    Create a custom page and show specific categories of products:

    <?php
    /**
    * Template Name: Courses template
    *
    */
    defined( 'ABSPATH' ) || exit;
    
    
    get_header();
    ?>
        <div id="content" class="content" role="main">
    
            <ul class="products">
                <?php
                    $args = array( 
                        'post_type' => 'product', 
                        'posts_per_page' => -1, 
                        'product_cat' => 'clothing', // Category slug "clothing"
                        'orderby' => 'rand' 
                    );
                    $loop = new WP_Query( $args );
                    while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
                
                        <h2>Courses</h2>
                
                            <li class="product">    
                
                                <a href="<?php echo get_permalink( $loop->post->ID ) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>">
                
                                    <?php woocommerce_show_product_sale_flash( $post, $product ); ?>
                
                                    <?php if (has_post_thumbnail( $loop->post->ID )) echo get_the_post_thumbnail($loop->post->ID, 'shop_catalog'); else echo '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder" width="300px" height="300px" />'; ?>
                
                                    <h3><?php the_title(); ?></h3>
                
                                    <span class="price"><?php echo $product->get_price_html(); ?></span>                    
                
                                </a>
                
                                <?php woocommerce_template_loop_add_to_cart( $loop->post, $product ); ?>
                
                            </li>
                
                <?php endwhile; ?>
                <?php wp_reset_query(); ?>
            </ul>
        </div><!-- #content -->
    
    <?php get_footer(); ?>
    

    Steps:

    1. Go to your active theme create a new page like course-tpl.php
    2. Copy and paste the above code on your custom page course-tpl.php and change/replace category slug "clothing" to "your category slug" and save.
    3. Open dashboard – go to pages and "Add New" page enter a page title and assign "Courses template" and save
    4. Open new page
    5. Update/manage page CSS and HTML accordingly.
    Login or Signup to reply.
  2. Get products of specific product category (by category slug or id):

    I would like to update Rajeev Singh’s solution, especially the solution for displaying products of specific product categories.

    Problem:

    According to Woocommerce documentation WP_Query() or get_posts() should not be used:

    wc_get_products and WC_Product_Query provide a standard way of
    retrieving products that is safe to use and will not break due to
    database changes in future WooCommerce versions. Building custom
    WP_Queries or database queries is likely to break your code in future
    versions of WooCommerce as data moves towards custom tables for better
    performance. This is the best-practices way for plugin and theme
    developers to retrieve multiple products. wc_get_products and
    WC_Product_Query are similar to WordPress get_posts and WP_Query. Just
    like those, you pass in an array of arguments defining the criteria
    for the search.

    WooCommerce Docs

    Solution 1 – get products by category slug

    Note: category argument requires an array of slugs, not IDs.

    If you would like use the id of the product category on the specific category archive page check solution 2. How to get the ID of the current category from the category archive page template is not part of this solution.

     <?php
        $product_term_slugs = array('shirts');
        
        $product_args = array(
            'post_status' => 'publish',
            'limit' => -1,
            'category' => $product_term_slugs,
            //more options according to wc_get_products() docs
        );
        $products = wc_get_products($product_args);
       ?>
    

    Solution 2 – get products by category id:

     $product_term_ids = array(12);
        
        $product_term_args = array(
            'taxonomy' => 'product_cat',
            'include' => $product_term_ids,
            'orderby'  => 'include'
        );
        $product_terms = get_terms($product_term_args);
        
        $product_term_slugs = [];
        foreach ($product_terms as $product_term) {
            $product_term_slugs[] = $product_term->slug;
        }
        
        $product_args = array(
            'post_status' => 'publish',
            'limit' => -1,
            'category' => $product_term_slugs,
            //more options according to wc_get_products() docs
        );
        $products = wc_get_products($product_args);
      
    

    Solution – display products

    <?php 
    if(!empty($products):
    foreach ($products as $product):
     $product_id = $product->get_id();
     $product_type = $product->get_type();
     $product_title = $product->get_title();
     $product_permalink = $product->get_permalink();
     $product_regular_price = $product->get_regular_price();
     $product_sale_price = $product->get_sale_price();
     $product_short_desc = $product->get_short_description();
     $product_categories = $product->get_categories(); 
     ?>
     <!-- display product html -->
     <?php
    endif;
    endforeach;
     ?>
    

    (Tested and works with WordPress 5.9.3 & WooCommerce 6.4.1.)

    Credit: @Christian Lescuyer

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search