Hacking Off

20% Time All the Time

Hacking Conditional Sidebars Into the _s (Underscores) WordPress Theme

Wrote a guide, as the process seemed mildly convoluted.

Here’s how to modify the _s (“underscores”) WordPress theme to support different sidebars that trigger depending on the page being viewed. There are plug-ins for this, but some of them are shady or just break the UI.

(E.g., Custom Sidebars notably made it impossible for me to save widget content, because its donation bar’s shitty CSS prevents users from being able to scroll far enough down to hit the button. Good times!)

Anyway, here’s the run down:

Overview

  1. Edit your functions.php to register more sidebars.

  2. Edit your sidebar.php file to throw in conditionals to determine how you invoke dynamic_sidebar().

  3. Edit the corresponding widgets.

Edit your functions.php to register more sidebars.

functions.php (original from _s)
1
2
3
4
5
6
7
8
9
10
_s's functions.php file initially contains the following:
function themenamegoeshere_widgets_init() {
  register_sidebar( array(
    'name' => __( 'Sidebar', 'themenamegoeshere' ),
    'id' => 'sidebar-1',
    'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    'after_widget' => '</aside>',
    'before_title' => '<h1 class="widget-title">',
    'after_title' => '</h1>',
  ) );

Registering additional sidebars in functions.php is pretty straightforward. Here’s an example of how to register a second sidebar with a semantically meaningful name.

functions.php (modified)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Relevant API documentation:
// http://codex.wordpress.org/Function_Reference/register_sidebars
function themenamegoeshere_widgets_init() {
  register_sidebar( array(
    'name' => __( 'Sidebar', 'themenamegoeshere' ),
    'id' => 'sidebar-1',
    'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    'after_widget' => '</aside>',
    'before_title' => '<h1 class="widget-title">',
    'after_title' => '</h1>',
  ) );
  register_sidebar( array(
    'name' => __( 'Page-Sidebar', 'themenamegoeshere' ),
    'id' => 'sidebar-page',
    'before_widget' => '<aside id="%1$s" class="widget %2$s">',
    'after_widget' => '</aside>',
    'before_title' => '<h1 class="widget-title">',
    'after_title' => '</h1>',
  ) );
}

I was initially tempted to use register_sidebars() instead, but it would lead to a bunch of sidebars named by number (e.g., sidebar-1, sidebar-2, etc.) which would be a maintenance hazard in that the names would lack any sort of semantic meaning, forcing you to look things up. A stitch in time, and all that jazz.

Edit your sidebar.php file to throw in conditionals to determine how you invoke dynamic_sidebar().

sidebar.php (original from _s)
1
2
3
<?php if ( ! dynamic_sidebar( 'sidebar-1' ) ) : ?>
  // ...
<?php endif; // end sidebar widget area ?>

Brief note for the uninitiated: that hideous ‘: … endif’ pairing is a PHP-idiomatic replacement for everyday curly-braces {} when the stuff between braces would have otherwise contained embedded HTML. (Yuck.)

sidebar.php (modified)
1
2
3
4
5
6
7
8
9
// Suppose you want one sidebar for pages and another for absolutely everything else.
if (is_page()) {
  $no_sidebar = !dynamic_sidebar('sidebar-page'); // Attempt showing page sidebar
} else {
  $no_sidebar = !dynamic_sidebar('sidebar-1'); // Fall back to showing generic sidebar
}
if $no_sidebar { ?>
  ...
<?php } ?>

The key here is nesting ifs (or using a case statement) to intelligently exploit WordPress’s conditional tags to only show a sidebar appropriate to the type of content being displayed. Said tags can be used to differentiate between pages, the blog index, categort pages, and so on, all the way down to even the individual post level. You’ve got a lot of control.

Warning

Be really cautious, here. Using things that otherwise seem they’d make sense can blow up in your face. Notably, using !dynamic_sidebar(‘sidebar-a’) || !dynamic_sidebar(‘sidebar-b’) will behave unexpectedly. Swapping &&, in the previous statement, for || does too.

Edit the corresponding widgets.

Open the WordPress admin panel. Appearance -> Widgets has a pretty obvious interface that will let you set up what gets displayed in each widget.

Bam! A little hand-waving later, and you’re good to go.