Michele
Michele

Reputation: 47

Display specific variation products as individual products on a new page using a shortcode in Woocommerce

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:

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?

Upvotes: 2

Views: 1080

Answers (2)

LoicTheAztec
LoicTheAztec

Reputation: 254362

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.

Upvotes: 1

user2589071
user2589071

Reputation:

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;

Upvotes: 0

Related Questions