Menu and Sidebar dropdown, custom Controls for the WordPress Theme Customizer

By default, the only controls the API offers are text field, checkbox, radio, select and dropdown pages. By creating our own control class, we can step beyond these boundaries and create even more controls, including implementing number box, a page template selector, a Google Font selector, a yes/no button and even a range selector.

Using Included Controls

To create our own controls we can extend the WP_Customize_Control class, adding some of our own functions.
Let’s make one together, a simple text box which is – surprisingly – not available by default.Let’s make one together, a simple text box which is – surprisingly – not available by default. Thanks to the theme customizer snippets for this example.

if( class_exists( 'WP_Customize_Control' ) ):
	class WP_Customize_Textarea_Control extends WP_Customize_Control {
		public $type = 'textarea';
 
		public function render_content() {
		?>
			<label>
				<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
				<textarea rows="5" style="width:100%;" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
			</label>
		<?php
		}
	}
endif;

For example, in the base class the public variable $type is defined as text. Looking at the code of the class there is no setter method which has the task of setting the value of this property. This is why, when extending the class, we define it ourselves. The render_content() method defines controls, which is why the example above has added this function.

It’s important to note that $this->link() is required for the Javascript in the theme customizer to work. $this->value() can be used to retrieve the value of the setting we are manipulating.

Menu Dropdown Custom Control

class Menu_Dropdown_Controls extends WP_Customize_Control{
    
        private $menus = false;
        public function __construct($manager, $id, $args = array(), $options = array())
        {
            $this->menus = wp_get_nav_menus($options);
            parent::__construct( $manager, $id, $args );
        }

        public $type = 'menu-dropdown';
        public function render_content(){
            if(!empty($this->menus))
            {
                ?>
                    <label>
                        <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>                    
                        <select name="<?php echo $this->id; ?>" id="<?php echo $this->id; ?>">
                        <?php
                            foreach ( $this->menus as $menu )
                            {
                                printf('<option value="%s" %s>%s</option>', $menu->term_id, selected($this->value(), $menu->term_id, false), $menu->name);
                            }
                        ?>
                        </select>
                    </label>
                <?php
            }
        
        }
    }

Sidebar Dropdown Custom Control

 class Sidebar_Dropdown_Controls extends WP_Customize_Control{
    public $type = 'sidebar-dropdown';
    public function render_content(){
    ?>
        <label class="customize_dropdown_input">
            <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
            <p><?php echo wp_kses_post($this->description); ?></p>
            <?php
            global $wp_registered_sidebars;
            ?>
            <select id="<?php echo esc_attr($this->id); ?>" name="<?php echo esc_attr($this->id); ?>" data-customize-setting-link="<?php echo esc_attr($this->id); ?>">
            <?php
            $sidebar_shop = $wp_registered_sidebars;
            
            if(is_array($sidebar_shop) && !empty($sidebar_shop)){
                foreach($sidebar_shop as $sidebar){
                    echo '<option value="'.$sidebar['id'].'" ' . selected( $this->value(), $sidebar['name'], false ) . '>'.$sidebar['name'].'</option>';
                }
            }
            ?>
            </select>
            <br>
        </label>
    <?php
    }
}

Pages Dropdown

class Pages_Dropdown_Controls extends WP_Customize_Control{

        public $type = 'pages-dropdown';
        public function render_content(){
            $latest = new WP_Query( array(
            'post_type'   => 'page',
            'post_status' => 'publish',
            'orderby'     => 'date',
            'order'       => 'DESC'
            )); ?>
            <label>
                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
                <select <?php $this->link(); ?>>
                    <?php 
                    while( $latest->have_posts() ) {
                        $latest->the_post();
                        echo "<option " . selected( $this->value(), get_the_ID() ) . " value='" . get_the_ID() . "'>" . the_title( '', '', false ) . "</option>";
                    }
                    ?>
                </select>
            </label>

        <?php
        }
    }