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");'));
?>