• Tutorials\
  • Theme Development

How to Use Custom Sidebars on Posts and Pages

Tutorial Details
  • Program: WordPress and jQuery
  • Version:
  • Difficulty: Intermediate
  • Estimated Completion Time: 30 min
Tweet

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 class=\'#\' 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 class='#' 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:


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.


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:

  • add_meta_box on the WordPress codex
  • How to Create Custom WordPress Write/Meta Boxes
  • Reusable custom meta box series

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.


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:

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!

Tags: sidebarstemplates
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • www.abditive.in Jayant Tyagi

    something i was looking for.

    • www.wpfix.org Wpfix

      Yeh,, very useful tutorial.

  • www.umnotablogger.com/ Lawliet

    Awesome share! would really help the novices… :)

  • wppot.com Ajay Patel

    Today i found something really useful, when I am using ElegantThems or woothemes have this types of feature and I wonder to do this. Thanks Guillaume Voisin !

  • www.nightocoder.com Rawaf

    Perfect tutorial, I liked it and I will try it in my next project

    thank you

  • jayj.dk Jesper

    Instead of creating the generateSlug function, you can use the sanitize_title() function.

    • fatihtoprak.com/ Fatih Toprak

      I think you are right … Thanks for the advice.

    • www.guillaumevoisin.fr/ Guillaume
      Author

      Yes, using this function is relevant. Didn’t know about this one. Thanks for sharing ;)

  • Pingback: Top 15 Wordpress Articles You Don't Want to Miss This Week

  • guillaume-bartolini.com Guillaume

    Thanks for that awesome tut it was just what i needed.

    Just maybe on little mistake (and i could be wrong) but in your last block of code (to get the $options array)
    you typed :

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

    where “choose_sidebar” should be “custom_sidebar”

    Thanks again

    • www.guillaumevoisin.fr/ Guillaume
      Author

      Absolutely, that seems to be a bad copy paste mistake ! Thanks for pointing this out.

  • www.webdesign309.com/ Steven D. Sanders

    I can’t wait for someone to come up with a graceful solution to this problem, but it definitely hasn’t happened yet. The method used in this post quickly becomes unmanageable once you have a multitude of pages that all require their own unique sidebars.

    • www.guillaumevoisin.fr/ Guillaume
      Author

      I agree this system can become very unhandy if you have lots of pages and posts.

      To avoid cluttering the widgets.php page, maybe we shoud do something with the metaboxes to manage and store content directly within your content. The drawback is that you can’t share a same content.

      I don’t have any magic solution right now, but it’s definitely something to digg into.

      • www.sorenhoyer.com Soren Hoyer

        I think your solution is great! The only thing you’d need to add to achieve what you’re additionally after is ..

        1) Add an empty/blank sidebar from the dropdown, where you select your custom dropdown select for the specific page.

        2) Show a metabox with a textfield for widget title and a textarea for the custom content.

        However I really don’t see how what you showed in this tutorial could ever be too unmanageable and cluttered, since

        - you use a dropdown select form element (which is compact in itself)
        - wordpress sidebars can be closed so they really wont take up much space
        - you have the ability to go even further and add custom widgets which in turn could deliver custom content for specific types of CPT’s.

        I honestly don’t see how (and why) one would be looking for a better (more graceful) solution than this. To me this is a solution that fits in great with the WP interface.

        Thanks for inspiring me to implement this. Great tutorial!

  • Pingback: Legg til widgets på utvalgte sider « Alexander Kjølstad

  • flickapix

    love the tut but how would you implement into a theme using the options framework by sy4mil which is based on devins old style options framework, any help appreciated :)

  • wpden.net/ Ritesh Sanap

    Great tutorial, I was looking for this, I thought I would have to write big bunches of lines, but you have shown it in small and quicker way

  • pinoyscreencast.net rnovino

    can this be also applied on the single post? I think this is for a custom page template

    • www.guillaumevoisin.fr/ Guillaume
      Author

      As I said in the tutorial, it is the same process for a single post, so there’s no problem with that. You just have to configure your metabox to set it to “post” instead of “page”.

    • designartwall.com mabuc

      you have to add metabox

      add_meta_box( ‘custom_sidebar’, __( ‘Custom Sidebar’, ‘demo_lang’ ), ‘custom_sidebar_callback’, ‘post’, ‘side’ );

  • wp-tricks.co.il/ Rami

    This is a great tutorial, thanks.

    Seems like the wordpress plugin repository has more advanced custom-sidber-plugins:

    wordpress.org/extend/plugins/search.php?q=Custom+Sidebars

  • wpdezign.com Naweed S

    Great tutorial!

    But how do you make a custom sidebar only for each and every post.

    I know of a plugin which can do this; mysnippets. But I’m into coding it manually than relying on plugins.

    Any tutorial based on this?

    • www.guillaumevoisin.fr/ Guillaume
      Author

      Hum, if you want to set a custom sidebar available for only one post, I guess you could deal with metadata and metaboxes, I do not see the point to attach different widgets on every post.

  • zeaks.org Scott

    Thanks for the tutorial. Could this be done with a child theme instead of Twenty Eleven?

    • www.guillaumevoisin.fr/ Guillaume
      Author

      I’m pretty sure you can, you juste have to override parent’s functions.php and put the functions inside and it shoult do the trick.

  • Pingback: Quality Tutorials For Creating WordPress Custom Post Types | Design Woop | The Web Design and Development Blog

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.