Advertisement
Theme Development

How to Use Custom Sidebars on Posts and Pages

by

Today I'd like to show you how to easily add custom sidebars to use within your posts and pages. It could be useful to display different widgets according to your page or post's topic.

We'll see how to use WordPress meta boxes to store and retrieve a chosen sidebar for a specific post. Custom sidebars will be added in the theme options section.


Introduction

I used to deal with the great widget logic plugin to display various widgets on different pages, but the widgets page became very fuzzy and difficult to maintain. So why not use several sidebars and choose which one to display on a specific post? That's what I'll cover in this tutorial.


Step 1 Adding Sidebars in the Theme Options Page (Twenty Eleven)

In this tutorial, I'll use the great WordPress default theme Twenty Eleven to demonstrate how to use custom sidebars in your theme.

First, we are going to add a new setting in Appearance -> Theme options. You can refer to this great tutorial to see how to add settings.

Open the theme-options.php file, located in twentyeleven/inc and add this code at the end of the twentyeleven_theme_options_init() function:

add_settings_field( 'custom_sidebar', __( 'Custom sidebars', 'twentyeleven' ), 'twentyeleven_settings_field_custom_sidebar', 'theme_options', 'general' );

Then add a default value (an empty array) to the default theme options values, at the end of the twentyeleven_get_default_theme_options() function:

$default_theme_options = array(
	'color_scheme' => 'light',
	'link_color'   => twentyeleven_get_default_link_color( 'light' ),
	'theme_layout' => 'content-sidebar',
	'custom_sidebar' => array()
);

Now we are going to create the callback function that handles the setting's display.

Let's add some jQuery to handle interactions such as adding and removing sidebars, which are basically some list elements containing a hidden input. We'll also generate those list elements from already saved sidebars.

function twentyeleven_settings_field_custom_sidebar()
{
	// Retrieve theme options
	$opts = twentyeleven_get_theme_options();

	// A bit of jQuery to handle interactions (add / remove sidebars)
	$output = "<script type='text/javascript'>";
	$output .= '
				var $ = jQuery;
				$(document).ready(function(){
					$(".sidebar_management").on("click", ".delete", function(){
						$(this).parent().remove();
					});
					
					$("#add_sidebar").click(function(){
						$(".sidebar_management ul").append("<li>"+$("#new_sidebar_name").val()+" <a href=\'#\' class=\'delete\'>'.__("delete", $themename).'</a> <input type=\'hidden\' name=\'twentyeleven_theme_options[custom_sidebar][]\' value=\'"+$("#new_sidebar_name").val()+"\' /></li>");
						$("#new_sidebar_name").val("");
					})
					
				})
	';
	
	$output .= "</script>";

	$output .= "<div class='sidebar_management'>";
	
	$output .= "<p><input type='text' id='new_sidebar_name' /> <input class='button-primary' type='button' id='add_sidebar' value='".__("add", $themename)."' /></p>";
	
	$output .= "<ul>";

	// Display every custom sidebar
	if(isset($opts['custom_sidebar']))
	{
		$i = 0;
		foreach($opts['custom_sidebar'] as $sidebar)
		{
			$output .= "<li>".$sidebar." <a href='#' class='delete'>".__("delete", $themename)."</a> <input type='hidden' name='twentyeleven_theme_options[custom_sidebar][]' value='".$sidebar."' /></li>";
			$i++;
		}
	}
	
	$output .= "</ul>";
	
	$output .= "</div>";
	
	echo $output;
}

Eventually, add this code in the twentyeleven_theme_options_validate() function to sanitize and validate form input:

if ( isset( $input['custom_sidebar'] ) ) {
	$output['custom_sidebar'] = $input['custom_sidebar'];
}

At this point, you should be able to manage and save custom sidebars within your theme. For instance, let's create a new custom sidebar called "My custom sidebar". Your theme options page should look like this:

Managing custom sidebars in the theme options section

Step 2 Register Custom Sidebars

Now we're able to add custom sidebars, we need to register them so they can appear in the widgets admin page.

In the Twenty Eleven theme, this is done within the twentyeleven_widgets_init() function. So at the end of this function add this:

$options = twentyeleven_get_theme_options();

if(isset($options['custom_sidebar']) && sizeof($options['custom_sidebar']) > 0)
{
	foreach($options['custom_sidebar'] as $sidebar)
	{
		register_sidebar( array(
			'name' => __( $sidebar, 'twentyeleven' ),
			'id' => generateSlug($sidebar, 45),
			'before_widget' => '<aside id="%1$s" class="widget %2$s">',
			'after_widget' => "</aside>",
			'before_title' => '<h3 class="widget-title">',
			'after_title' => '</h3>',
		) );
	}
}

We retrieve theme options, check that there is at least one custom sidebar and register it. We use a quick function to generate a slug out of the sidebar name to be used as the sidebar ID.

function generateSlug($phrase, $maxLength)
{
	$result = strtolower($phrase);

	$result = preg_replace("/[^a-z0-9\s-]/", "", $result);
	$result = trim(preg_replace("/[\s-]+/", " ", $result));
	$result = trim(substr($result, 0, $maxLength));
	$result = preg_replace("/\s/", "-", $result);

	return $result;
}

Now, go to Appearance -> Widgets and you should see our new custom sidebar.

Add widgets to custom sidebars

Step 3 Adding A Meta Box

Now our custom sidebars are available, we'll add a meta box to display a list of all sidebars available inside the post editing form.

If you're not familiar with meta boxes, you can refer to these links:

Now let's dig into the code.

Add Meta Boxes

First, we'll simply add our meta boxes. We need to declare two meta boxes, one for posts and one for pages. We also need to register two hooks, one to add meta boxes and the other one to save them.

So open your functions.php file and add this:

/* Define the custom box */

add_action( 'add_meta_boxes', 'add_sidebar_metabox' );
add_action( 'save_post', 'save_sidebar_postdata' );

/* Adds a box to the side column on the Post and Page edit screens */
function add_sidebar_metabox()
{
	add_meta_box( 
		'custom_sidebar',
		__( 'Custom Sidebar', 'twentyeleven' ),
		'custom_sidebar_callback',
		'post',
		'side'
	);
	add_meta_box( 
		'custom_sidebar',
		__( 'Custom Sidebar', 'twentyeleven' ),
		'custom_sidebar_callback',
		'page',
		'side'
	);
}

Create the Callback Function

Now, let's create the custom_sidebar_callback function, which will print out the meta boxes' markup.

There're several key steps in this function:

  • Retrieve all registered sidebars (theme default sidebars included) with the global $wp_registered_sidebars variable.
  • Get post metas
  • Create nonce security
  • Add a select element with all sidebars plus a default one which is defined directly in the template file.
/* Prints the box content */
function custom_sidebar_callback( $post )
{
	global $wp_registered_sidebars;
	
	$custom = get_post_custom($post->ID);
	
	if(isset($custom['custom_sidebar']))
		$val = $custom['custom_sidebar'][0];
	else
		$val = "default";

	// Use nonce for verification
	wp_nonce_field( plugin_basename( __FILE__ ), 'custom_sidebar_nonce' );

	// The actual fields for data entry
	$output = '<p><label for="myplugin_new_field">'.__("Choose a sidebar to display", 'twentyeleven' ).'</label></p>';
	$output .= "<select name='custom_sidebar'>";

	// Add a default option
	$output .= "<option";
	if($val == "default")
		$output .= " selected='selected'";
	$output .= " value='default'>".__('default', $themename)."</option>";
	
	// Fill the select element with all registered sidebars
	foreach($wp_registered_sidebars as $sidebar_id => $sidebar)
	{
		$output .= "<option";
		if($sidebar_id == $val)
			$output .= " selected='selected'";
		$output .= " value='".$sidebar_id."'>".$sidebar['name']."</option>";
	}
  
	$output .= "</select>";
	
	echo $output;
}

Save Meta Box

Now let's save our post meta. Again several steps here:

  • Check WordPress is not autosaving
  • Check nonce and authorizations
  • Save post_meta
/* When the post is saved, saves our custom data */
function save_sidebar_postdata( $post_id )
{
	// verify if this is an auto save routine. 
	// If it is our form has not been submitted, so we dont want to do anything
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) 
	  return;

	// verify this came from our screen and with proper authorization,
	// because save_post can be triggered at other times

	if ( !wp_verify_nonce( $_POST['custom_sidebar_nonce'], plugin_basename( __FILE__ ) ) )
	  return;

	if ( !current_user_can( 'edit_page', $post_id ) )
		return;

	$data = $_POST['custom_sidebar'];

	update_post_meta($post_id, "custom_sidebar", $data);
}

Now you should now be able to see this box in the post edit page, in the right column. If not, check that the custom sidebar box is displayed in the top screen options panel.

Choosing a sidebar in the custom sidebar meta box

Step 4 Adjust Template Files

Now everything is correctly set up, what's left to do is updating our templating files so that they can display custom sidebars.

Let's create a new page based on the sidebar template (available in the page attributes box). This template relies on the sidebar-page.php file. Edit this file and add these lines at the top (below the template's commented header):

$options = get_post_custom(get_the_ID());

if(isset($options['custom_sidebar']))
{
	$sidebar_choice = $options['custom_sidebar'][0];
}
else
{
	$sidebar_choice = "default";
}

We retrieve current post meta data to get the chosen sidebar.

To switch between a custom sidebar and the default one, change the get_sidebar() call at the bottom of this same file to this:

if($sidebar_choice && $sidebar_choice != "default")
{
	get_sidebar("custom");
}
else
{
	get_sidebar();
}

The get_sidebar($slug) calls for sidebar-slug.php. So what we have to do, is to create a file named sidebar-custom.php and add this inside:

$options = get_post_custom($post->ID);
$sidebar_choice = $options['custom_sidebar'][0];

?>
<aside id="sidebar" class="floatleft">
	
	<ul class="widgets">
		<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar() ) : 
			dynamic_sidebar($sidebar_choice);
		else : 
			/* No widget */
		endif; ?>
	</ul>

</aside>

Now your page should display the sidebar you chose. For instance, I added two widgets in my custom sidebar:

Page with custom sidebar

I won't cover how to apply this to posts as it's exactly the same behaviour, you just have to update the content-single.php file to manage custom sidebars.


Conclusion

That's all folks! Now you can use unlimited sidebars for your pages and posts. This is just one solution among others, but it's a quick and easy way to implement custom sidebars, so don't hesitate to leave a comment, share your ideas, and give feedback!

Related Posts
  • Code
    Creative Coding
    Advanced Use of Attachments in WordPress: Creating Custom Queries for AttachmentsAdvanced use of attachments in wordpress 400
    This tutorial is the second in a four part series in which you'll learn some techniques for working with images in attachments in WordPress which give you advanced options.Read More…
  • Code
    Theme Development
    Custom Controls in the Theme CustomizerTheme customizer custom control 400
    In the last article, we explored the advanced controls available in the Theme Customizer, and how to implement them. We’re going to look at how to create our own custom control, allowing you to choose which Category of Posts are displayed on the home page. To get started, download version 0.6.0 of our Theme Customizer Example.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme from Static HTML - Creating a Page TemplateCreating wordpress theme from html 400
    So far in this series, I've shown you how to create a fully functioning WordPress theme from static HTML. We've covered the following steps: preparing your markup for WordPress converting your HTML to PHP and splitting your file into template files editing the stylesheet and uploading your theme to WordPress adding a loop to your index file adding meta tags, the wp_head hook and the site title and description to your header file adding a navigation menu adding widget areas to the header and sidebar adding widget areas, a colophon and the wp_footer hook to the footer file. At the moment, your theme only has one template file for displaying content—the index.php file. A powerful feature of WordPress is the ability to use template files for different kinds of content.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: The Footer FileCreating wordpress theme from html 400
    In this series, you've been learning how to create a WordPress theme form static HTML. Up to this point, you have: prepared your markup for WordPress converted your HTML to PHP and split your file into template files edited the stylesheet and uploaded your theme to WordPress added a loop to your index file added meta tags, the wp_head hook and the site title and description to your header file added a navigation menu added widget areas to the header and sidebar. Read More…
  • Code
    Theme Development
    Creating a WordPress Theme from Static HTML - Adding WidgetsCreating wordpress theme from html 400
    In this series, you've learned how to convert a static HTML file to a WordPress theme and edit the header file. So far you've: prepared your markup for WordPress converted your HTML to PHP and split your file into template files edited the stylesheet and uploaded your theme to WordPress added a loop to your index file added meta tags, the wp_head hook and the site title and description to your header file added a navigation menu. Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: Creating Template FilesCreating wordpress theme from html 400
    In the first part of this series, I showed you how to prepare your HTML and CSS files for WordPress, ensuring the structure would work, the code was valid and that the correct classes were being used. In this tutorial you'll learn how to take your index.html file and split it up into a set of template files for use by WordPress.Read More…