CODE UPDATED WITH = ADD UNLIMITED SIDEBARS (JavaScript)
Create a function that register sidebars, using [register_sidebar
][1], starting from an option:
add_action('widgets_init', 'my_custom_sidebars');
function my_custom_sidebars() {
$sidebars = get_option('my_theme_sidebars'); // get all the sidebars names
if ( ! empty($sidebars) ) {
// add a sidebar for every sidebar name
foreach ( $sidebars as $sidebar ) {
if ( empty($sidebar) ) continue;
register_sidebar(array(
'name' => $sidebar,
'id' => sanitize_title($sidebar),
'before_title' => '<h1>',
'after_title' => '</h1>'
));
}
}
}
UPDATED: Now you have to save an option 'my_theme_sidebars'
that contain an array of sidebars name.
Here I'm posting post the code that create a page with 10 text inputs where add the sidebar name. (I'll use [add_theme_page
][2]) You can improve it adding javascript to dynamic add fields.. Add unlimited sidebars admin page.
add_action( 'admin_menu', 'my_sidebar_plugin_menu' );
function my_sidebar_plugin_menu() {
add_theme_page( 'sidebar Plugin Options', 'Add Sidebar', 'manage_options', 'my-sidebar-unique-identifier', 'my_sidebar_plugin_options' );
$nonce = filter_input(INPUT_POST, 'my_custom_sidebars_nonce', FILTER_SANITIZE_STRING);
if ( ! empty($nonce) && wp_verify_nonce($nonce, 'my_custom_sidebars') ) {
$sidebars = (array) $_POST['custom_sidebars'];
update_option('my_theme_sidebars', $sidebars);
add_action('admin_notices', 'my_custom_sidebars_notice');
}
}
function my_sidebar_plugin_options() {
wp_enqueue_script('jquery');
wp_enqueue_script('custom_sidebar-js', get_template_directory_uri() . '/js/custom_sidebar.js');
if ( !current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have sufficient permissions to access this page.' ) );
}
?>
<div class="my-form">
<div class="wrap">
<h2>Add Custom Sidebars</h2>
<form id="sidebars" method="post">
<?php wp_nonce_field('my_custom_sidebars', 'my_custom_sidebars_nonce');
$saved = get_option('my_theme_sidebars');
$xx=get_option('my_theme_sidebars');
//print_r($xx);
$no=count($xx);
?>
<div id="append">
<p class="text-box">
<label for="box1">Sidebar-<span class="box-number">1</span></label>
<input type="text" name="custom_sidebars[]" value="<?php echo $xx[0]; ?>" id="box1" />
<a href="#" class="remove-box">Remove</a>
</p>
<?php if($no>1){
for($i=1;$i<$no;$i++){
?>
<p class="text-box"><label for="box' + n + '">Sidebar-<span class="box-number"><?php echo $i+1; ?></span></label>
<input type="text" name="custom_sidebars[]" value="<?php echo $xx[$i]; ?>" id="box' + n + '" />
<a href="#" class="remove-box">Remove</a>
</p>
<?php }
} ?></div>
<!--<a class="add-box" href="#">Add More</a>-->
<button type="button" class="add-box">Add New Sidebar</button>
</table>
<input type="hidden" name="action" value="update" />
<input type="hidden" name="page_options" value="no_of_sidebar,sidebar_names,boxes" />
<p class="submit">
<input type="submit" class="button-primary clsSubmit" value="<?php _e('Save Changes') ?>" />
</p>
</form>
</div>
</div>
<?php
}
function my_custom_sidebars_notice() {
echo '<div class="updated"><p>Sidebar(s) Updated.</p></div>';
}
Now, you have you let users select the sidebars for a specific page.
You can add a metabox for that. (See [add_meta_box
][3] docs).
add_action( 'add_meta_boxes', 'my_custom_sidebar_metabox' );
function my_custom_sidebar_metabox() {
$screens = array( 'post', 'page' ); // add the metabox for pages and post
foreach ( $screens as $screen ) {
add_meta_box('my_custom_sidebar', 'Select a Sidebar','my_custom_sidebar_box', $screen);
}
}
function my_custom_sidebar_box( $post ) {
$sidebars = get_option('my_theme_sidebars'); // get all the sidebars names
if ( empty($sidebars) ) {
echo 'No custom sidebars registered.';
return;
}
wp_nonce_field( 'my_custom_sidebar', 'my_custom_sidebar_box_nonce' );
$value = get_post_meta( $post->ID, '_custom_sidebar', true ); // actual value
echo '<label>Select a Sidebar</label> ';
echo '<select name="custom_sidebar">';
// default option
echo '<option value=""' . selected('', $value, false) . '>Default</option>';
// an option for every sidebar
foreach ($sidebars as $sidebar) {
if ( empty($sidebar) ) continue;
$v = sanitize_title($sidebar);
$n = esc_html($sidebar);
echo '<option value="' . $v . '"' . selected($v, $value) .'>' .$n .'</option>';
}
echo '<select>';
}
Then add the function to save the metabox:
add_action( 'save_post', 'my_custom_sidebar_metabox_save' );
function my_custom_sidebar_metabox_save( $post_id ) {
// If this is an autosave, our form has not been submitted, do nothing.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// check nonce
$nonce = filter_input(INPUT_POST, 'my_custom_sidebar_box_nonce', FILTER_SANITIZE_STRING);
if ( empty($nonce) || ! wp_verify_nonce( $nonce, 'my_custom_sidebar' ) ) return;
$type = get_post_type($post_id);
// Check the user's permissions.
$cap = ( 'page' === $type ) ? 'edit_page' : 'edit_post';
if ( ! current_user_can( $cap, $post_id ) ) return;
$custom = filter_input(INPUT_POST, 'custom_sidebar', FILTER_SANITIZE_STRING);
// Update the meta field in the database.
if ( empty($custom) ) {
delete_post_meta( $post_id, '_custom_sidebar');
} else {
update_post_meta( $post_id, '_custom_sidebar', $custom );
}
}
In this way your users can choose a custom sidebar for every post or page. It is saved in the meta field '_custom_sidebar'
.
To display the custom sidebar, your sidebar.php
should contain something like:
// change the following according to your defaults sidebar if exists
$sidebar = 'main_sidebar';
// if in singular post/page check for saved custom sidebar
if ( is_singular() ) {
$id = get_queried_object_id(); // get current post/page id
$custom = get_post_meta( $id, '_custom_sidebar', true ); // get selected sidebar
if ( ! empty($custom) ) $sidebar = $custom;
}
if ( is_active_sidebar( $sidebar ) ) {
?>
<ul id="sidebar"><?php dynamic_sidebar( $sidebar ); ?></ul>
<?php } ?>
Finally in your pages and posts just call get_sidebar();
as usual.
UPDATED: Create a new JavaScript file for multi sidebars js/custom_sidebar.js
( function( $ ) {
$('.my-form .add-box').click(function(){
var n = $('.text-box').length + 1;
var box_html = $('<p class="text-box"><label for="box' + n + '">Sidebar-<span class="box-number">' + n + '</span></label> <input type="text" name="custom_sidebars[]" value="" id="box' + n + '" /> <a href="#" class="remove-box">Remove</a></p>');
box_html.hide();
$('#append').append(box_html);
box_html.fadeIn('slow');
return false;
});
$('.my-form').on('click', '.remove-box', function(){
$(this).parent().css( 'background-color', '#FF6C6C' );
$(this).parent().fadeOut("slow", function() {
$(this).remove();
$('.box-number').each(function(index){
$(this).text( index + 1 );
});
});
return false;
});
$('.clsSubmit').click(function(){
var m = $('.text-box').length;
if(m==0){alert("press OK to Reset");}
});
Finally in your pages and posts just call get_sidebar();
as usual.