Skip to content

Instantly share code, notes, and snippets.

@bekarice
Last active April 17, 2020 12:10
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bekarice/f99d0d4ce1a33e9f77f2 to your computer and use it in GitHub Desktop.
Save bekarice/f99d0d4ce1a33e9f77f2 to your computer and use it in GitHub Desktop.
WooCommerce Upsells widget: Shows upsells in a widget on product pages, and removes the default upsell position when active
<?php
/**
* Plugin Name: WooCommerce Upsells Widget
* Plugin URI: https://www.skyverge.com/blog/moving-woocommerce-upsells-on-product-pages/
* Description: Adds a widget to display product upsells in a widget instead of below the product description
* Author: SkyVerge
* Author URI: https://www.skyverge.com/
* Version: 1.1.0
* Text Domain: woocommerce-upsells-widget
*
* Copyright: (c) 2016-2017 SkyVerge, Inc. (info@skyverge.com)
*
* License: GNU General Public License v3.0
* License URI: http://www.gnu.org/licenses/gpl-3.0.html
*
* @author SkyVerge
* @copyright Copyright (c) 2016-2017, SkyVerge, Inc.
* @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
*
*/
defined( 'ABSPATH' ) or exit;
/**
* A widget for displaying product upsells in a widget instead of on the product page
*
* @since 1.0.0
* @extends \WP_Widget
*/
class WC_Upsells_Widget extends WP_Widget {
/**
* Setup the widget options
*
* @since 1.0.0
*/
public function __construct() {
// remove product upsells from the page when this widget is used
add_action( 'wp', array( $this, 'remove_product_upsells' ) );
// adjust the display of upsells when used in the widget
add_action( 'wp_print_footer_scripts', array( $this, 'modify_product_upsells_styles' ) );
add_filter( 'woocommerce_upsell_display_args', array( $this, 'change_upsell_columns' ) );
// set widget options
$options = array(
'classname' => 'widget_wc_upsells',
'description' => __( 'Displays product upsells when on product pages.', 'woocommerce-upsells-widget' ),
);
// instantiate the widget
parent::__construct( 'WC_Upsells_Widget', __( 'WooCommerce upsells', 'woocommerce-upsells-widget' ), $options );
}
/**
* Render the widget
*
* @since 1.0.0
*
* @see WP_Widget::widget()
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
global $product;
// Only show this if we're looking at a product page
if ( ! is_singular( 'product' ) ) {
return;
}
// WC 3.0+ compat
$upsells = is_callable( array( $product, 'get_upsell_ids' ) ) ? $product->get_upsell_ids() : $product->get_upsells();
// bail if the product has no upsells before we output anything
if ( empty( $upsells ) ) {
return;
}
echo $args['before_widget'];
if ( $instance['title'] ) {
echo $args['before_title'] . wp_kses_post( $instance['title'] ) . $args['after_title'];
}
// Show the product's upsells
woocommerce_upsell_display();
echo $args['after_widget'];
}
/**
* Update the widget title
*
* @since 1.0
*
* @see WP_Widget::update()
* @param array $new_instance new widget settings
* @param array $old_instance old widget settings
* @return array updated widget settings
*/
public function update( $new_instance, $old_instance ) {
$instance['title'] = strip_tags( $new_instance['title'] );
return $instance;
}
/**
* Render the admin form for the widget
*
* @since 1.0.0
*
* @see WP_Widget::form()
* @param array $instance the widget settings
* @return string|void
*/
public function form( $instance ) {
?>
<p>
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php _e( 'Title', 'woocommerce-upsells-widget' ) ?>:</label>
<input type="text" class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" value="<?php echo esc_attr( isset( $instance['title'] ) ? $instance['title'] : '' ); ?>" />
</p>
<?php
}
/**
* Removes the product upsells from their current location on the product page
*
* @since 1.0.0
*/
public function remove_product_upsells() {
if ( is_singular( 'product' ) && is_active_widget( false, false, $this->id_base ) ) {
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_upsell_display', 15 );
}
}
/**
* Changes the number of upsell columns when displayed in the widget
*
* @since 1.0
* @param array $args arguments for upsell display
* @return array the updated arguments
*/
public function change_upsell_columns( $args ) {
if ( is_singular( 'product' ) && is_active_widget( false, false, $this->id_base ) ) {
$args['columns'] = 2;
}
return $args;
}
/**
* Add some specific CSS for the widget
*
* @since 1.0.0
*/
public function modify_product_upsells_styles() {
if ( is_singular( 'product' ) && is_active_widget( false, false, $this->id_base ) ) {
echo '<style>
.woocommerce .widget_wc_upsells ul.products li.product,
.woocommerce-page .widget_wc_upsells ul.products li.product {
width: 48%;
margin-top: 1em;
}
</style>';
}
}
}
/**
* Registers the new widget to add it to the available widgets
*
* @since 1.0.0
*/
function wc_upsells_register_widget() {
register_widget( 'WC_Upsells_Widget' );
}
add_action( 'widgets_init', 'wc_upsells_register_widget' );
@MURL1DHAR
Copy link

MURL1DHAR commented May 7, 2016

Hii,

I just added the file and activated the plugin. But it doesnt seem to show any upsell product. And it didnt even remove the original upsell product. Can you help me with it? I can post here the screenshot and other relevant info you would require to debug.

@Phil188
Copy link

Phil188 commented Apr 17, 2020

Hello Beka,

thanks for your help. There's still no comparable solution that teaches how to display upsells in the widget area.

I'm facing small problems on my product page.

Something went wrong with the columns.

Do you have some suggestions on what I could do?

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment