This post is the latest in the series on WooCommerce hooks. This series focuses on the hooks that developers could use in their WooCommerce projects for adjusting and/or enhancing the various features of their projects. This installment focuses on WooCommerce Widget actions.
WooCommerce actions allow developers to add or remove code to the core plugins. Using actions, developers could extend the functionalities of WooCommerce. The actions could be used to add conversion scripts to the checkout process, add information to the shop or product pages, add customized fields to orders, and act as triggers for specific events.
Here is a short list of WooCommerce Widget Actions:
- woocommerce_after_widget_product_list: The WordPress Core woocommerce after widget product list hook
Type: filter
if ( ( $products = $this->get_products( $args, $instance ) ) && $products->have_posts() ) { $this->widget_start( $args, $instance ); echo apply_filters( 'woocommerce_before_widget_product_list', '<ul class="product_list_widget">' ); while ( $products->have_posts() ) { $products->the_post(); wc_get_template( 'content-widget-product.php', array( 'show_rating' => false ) ); } echo apply_filters( 'woocommerce_after_widget_product_list', '</ul>' ); $this->widget_end( $args ); }
- woocommerce_before_widget_product_list : The WordPress Core woocommerce before widget product list
Type: filter
echo apply_filters( 'woocommerce_before_widget_product_list', '<ul class="product_list_widget">' );
- woocommerce_layered_nav_link : This function sets a global variable and selects taxonomy terms and the query.
Type: filter
if ( ! empty( $current_filter ) ) { $link = add_query_arg( $filter_name, implode( ',', $current_filter ), $link ); // Add Query type Arg to URL if ( $query_type === 'or' && ! ( 1 === sizeof( $current_filter ) && $option_is_set ) ) { $link = add_query_arg( 'query_type_' . sanitize_title( str_replace( 'pa_', '', $taxonomy ) ), 'or', $link ); } } echo '<li class="wc-layered-nav-term ' . ( $option_is_set ? 'chosen' : '' ) . '">'; echo ( $count > 0 || $option_is_set ) ? '<a href="' . esc_url( apply_filters( 'woocommerce_layered_nav_link', $link ) ) . '">' : '<span>'; echo esc_html( $term->name ); echo ( $count > 0 || $option_is_set ) ? '</a>' : '</span>'; echo ' <span class="count">(' . absint( $count ) . ')</span></li>';
- woocommerce_price_filter_meta_keys : Get filtered min price for current products.
Type: filter
$meta_query = new WP_Meta_Query( $meta_query ); $tax_query = new WP_Tax_Query( $tax_query ); $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); $sql = "SELECT min( CAST( price_meta.meta_value AS UNSIGNED ) ) as min_price, max( CAST( price_meta.meta_value AS UNSIGNED ) ) as max_price FROM {$wpdb->posts} "; $sql .= " LEFT JOIN {$wpdb->postmeta} as price_meta ON {$wpdb->posts}.ID = price_meta.post_id " . $tax_query_sql['join'] . $meta_query_sql['join']; $sql .= " WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish' AND price_meta.meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "') AND price_meta.meta_value > '' "; $sql .= $tax_query_sql['where'] . $meta_query_sql['where']; return $wpdb->get_row( $sql );
- woocommerce_price_filter_widget_max_amount : The WordPress Core woocommerce price filter widget max amount
Type: filter
echo '<form method="get" action="' . esc_url( $form_action ) . '"> <div class="price_slider_wrapper"> <div class="price_slider" style="display:none;"></div> <div class="price_slider_amount"> <input type="text" id="min_price" name="min_price" value="' . esc_attr( $min_price ) . '" data-min="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_min_amount', $min ) ) . '" placeholder="' . esc_attr__( 'Min price', 'woocommerce' ) . '" /> <input type="text" id="max_price" name="max_price" value="' . esc_attr( $max_price ) . '" data-max="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_max_amount', $max ) ) . '" placeholder="' . esc_attr__( 'Max price', 'woocommerce' ) . '" /> <button type="submit" class="button">' . __( 'Filter', 'woocommerce' ) . '</button> <div class="price_label" style="display:none;"> ' . __( 'Price:', 'woocommerce' ) . ' <span class="from"></span> — <span class="to"></span> </div> ' . $fields . ' <div class="clear"></div> </div> </div> </form>';
- woocommerce_price_filter_widget_min_amount :Define the woocommerce price filter widget  min amount callback
Type: filter
$list_args['walker'] = new WC_Product_Cat_List_Walker; $list_args['title_li'] = ''; $list_args['pad_counts'] = 1; $list_args['show_option_none'] = __('No product categories exist.', 'woocommerce' ); $list_args['current_category'] = ( $this->current_cat ) ? $this->current_cat->term_id : ''; $list_args['current_category_ancestors'] = $this->cat_ancestors; echo '<ul class="product-categories">'; wp_list_categories( apply_filters( 'woocommerce_product_categories_widget_args', $list_args ) ); echo '</ul>';
- woocommerce_product_categories_widget_args : The WordPress Core woocommerce product categories widget args hook
Type: filter
$list_args['walker'] = new WC_Product_Cat_List_Walker; $list_args['title_li'] = ''; $list_args['pad_counts'] = 1; $list_args['show_option_none'] = __('No product categories exist.', 'woocommerce' ); $list_args['current_category'] = ( $this->current_cat ) ? $this->current_cat->term_id : ''; $list_args['current_category_ancestors'] = $this->cat_ancestors; echo '<ul class="product-categories">'; wp_list_categories( apply_filters( 'woocommerce_product_categories_widget_args', $list_args ) ); echo '</ul>';
- woocommerce_product_categories_widget_dropdown_args : The WordPress Core woocommerce product categories widget dropdown args.
 Type: filter
if ( $dropdown ) { $dropdown_defaults = array( 'show_count' => $count, 'hierarchical' => $hierarchical, 'show_uncategorized' => 0, 'orderby' => $orderby, 'selected' => $this->current_cat ? $this->current_cat->slug : '' ); $dropdown_args = wp_parse_args( $dropdown_args, $dropdown_defaults ); // Stuck with this until a fix for https://core.trac.wordpress.org/ticket/13258 wc_product_dropdown_categories( apply_filters( 'woocommerce_product_categories_widget_dropdown_args', $dropdown_args ) ); wc_enqueue_js( " jQuery( '.dropdown_product_cat' ).change( function() { if ( jQuery(this).val() != '' ) { var this_page = ''; var home_url = '" . esc_js( home_url( '/' ) ) . "'; if ( home_url.indexOf( '?' ) > 0 ) { this_page = home_url + '&product_cat=' + jQuery(this).val(); } else { this_page = home_url + '?product_cat=' + jQuery(this).val(); } location.href = this_page; } }); " ); // List }
- woocommerce_product_categories_widget_product_terms_args : The WordPress Core woocommerce product categories widget product terms args hook
 Type: filter
$this->current_cat = false; $this->cat_ancestors = array(); if ( is_tax( 'product_cat' ) ) { $this->current_cat = $wp_query->queried_object; $this->cat_ancestors = get_ancestors( $this->current_cat->term_id, 'product_cat' ); } elseif ( is_singular( 'product' ) ) { $product_category = wc_get_product_terms( $post->ID, 'product_cat', apply_filters( 'woocommerce_product_categories_widget_product_terms_args', array( 'orderby' => 'parent' ) ) ); if ( ! empty( $product_category ) ) { $this->current_cat = end( $product_category ); $this->cat_ancestors = get_ancestors( $this->current_cat->term_id, 'product_cat' ); } }
- woocommerce_product_tag_cloud_widget_args: The WordPress Core woocommerce product tag cloud widget args hook
Type: filter
echo '<div class="tagcloud">'; wp_tag_cloud( apply_filters( 'woocommerce_product_tag_cloud_widget_args', array( 'taxonomy' => $current_taxonomy, 'topic_count_text_callback' => array( $this, '_topic_count_text' ), ) ) ); echo '</div>';
- woocommerce_products_widget_query_args : The WordPress Core woocommerce products widget query args hook
Type: filter
public function get_products( $args, $instance ) { $number = ! empty( $instance['number'] ) ? absint( $instance['number'] ) : $this->settings['number']['std']; $show = ! empty( $instance['show'] ) ? sanitize_title( $instance['show'] ) : $this->settings['show']['std']; $orderby = ! empty( $instance['orderby'] ) ? sanitize_title( $instance['orderby'] ) : $this->settings['orderby']['std']; $order = ! empty( $instance['order'] ) ? sanitize_title( $instance['order'] ) : $this->settings['order']['std']; $query_args = array( 'posts_per_page' => $number, 'post_status' => 'publish', 'post_type' => 'product', 'no_found_rows' => 1, 'order' => $order, 'meta_query' => array() ); if ( empty( $instance['show_hidden'] ) ) { $query_args['meta_query'][] = WC()->query->visibility_meta_query(); $query_args['post_parent'] = 0; } if ( ! empty( $instance['hide_free'] ) ) { $query_args['meta_query'][] = array( 'key' => '_price', 'value' => 0, 'compare' => '>', 'type' => 'DECIMAL', ); } $query_args['meta_query'][] = WC()->query->stock_status_meta_query(); $query_args['meta_query'] = array_filter( $query_args['meta_query'] ); switch ( $show ) { case 'featured' : $query_args['meta_query'][] = array( 'key' => '_featured', 'value' => 'yes' ); break; case 'onsale' : $product_ids_on_sale = wc_get_product_ids_on_sale(); $product_ids_on_sale[] = 0; $query_args['post__in'] = $product_ids_on_sale; break; } switch ( $orderby ) { case 'price' : $query_args['meta_key'] = '_price'; $query_args['orderby'] = 'meta_value_num'; break; case 'rand' : $query_args['orderby'] = 'rand'; break; case 'sales' : $query_args['meta_key'] = 'total_sales'; $query_args['orderby'] = 'meta_value_num'; break; default : $query_args['orderby'] = 'date'; } return new WP_Query( apply_filters( 'woocommerce_products_widget_query_args', $query_args ) ); }
- woocommerce_rating_filter_link : The WordPress Core woocommerce rating filter link hook
Type: filter
echo '<li class="wc-layered-nav-rating ' . ( ! empty( $_GET['min_rating'] ) && $rating === absint( $_GET['min_rating'] ) ? 'chosen' : '' ) . '">'; echo '<a href="' . esc_url( apply_filters( 'woocommerce_rating_filter_link', $link ) ) . '">'; echo '<span class="star-rating" title="' . esc_attr( sprintf( __( 'Rated %s and above', 'woocommerce' ), $rating ) ). '"> <span style="width:' . esc_attr( ( $rating / 5 ) * 100 ) . '%">' . sprintf( __( 'Rated %s and above', 'woocommerce'), $rating ) . '</span> </span> (' . esc_html( $count ) . ')'; echo '</a>'; echo '</li>';
- woocommerce_widget_cart_is_hidden : The WordPress Core woocommerce widget cart is hidden hook
Type: filter
public function widget( $args, $instance ) { if ( apply_filters( 'woocommerce_widget_cart_is_hidden', is_cart() || is_checkout() ) ) { return; } $hide_if_empty = empty( $instance['hide_if_empty'] ) ? 0 : 1; $this->widget_start( $args, $instance ); if ( $hide_if_empty ) { echo '<div class="hide_cart_widget_if_empty">'; } // Insert cart widget placeholder - code in woocommerce.js will update this on page load echo '<div class="widget_shopping_cart_content"></div>'; if ( $hide_if_empty ) { echo '</div>'; } $this->widget_end( $args ); }
Summary
In this article, I discussed the concept of WooCommerce widget hooks and how this concept is used in WooCommerce development. If you need further information about a specific hook or would like to extend the discussion, please leave a comment.
Owais Alam
is the WordPress Community Manager at Cloudways - A Managed WooCommerce Hosting Platform and a seasoned PHP developer. He loves to develop all sorts of websites on WordPress and is in love with WooCommerce in particular. You can email him at [email protected]