WordPress Customizer widget instance

On the WordPress admin widgets page there is a known issue with the widget form not being available the first time a widget is added to a widget area. This can be seen in this trac ticket here: https://core.trac.wordpress.org/ticket/14686.

A solution to that can be found here.

However, as of WordPress 3.4, an API – Theme Customization was added that allows developers to customize and add controls to the “Appearance” → “Customize” admin screen. The Theme Customization screen (i.e. “Theme Customizer”) allows site admins to tweak a theme’s settings, color scheme or widgets, and see a preview of those changes in real time.

The same problem occurs to these widgets in Customizer screen. The instance of the widget object is not available for the first time you add a widget.

The problem can be reproduced following these instructions. Please make sure your theme supports widgets.

First, copy paste this code to funtions.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class test_widget extends WP_Widget{
  function test_widget(){
    $this->WP_Widget(false, 'Widget Instance Test');
  }
 
  function widget($args, $instance){
    echo 'front-end';
  }
 
  function form($instance){
    print_r($this);
  }
}
add_action('widgets_init', create_function('', 'register_widget("test_widget");'));

Then go to “Appearance” → “Customize” → “Widgets”. Then locate “Widget Instance Test” and add to any widget area.
You will get something like this image below labeled as unsaved.

widget instance test

sample object output…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
test_widget Object
(
    [id_base] => test_widget
    [name] => Widget Instance Test
    [widget_options] => Array
        (
            [classname] => widget_test_widget
        )
 
    [control_options] => Array
        (
            [id_base] => test_widget
        )
 
    [number] => __i__
    [id] => test_widget-__i__
    [updated] => 
    [option_name] => widget_test_widget
)

There are values not available…

But when you hit “Save and Publish” button and do a page reload, you’ll get the instance of the widget. We certainly DON’T want that kind of behavior. We don’t want to save it just to get the instance.

Luckily, I found a fixed to this. Thanks to David Gwyer for following me up in this problem.
We can create a plugin with these files below..

for php:

1
2
3
4
function reigelgallarde_load_widgets_script() {
    wp_enqueue_script( 'admin_widget_bug_fix', plugins_url( 'widget-bug-fix.js', __FILE__ ), array( 'jquery' ) );
}
add_action( 'customize_controls_print_scripts', 'reigelgallarde_load_widgets_script' );

where widget-bug-fix.js is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
jQuery(document).ready( function($) {
 
	$( document ).on( 'widget-added', function(event, widget) {
 
		var $saveBtn = $(widget).find('.widget-control-save');
		// let's check if the control for this widget is ready... 
		if ($saveBtn.closest('.control-section').is(':visible')) {
			// if the control for this widget is ready, let's hit apply...
			$saveBtn.click();
		}
	});
 
        // update the content of the widget....
	$( document ).on( 'widget-synced', function(e,widget ,form) {
		var _widget = $('#' + widget[0].id);
		if (_widget.data('synced') != true) {
			_widget.find('.widget-content').html(form);
			_widget.data('synced', true);	
		}
	});
 
});

or you could just download the files here…

https://github.com/reigelgallarde/wp-plugins/tree/master/customizer-widget-bug-fix

With this fixed, the instance is available same as you are hitting “Save and Publish” button. But the difference is that the widget will not be saved. The user will need to hit Save and Publish button to permanently save the widget in the theme.

If you have any concerns, feel free to reach me through comments below.

You may also like...