More Efficient Sidebars in WordPress, or the Lack Thereof
Friday, April 10th 2009Out-of-box, WordPress puts all its dynamic widgets in sidebar.php, which gets included in all templates throughout the site. If WordPress is acting as a CMS, however, just one sidebar.php for the whole site won't do. Since you'll be making your own widgets as well as creating layouts which use different sets of widgets at different times, you don't want to have to deal with countless WordPress if conditionals like "is_home" or "is_page," etcetera. In a CMS setup, the templates themselves are doing the work of conditionals. Instead of stuffing everything in sidebar.php, let's define each widget in a PHP switch statement in our functions.php. We can call individual widgets into our templates on demand by referencing get_widget( "name-of-widget" ); like so:
function get_widget($w) {
switch ($w) {
// YOUR WIDGET *************
case "name-of-widget" :
// do stuff
break;
// ANOTHER WIDGET *************
case "another-widget" :
// do stuff
break;
// FAILED CASE *************
default :
// do nothing
break;
}
}
The Markup
There are a number of ways you could mark up your widgets. If you intend to use a lot of built-in dynamic widgets from the WordPress Dashboard or plugins, then you'll likely want to mark up your widgets as list items in one unordered list. I'm not a fan of the whole giant unordered list, so I tend to mark up my widgets like so:
<div id="name-of-widget" class="widget"> <h4>Heading for Widget</h4> <!-- widget markup goes here --> </div>
Dynamic Sidebars
If you want to still be able to use dynamic sidebars, you can add multiple dynamic sidebars in your get_widget function as cases. First, you'll need to register each dynamic sidebar outside of the get_widget() function. So somewhere else in functions.php, add:
register_sidebar(array('name'=>'my-dynamic-widgets',
'before_widget' => '<div class="widget">',
'after_widget' => '</div>',
'before_title' => '<h4>',
'after_title' => '</h4>',
));
By registering "my-dynamic-widgets" in functions.php, you'll be able to add widgets to the "my-dynamic-widgets" sidebar within the Dashboard. Now, all you need to do is reference your newly registered dynamic sidebar in our get_widget function:
// YOUR WIDGET *************
case "my-dynamic-widgets" :
if ( !function_exists('dynamic_sidebar') ||
!dynamic_sidebar('my_dynamic_widgets') ) :
endif;
break;
And of course, you can add as many additional dynamic sidebars as you want, in different cases. I've found that doing away with the sidebar.php template in this way saves a lot of time in constructing templates, because now I can have a set of different widgets for each of my single posts and page templates.

Wow, this sounds very cool... but I feel like I'm missing something.
How does a widget show up on one page, but not another? What's calling a particular widget to render on a particular page, if not conditional statements in sidebar.php?
In your page template (or any template where you'd like a particular widget to appear), you call get_widget("name-of-widget"). In most of my themes, on generic pages I usually have the same set of widgets, so no conditionals are needed.
For example, on this website, I call a different set of widgets in the 404 template than I do in the page template, and a different set in the homepage template than my "About" page template. There's no need to load sidebar at all, because I call widgets directly from the functions file.
Brilliant; I totally get it now.
I was thinking of having certain sets of widgets on certain pages, which would require conditionals (I have a client that needing a lot of conditionals, so I'm on the lookout for a better solution).
But, in your application (as well as my own site), it makes perfect sense. Thanks again.