Skip to content

Instantly share code, notes, and snippets.

@tyxla
Created August 24, 2016 10:43
Show Gist options
  • Save tyxla/372f51ea1340e5e643f6b47e2ddf43f2 to your computer and use it in GitHub Desktop.
Save tyxla/372f51ea1340e5e643f6b47e2ddf43f2 to your computer and use it in GitHub Desktop.
Insert a widget in a sidebar programmatically in WordPress
<?php
/**
* Insert a widget in a sidebar.
*
* @param string $widget_id ID of the widget (search, recent-posts, etc.)
* @param array $widget_data Widget settings.
* @param string $sidebar ID of the sidebar.
*/
function insert_widget_in_sidebar( $widget_id, $widget_data, $sidebar ) {
// Retrieve sidebars, widgets and their instances
$sidebars_widgets = get_option( 'sidebars_widgets', array() );
$widget_instances = get_option( 'widget_' . $widget_id, array() );
// Retrieve the key of the next widget instance
$numeric_keys = array_filter( array_keys( $widget_instances ), 'is_int' );
$next_key = $numeric_keys ? max( $numeric_keys ) + 1 : 2;
// Add this widget to the sidebar
if ( ! isset( $sidebars_widgets[ $sidebar ] ) ) {
$sidebars_widgets[ $sidebar ] = array();
}
$sidebars_widgets[ $sidebar ][] = $widget_id . '-' . $next_key;
// Add the new widget instance
$widget_instances[ $next_key ] = $widget_data;
// Store updated sidebars, widgets and their instances
update_option( 'sidebars_widgets', $sidebars_widgets );
update_option( 'widget_' . $widget_id, $widget_instances );
}
@woodwardmatt
Copy link

Works a treat, thanks for sharing! 👍

@davebonds
Copy link

Very helpful! Thank you!

@freesouldesign
Copy link

Perfect! Thank you!

@MTphilclothier
Copy link

Works great, thanks!

@dameer
Copy link

dameer commented Dec 25, 2018

It keeps doubling widgets on 'after_switch_theme' action so it's not quite useful when certain widget needs to be added upon theme activation.

@hkujla
Copy link

hkujla commented Apr 12, 2020

You saved my day, Perfect solution. Thanks. I would like to share to avoid widget duplication.


if (!is_active_widget( false, $widget-id, $obj->id_base, true ) ) {
insert_widget_in_sidebar( $widget_id, $widget_data, $sidebar );
} else {
widget_update_by_subsite($widget_id,$new);
}

function widget_update_by_subsite($widget_id,$new) {

	$widget_id = 'widget_'.$widget_id;
	$widget_data = get_option($widget_id);
	
	if(!empty($widget_data) && array_key_exists($widget_number,$widget_data)) {

		$widget_data[$widget_number]=$new;

	} else {

		$widget_data[$widget_number]=$new;
	}
	
	$res = update_option( $widget_id, $widget_data);
	if($res) {
		return true;
	} 
	return false;			    
    }

@tyxla
Copy link
Author

tyxla commented Apr 13, 2020

Nice, thanks @hkujla!

@davidfcarr
Copy link

Thank you. I've probably been trying to figure this out for a year.

@seowner
Copy link

seowner commented May 1, 2022

Sadly this code no longer works in php 7.4, any way to get an update @tyxla?

@tyxla
Copy link
Author

tyxla commented May 2, 2022

Happy to update it @seowner! Could you share some more information about the error you are getting on PHP 7.4?

@seowner
Copy link

seowner commented May 4, 2022

@tyxla I was able to fix it (to meet my own specifications) by doing this:

if ( !isset( $sidebars_widgets[$sidebar] ) ) {
    $sidebars_widgets = array();
    $sidebars_widgets[$sidebar] = array();
}
$sidebars_widgets[$sidebar][] = $widget_id . '-' . '1';

// Add the new widget instance
$widget_instances = array();
$widget_instances[1] = $widget_data;

It seems the main problem was PHP 7.4 will not allow you to use [] to initialize arrays without first initializing them with array().

Although this code isn't the same as yours above, I hope it makes things faster for you!

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