[wp-hackers] Sidebar ID Naming Problems

Charles K. Clarkson cclarkson at htcomp.net
Sun Nov 15 05:02:56 UTC 2009


This went a little long. There were a lot more problems than I anticipated. So,
I moved the question to the top.

How should I proceed?

     Write a patch for a new function that gets the sidebar id from a name-or-id
     input or an array where the name or id is specified? (Which would entail
     patching other functions [3] in /wp-includes/widgets.php.)

     - OR -

     Rewrite the documentation to reflect the problems with some edge cases of id

     - OR -

     Something else?

register_sidebar() allows more names and ids to be registered than
dynamic_sidebar() recognizes as valid names and ids.

For example, register_sidebar() allows me to name a side bar "1" with a id of
"first". I don't know why anyone would choose those values, but
register_sidebar() allows it [1].

register_sidebar( array('name' => 1, id => 'first') );

dynamic_sidebar() will not be able to find the sidebar given its name (1).

     if ( is_int($index) ) {
         $index = "sidebar-$index"; /// 1 becomes 'sidebar-1'

The main problem is that dynamic_sidebar() is trying to process both ids and
names through the same variable ($index) while register_sidebar() separates the
two with an array ( array('name' => 'Top', 'id' => 'sidebar-1' ).

According to the in-line docs for dynamic_sidebar():

     It is confusing for the $index parameter, but just know that it should just
     work. When you register the sidebar in the theme, you will use the same name
     for this function or "Pay no heed to the man behind the curtain." Just
     accept it as an oddity of WordPress sidebar register and display.

It does "just work" if you never use your own sidebar ids.

I started looking at this because I wanted to use is_active_sidebar() which
tests to see if a dynamic_sidebar() has anything in it. There is no
get_dynamic_sidebar(). dynamic_sidebar() sends everything to the browser or
returns false.

     register_sidebar( array('name' => 'Top') ); // id defaults to "sidebar-1"

     if ( is_active_sidebar('Top') )

Which fails because is_active_sidebar() just completely skips over searching for
an id to go with a name. To get it to work you need to know when it was
registered. Not something theme authors and designers are going to follow
easily. There's a ticket to fix this: http://core.trac.wordpress.org/ticket/10440

     if ( is_active_sidebar(1) )

Like dynamic_sidebar(), is_active_sidebar() converts 1 to "sidebar-1". Unlike
dynamic_sidebar() it assumes everything is entered as an id.

unregister_sidebar() assumes its parameter (incorrectly named $name, not $id) is
an id. But it wants a literal id, like "sidebar-1". unregister_sidebar(1)
unregisters a sidebar with an id of 1, while dynamic_sidebar(1) tries to display
a sidebar with an id of "sidebar-1".

Wait. There's more.

The dynamic_sidebar() function is used by the Widgets management page. So, it is
possible to create a sidebar with register_sidebar() that dynamic_sidebar()
cannot find. You can populate it with drag and drop [2] and not have it appear
on the web site.

[1] register_sidebar() allows the user to override the default setting of:
     'id' => "sidebar-$i",

[2] When you refresh the Widgets management page the widgets will disappear from
     the sidebar. They are still attached to a sidebar, but dynamic_sidebar()
     cannot see the sidebar.

[3] Depending on the exact solution used, this might include patching these

     And creating this one:


Charles Clarkson
Mobile Home Investor
Free Market Advocate

I'm not really a smart person. I just play one on the Internet.

Stephenville, TX
+1 (254) 968-8328

More information about the wp-hackers mailing list