In this tutorial I’m showing how to create a WordPress widget. Widget we will create allows you to add to the sidebar a list of products from chosen category. It works with Woocommerce – e-commerce WordPress plugin.
Good practice is to make your WordPress widget as a plugin. So you have to create widget-name.php file under wp-content/plugins directory and at the beginning of it add specific comment text. This text is required by WordPress to show your plugin in Plugins tab in admin panel.
<?php /* Plugin Name: Products from chosen category Description: Display a list of products from chosen category. Author: Anna Kolm Version: 1.0 Author URI: http://annakolm.pl */ ?>
Then we extend WordPress standard widgets list with our widget by adding to this file following command:
class products_from_category extends WP_Widget {}
So far we have added a widget that is empty. Let’s give it some live.
First we define the widget:
function products_from_category() { /* Widget variable settings. */ $this->pfc_widget_cssclass = 'woocommerce widget_products_from_category'; $this->pfc_widget_description = __('Display a list of products from chosen category.', 'translationreference'); $this->pfc_widget_idbase = 'products_from_category'; $this->pfc_widget_name = __('Products from chosen category', 'translationreference'); /* Widget settings. */ $widget_ops = array('classname' => $this->pfc_widget_cssclass, 'description' => $this->pfc_widget_description); /* Create the widget. */ $this->WP_Widget('products_from_category', $this->pfc_widget_name, $widget_ops); }
Next we use form function to define how our widget will look like in the admin panel after adding it to a sidebar:
function form($instance) { $instance = wp_parse_args((array) $instance, array('title' => '', 'category' => '', 'number' => 3)); $title = $instance['title']; $category = $instance['category']; $number = $instance['number']; $args = array( 'orderby' => 'name', 'order' => ASC, 'hide_empty' => true, ); $product_categories = get_terms('product_cat', $args); ?> <p><label for="<?php echo $this->get_field_id('title'); ?>">Title: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p> <p><label for="<?php echo $this->get_field_id('category'); ?>"><?php _e('Category:', 'woocommerce') ?></label> <select id="<?php echo esc_attr($this->get_field_id('category')); ?>" name="<?php echo esc_attr($this->get_field_name('category')); ?>"> <?php if ($product_categories) { foreach ($product_categories as $cat) { echo '<option value="' . $cat->name . '" ' . selected(($instance['category'] == $cat->name), true, false) . '>' . $cat->name . '</option>'; } } ?> </select> </p> <p><label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('Number of products to show:', 'woocommerce'); ?></label> <input id="<?php echo esc_attr($this->get_field_id('number')); ?>" name="<?php echo esc_attr($this->get_field_name('number')); ?>" type="text" value="<?php echo esc_attr($number); ?>" size="3" /></p> <?php }
We have to ensure that data insert in the form will be updated and saved:
function update($new_instance, $old_instance) { $instance = $old_instance; $instance['title'] = $new_instance['title']; $instance['category'] = $new_instance['category']; $instance['number'] = (int) $new_instance['number']; return $instance; }
Next we have to show the list of products from chosen category in frontend:
function widget($args, $instance) { extract($args, EXTR_SKIP); $title = $instance['title']; $category = $instance['category']; $number = $instance['number']; $query_args = array( 'product_cat' => $category, 'posts_per_page' => $number, ); $r = new WP_Query($query_args); if ($r->have_posts()) : ?> <?php echo $before_widget; ?> <?php if ($title) echo $before_title . $title . $after_title; ?> <ul class="product_list_widget"> <?php while ($r->have_posts()) : $r->the_post(); global $product; ?> <li><a href="<?php echo esc_url(get_permalink($r->post->ID)); ?>" title="<?php echo esc_attr($r->post->post_title ? $r->post->post_title : $r->post->ID); ?>"> <?php echo $product->get_image(); ?> <?php if ($r->post->post_title) echo get_the_title($r->post->ID); else echo $r->post->ID; ?> </a> <?php echo $product->get_price_html(); ?></li> <?php endwhile; ?> </ul> <?php echo $after_widget; ?> <?php endif; }
At last we register the widget using widgets_init hook:
add_action('widgets_init', create_function('', 'return register_widget("products_from_category");'));
Full content of widget-name.php file:
<?php /* Plugin Name: Products from chosen category Description: Display a list of products from chosen category. Author: Anna Kolm Version: 1.0 Author URI: http://annakolm.pl */ class products_from_category extends WP_Widget { function products_from_category() { /* Widget variable settings. */ $this->pfc_cssclass = 'woocommerce widget_products_from_category'; $this->pfc_widget_description = __('Display a list of products from chosen category.', 'translationreference'); $this->pfc_widget_idbase = 'products_from_category'; $this->pfc_widget_name = __('Products from chosen category', 'translationreference'); /* Widget settings. */ $widget_ops = array('classname' => $this->pfc_widget_cssclass, 'description' => $this->pfc_widget_description); /* Create the widget. */ $this->WP_Widget('products_from_category', $this->pfc_widget_name, $widget_ops); } function form($instance) { $instance = wp_parse_args((array) $instance, array('title' => '', 'category' => '', 'number' => 3)); $title = $instance['title']; $category = $instance['category']; $number = $instance['number']; $args = array( 'orderby' => 'name', 'order' => ASC, 'hide_empty' => true, ); $product_categories = get_terms('product_cat', $args); ?> <p><label for="<?php echo $this->get_field_id('title'); ?>">Title: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p> <p><label for="<?php echo $this->get_field_id('category'); ?>"><?php _e('Category:', 'woocommerce') ?></label> <select id="<?php echo esc_attr($this->get_field_id('category')); ?>" name="<?php echo esc_attr($this->get_field_name('category')); ?>"> <?php if ($product_categories) { foreach ($product_categories as $cat) { echo '<option value="' . $cat->name . '" ' . selected(($instance['category'] == $cat->name), true, false) . '>' . $cat->name . '</option>'; } } ?> </select> </p> <p><label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('Number of products to show:', 'woocommerce'); ?></label> <input id="<?php echo esc_attr($this->get_field_id('number')); ?>" name="<?php echo esc_attr($this->get_field_name('number')); ?>" type="text" value="<?php echo esc_attr($number); ?>" size="3" /></p> <?php } function update($new_instance, $old_instance) { $instance = $old_instance; $instance['title'] = $new_instance['title']; $instance['category'] = $new_instance['category']; $instance['number'] = (int) $new_instance['number']; return $instance; } function widget($args, $instance) { extract($args, EXTR_SKIP); $title = $instance['title']; $category = $instance['category']; $number = $instance['number']; $query_args = array( 'product_cat' => $category, 'posts_per_page' => $number, ); $r = new WP_Query($query_args); if ($r->have_posts()) : ?> <?php echo $before_widget; ?> <?php if ($title) echo $before_title . $title . $after_title; ?> <ul class="product_list_widget"> <?php while ($r->have_posts()) : $r->the_post(); global $product; ?> <li><a href="<?php echo esc_url(get_permalink($r->post->ID)); ?>" title="<?php echo esc_attr($r->post->post_title ? $r->post->post_title : $r->post->ID); ?>"> <?php echo $product->get_image(); ?> <?php if ($r->post->post_title) echo get_the_title($r->post->ID); else echo $r->post->ID; ?> </a> <?php echo $product->get_price_html(); ?></li> <?php endwhile; ?> </ul> <?php echo $after_widget; ?> <?php endif; } } add_action('widgets_init', create_function('', 'return register_widget("products_from_category");')); ?>