Dynamically Register New Sidebars in WordPress with Advanced Custom Fields

The Advanced Custom Fields plugin offers a plethora of possibilities for enhancing WordPress functionality. The following is an example of one such possibility.

In the process of building a new WordPress theme for a client, I wanted a way for administrators to dynamically create new widgetized sidebars and then select which sidebar to use on a per-page or post basis.

Notice: This project requires the repeater field available as a premium add-on in ACF 4.X or included with ACF Pro.

Lets start with the basic “register_sidebar” function in the functions.php file

/*
 *
 * Register Sidebars
 */

function sidebar_widgets_init() { //Register the default sidebar
 register_sidebar( array(
 'name' => 'Sidebar',
 'id' => 'default-sidebar',
 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
 'after_widget' => '</aside>',
 'before_title' => '<h1 class="widget-title">',
 'after_title' => '</h1>',
 ) );
 include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
 if (is_plugin_active('advanced-custom-fields/acf.php')){ //Check to see if ACF is installed
 if (get_field('sidebars','option')){
 while (has_sub_field('sidebars','option')){ //Loop through sidebar fields to generate custom sidebars
 $s_name = get_sub_field('sidebar_name','option');
 $s_id = str_replace(" ", "-", $s_name); // Replaces spaces in Sidebar Name to dash
 $s_id = strtolower($s_id); // Transforms edited Sidebar Name to lowercase
 register_sidebar( array(
 'name' => $s_name,
 'id' => $s_id,
 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
 'after_widget' => '</aside>',
 'before_title' => '<h1 class="widget-title">',
 'after_title' => '</h1>',
 ) );
 };
 };
 };
};

add_action( 'widgets_init', 'sidebar_widgets_init' );

What we’re doing here is initiating the standard Default Sidebar as well as looping through a repeater field that we will be setting up in our ACF Options.

To set up those options, create a new repeater field in our Options field group with the following settings…

Sidebar Options
Now we have the ability to dynamically register new sidebars in our options like this…

Add New Sidebars

Now that’s only half the battle! Now, we want users to be able to select which sidebar they’d like to use when create a new page or (optionally) a post.

We do this by first creating a new ACF field group called “Select Sidebar”. This group only has a single select field. In this case we’ll label it “Select A Field” and make sure it has a name of “select_a_filed”. Add field instructions if you wish and leave everything else default. Make sure to leave the Choices field empty. We will be populating this dynamically based off of the sidebars we register on out options page.

Add the following code to our functions.php file…

/*
 * ACF Sidebar Loader
 */

function my_acf_load_sidebar( $field )
{
 // reset choices
 $field['choices'] = array();
 $field['choices']['default-sidebar'] = 'Default Sidebar';
 $field['choices']['none'] = 'No Sidebar';
 // load repeater from the options page
 if(get_field('sidebars', 'option'))
 {
 // loop through the repeater and use the sub fields "value" and "label"
 while(has_sub_field('sidebars', 'option'))
 {

 $label = get_sub_field('sidebar_name');
 $value = str_replace(" ", "-", $label);
 $value = strtolower($value);

$field['choices'][ $value ] = $label;

}
 }

 // Important: return the field
 return $field;
}

add_filter('acf/load_field/name=select_a_sidebar', 'my_acf_load_sidebar');

This code populates our “Select A Sidebar” field using the add_filter function. It starts by creating two options by default. A “Default Sidebar” and a “None” option. These should be self explanitory, but just in case, the Default Sidebar is the standard WordPress sidebar available from the start. The “None” is exactly that. No sidebar will appear on the page.

Select A Sidebar Group

We’re almost done, but depending on your template, chances are you’ll need to make some modifications to the sidebar.php file.

This is what mine looks like…

/*
 * sidebar.php
 */

<div id="secondary" class="widget-area span4" role="complementary">
 <?php do_action( 'before_sidebar' ); ?>

 <?php
 $sidebar = get_field('select_a_sidebar');
 if($sidebar != 'none'){
 dynamic_sidebar($sidebar);
 };
 ?>

<?php do_action( 'after_sidebar' ); ?>
</div><!-- #secondary .widget-area -->

What we’re doing here is calling back to our “Select a Sidebar” field to see what the user has chossen for his sidebar. If “None” was selected, then no sidebar will be returned.

And that’s it! Now we have given our users a way to create new sidebar containers and select which conaiter they’d like to use on their pages on a per-page basis.

I hope this helped, and if you see a way to improve this process, I’m all ears.

5 Responses to “Dynamically Register New Sidebars in WordPress with Advanced Custom Fields”

  1. Gen says:

    “To set up those options, create a new repeater field in our Options field group” — “Repeater” is not a field type.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>