On a custom page I output products from a category using wp_query. How can I output a list of attributes and their number from these products for further filtering?
Size (pa_size) (radio or checkboxs)
-S (2)
-M (1)
Color (pa_color) (radio or checkboxs)
-Red (15)
-Blue (4)
...
wp_query products:
$query = new WP_Query($args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => 41,
),
),
));
?>
<div class="products">
<?php
if ($query->have_posts()) :
while ($query->have_posts()) :
$query->the_post();
wc_get_template_part('content', 'product-list');
endwhile;
wp_reset_postdata();
endif;
?>
</div>
For example get_terms("pa_size");
shows all attributes. WC Filters on custom page do not work. I know how to filter further by attributes, but I don’t know how to get a list of attributes from these products.
You can use the following custom utilities function to get product attributes from a WP_Query and display radio buttons for each product attribute terms:
function get_product_attributes_from_query( $query ){
global $wpdb;
$post_ids = implode(',', array_column( (array) $query->posts, 'ID', false) );
return $wpdb->get_results("
SELECT t.term_id, t.name, t.slug, tt.taxonomy, tt.count
FROM {$wpdb->prefix}term_relationships as tr
JOIN {$wpdb->prefix}term_taxonomy as tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN {$wpdb->prefix}terms as t ON tt.term_id = t.term_id
WHERE tt.taxonomy LIKE 'pa_%' AND tr.object_id IN ( {$post_ids} )
GROUP BY t.term_id ORDER BY tt.taxonomy
" );
}
function display_related_product_attributes_radio_buttons( $query ) {
if ( $query->have_posts() ) {
echo ' <div class="attributes-radios">';
if ( $results = get_product_attributes_from_query( $query ) ) {
$terms_by_taxonomy = array(); // Initializing
// Loop through attributes
foreach ( $results as $result ) {
// Group by attribute taxonomy
$terms_by_taxonomy[$result->taxonomy][$result->term_id] = $result;
}
// Loop through grouped attributes by taxonomy
foreach ( $terms_by_taxonomy as $taxonomy => $terms ) {
printf('<p class="form-row" id="%s_field"><label for="%s"><strong>%s:</strong></label>
<span class="woocommerce-input-wrapper">',
$taxonomy, $taxonomy, wc_attribute_label($taxonomy) );
// Loop through terms from the current taxonomy
foreach ( $terms as $term_id => $term ) {
printf('<label for="%s_%s" class="radio">
<input type="radio" class="input-radio" value="%s" name="%s" id="%s_%s"> <span>%s (%s)</span></label>', $term->slug, $taxonomy,
$taxonomy, $term->slug, $taxonomy, $term->slug, $term->name, $term->count );
}
echo '</span></p>';
}
}
echo '</div>';
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
USAGE: Then you can use it in your code like:
$query = new WP_Query($args = array(
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'terms' => 41,
),
),
));
// Here we insert the function for example
display_related_product_attributes_radio_buttons( $query );
?>
<div class="products">
<?php
if ($query->have_posts()) :
while ($query->have_posts()) :
$query->the_post();
wc_get_template_part('content', 'product-list');
endwhile;
wp_reset_postdata();
endif;
?>
</div>
You will get something like: