WordPress: let users choose their sidebar on posts and pages with custom values

WordPress: let users choose their sidebar on posts and pages with custom values

How to create a select box on posts and pages to let users choose their preferred WordPress sidebar.

Letting users choose their preferred sidebar to be displayed on posts and pages is surely a nice feature to add to a WordPress theme. In this article we'll see how to accomplish this task by using an object-oriented approach.

Creating the sidebars

We're going to create three sidebars for our theme:


<?php
class ThemeInit {
	
	public function __construct() {
		
		$this->registerSidebars();
	
	}
	
	public function registerSidebars() {
		if ( function_exists('register_sidebar') ) {

			register_sidebar(array('name'=>'Sidebar 1',
					'before_widget' => '<div class="widget">',
					'after_widget' => '</div>',
					'before_title' => '<h3>',
					'after_title' => '</h3>',
				));

			register_sidebar(array('name'=>'Sidebar 2',
					'before_widget' => '<div class="widget">',
					'after_widget' => '</div>',
					'before_title' => '<h3>',
					'after_title' => '</h3>',
				));

			register_sidebar(array('name'=>'Sidebar 3',
					'before_widget' => '<div class="widget">',
					'after_widget' => '</div>',
					'before_title' => '<h3>',
					'after_title' => '</h3>',
				));

		}

	
	}
}

$init = new ThemeInit();

The next step is to add a custom metabox to post and pages in order to allow users to select their sidebar.

Creating the metabox

The metabox we're going to create will define a custom meta value named sidebar which will store the sidebar's name:


<?php
class ThemeSidebar {

	public function __construct() {
		add_action( 'admin_init', array($this, 'sidebarMetaBox'));
		add_action( 'save_post', array($this, 'saveSidebar'));
	}
	
	public function sidebarMetaBox() {
		add_meta_box("sidebar-meta", "Sidebar", array(&$this, 'sidebarMetaOptions'), "post", "side", "low");
		add_meta_box("sidebar-meta", "Sidebar", array(&$this, 'sidebarMetaOptions'), "page", "side", "low");
	}

	
	
	public function sidebarMetaOptions() {
		global $post;
		if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
		$custom = get_post_custom($post->ID);
		$sidebar = $custom["sidebar"][0];
?>
    	<label>Sidebar:</label>
    	<select name="sidebar">
    		<option value="Sidebar 1" selected="selected">Sidebar 1</option>
    		<option value="Sidebar 2"<?php if($sidebar == 'Sidebar 2'): echo ' selected="selected"'; endif;?>>Sidebar 2</option>
    		<option value="Sidebar 3"<?php if($sidebar == 'Sidebar 3'): echo ' selected="selected"'; endif;?>>Sidebar 3</option>
    	</select>
    <?php
	}
	
	public function saveSidebar(){
		global $post;

		if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){
			return $post_id;
		}else{
			update_post_meta($post->ID, 'sidebar', $_POST["sidebar"]);
		}
	}



}

$sidebar = new ThemeSidebar();

Editing sidebar.php

Now we need to read the custom value on the sidebar.php template:


<div id="sidebar">
<?php
		global $post;
		$id = $post->ID;
		$sidebar = get_post_meta($id, 'sidebar', true);
		
		if($sidebar != '') {
			dynamic_sidebar($sidebar);
		
		} else {
			if ( ! dynamic_sidebar( 'Sidebar 1' )) {?>
			
			<!--...-->
			
		<?php	
			}
					
		}
	
	?>	


</div>

Editing functions.php

In the functions.php file we need to include our classes:


<?php
require_once(TEMPLATEPATH . '/framework/ThemeInit.php');
require_once(TEMPLATEPATH . '/framework/ThemeSidebar.php');
?>

Of course you can change the default path to fit your theme's file structure.