skip to Main Content

I want to display only a specific variation of all my products on a page using a shortcode. In my example, I want to display all the variation products with the attribute "color" and the term "blue" as single product.

Here’s my code:


function filterVariations() {
    $query = new WP_Query( 
        array(
        'post_parent' => '', 
        'post_status' => 'publish',
        'post_type' => 'product_variation',
        'posts_per_page' => -1,
        'meta_query' => 
            array( 
                array(
                'key' => 'attribute_pa_color',
                'value' => 'blue',
                ) 
            ),
        ) 
    );
    
    $result = array();
    if($query->have_posts()){
        while ($query->have_posts()) {
            $query->next_post();
            $result[] = $query->post;
        }
        wp_reset_postdata();
    }
    wp_reset_query();

    return $result;
}


function custom_variations_shortcode() {
    ob_start(); 
    
    $variations = filterVariations(); 
    if (!empty($variations)) {
        
    // Set loop properties
    //wc_set_loop_prop('columns', 3);
        
    echo '<div class="woocommerce">';
        woocommerce_product_loop_start();    
        
        foreach ($variations as $variation) {       
           setup_postdata($variation); 
           wc_get_template_part('content', 'product');                  
        }
        
        woocommerce_product_loop_end(); 
    echo '</div>';
        
        wp_reset_postdata();
        
    } else {
        echo 'No variations found.';
    }
    return ob_get_clean();
}
add_shortcode('custom_variations', 'custom_variations_shortcode');

Here come the problems:

  • The displayed products all have the page title as the product title, which is linked to the same page
  • The woocommerce styles are not correctly applied (eg. texts are not centered, etc.)
  • The ‘add to cart’ button link is more articulated than necessary: http://localhost/mysite-local/wordpress/books/book-title/?attribute_pa_color=blue&variation_id=188&add-to-cart=186

I think that the main culprit could be this part
wc_get_template_part('content', 'product');
but I cannot find a way to probarly fix this.

Is this the correct approach for displaying variation products as single product on a page or are there better solutions?

2

Answers


  1. You don’t need a shortcode for a custom loop in a template however you should include the default shop loop action hooks which you can find in archive-product.php and markup using wc_get_template_part( 'content', 'product' );

    Something like this :

    $products = new WP_Query(
        array(
            'post_type'  => array( 'product_variation' ),
            'meta_query' => array(
                array(
                    'key' => 'attribute_pa_color',
                    'value' => 'blue',
                )
            ),
        )
    );
    
    while( $products->have_posts() ) : 
           $products->the_post();
    wc_get_template_part( 'content', 'product' );       
    endwhile;
    
    Login or Signup to reply.
  2. The rule on stack overflow is one problem at the time, so I will answer here your first problem around the product variation title:

    The following code will replace the product title, for product type "variation", with the correct title to be displayed:

    add_action('woocommerce_shop_loop_item_title', 'adjust_shop_loop_item_title', 5 );
    function adjust_shop_loop_item_title() {
        global $product;
    
        if ( $product->is_type('variation') ) {
            remove_action('woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10 );
            add_action('woocommerce_shop_loop_item_title', 'woocommerce_template_loop_variation_title', 10 );
        }
    }
    
    function woocommerce_template_loop_variation_title() {
        global $product;
    
        echo '<h2 class="' . esc_attr( apply_filters( 'woocommerce_product_loop_title_classes', 'woocommerce-loop-product__title' ) ) . '">' . $product->get_name() . '</h2>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested Storefront theme and work on most themes.

    Some themes already made changes to products and enable sometimes custom hooks. In that case, if the code doesn’t work, you will need to search in the main theme files for woocommerce_shop_loop_item_title to find out what are those changes, and how to manage making the required changes to my code, to make it work.


    I have tested your code in a new page, pasting [custom_variations] shortcode in the editor, and I don’t have any styling problems or glitches.

    For the variation add to cart link, is completely normal and Ajax add to cart works nicely.

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