I am developing a theme, and I’m trying to add widgets programatically to its sidebar. I read this excellent answer:

https://wordpress.stackexchange.com/a/51086/14225

But there’s one thing I’m not clear on: where do you get the number you append to the widgets? (search-2, archives-3, etc.). For example, the default widgets on a fresh WP installed are initialized thus:

update_option( 'sidebars_widgets', array ( 'wp_inactive_widgets' => array (), 'sidebar-1' => array ( 0 => 'search-2', 1 => 'recent-posts-2', 2 => 'recent-comments-2', 3 => 'archives-2', 4 => 'categories-2', 5 => 'meta-2', ), 'array_version' => 3 ) );

Why search-2 and not search-1, for example? OTOH, the linked answer above just uses a $counter variable to give each widget in a sidebar a different number, starting with 1.

I realize all this is to avoid collisions between different instances of the same widget. What I don’t understand is at which level one is supposed to avoid them: between different widgets in the same sidebar? Different instances of the same widget, added to different themes? Different instances of the same widget in the same theme, but in different sidebars? What’s the best practice when generating numbers to avoid collisions?

1 Answer
1

Looking at the source code that WordPress uses to register widgets here, there’s a $number parameter defined, in line 242, as:

The unique order number of this widget instance compared to other instances of the same class.

The function _set($number) stores this ID number attached to the base identifier string of the widget.

Then, the function get_settings retrieves all configuration options for all the instances of the widget, in all sidebars. And when they are registered is when this $number part of the full widget ID is generated:

 public function _register() {
                $settings = $this->get_settings();
                $empty = true;

                if ( is_array($settings) ) {
                        foreach ( array_keys($settings) as $number ) {
                                if ( is_numeric($number) ) {
                                        $this->_set($number);
                                        $this->_register_one($number);
                                        $empty = false;
                                }
                        }
                }
[...]

In the register_one function, we find this:

integer $number Optional. The unique order number of this widget instance
compared to other instances of the same class.

So, the combination of the ID $number with the $id_base name has to be unique for all the instances of your widget, in any sidebar.

Leave a Reply

Your email address will not be published. Required fields are marked *