Paulund
2013-11-27 #wordpress

Custom WordPress Customizer Controls

In a previous tutorial I spoke about the WordPress theme customizer and how you can use this feature to make it easy for your users to change the theme straight from the admin area. Then we looked at how you can inherit from the class WP_Customize_Control to create your own custom controls in your WordPress theme. I've created a Github repo where I added some custom controls which you can use in your own theme. WordPress Theme Customizer Custom Controls In this tutorial we are going to go over the code that you need to use to create these custom controls and how to use the demo page to see these controls in action. Currently the controls that are in this repository are:

  • Date picker
  • Layout picker
  • Category dropdown
  • Google font dropdown
  • Menu dropdown
  • Post dropdown
  • Post type dropdown
  • Tags dropdown
  • Taxonomy dropdown
  • User dropdown
  • Text editor
  • Textarea

Date Picker

The below code will add the jQuery UI styling onto the page and will create a textbox to add a date picker to the theme customizer.


<?php
if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * Class to create a custom date picker
 */
class Date_Picker_Custom_Control extends WP_Customize_Control
{
    /**
    * Enqueue the styles and scripts
    */
    public function enqueue()
    {
        wp_enqueue_style( 'jquery-ui-datepicker' );
    }

    /**
    * Render the content on the theme customizer page
    */
    public function render_content()
    {

        ?>
            <label>
              <span class="customize-date-picker-control"><?php echo esc_html( $this->label ); ?></span>
              <input type="date" id="<?php echo $this->id; ?>" name="<?php echo $this->id; ?>" value="<?php echo $this->value(); ?>" class="datepicker" />
            </label>
        <?php
    }
}
?>

Layout picker

This code will create 3 radio buttons you will show your user to choose a new layout, you can then get this value in your theme and change the template that is displayed.


<?php
if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * Class to create a custom layout control
 */
class Layout_Picker_Custom_Control extends WP_Customize_Control
{
      /**
       * Render the content on the theme customizer page
       */
      public function render_content()
       {
            ?>
                <label>
                  <span class="customize-layout-control"><?php echo esc_html( $this->label ); ?></span>
                  <ul>
                    <li><img src="/1col.png" alt="Full Width" /><input type="radio" name="<?php echo $this->id; ?>" id="<?php echo $this->id; ?>[full_width]" value="1" /></li>
                    <li><img src="/2cl.png" alt="Left Sidebar" /><input type="radio" name="<?php echo $this->id; ?>" id="<?php echo $this->id; ?>[left_sidebar]" value="1" /></li>
                    <li><img src="/2cr.png" alt="Right Sidebar" /><input type="radio" name="<?php echo $this->id; ?>" id="<?php echo $this->id; ?>[right_sidebar]" value="1" /></li>
                  </ul>
                </label>
            <?php
       }
}
?>

Layout Images

The above will bring in layout images to show the user what each radio button does, here are the 3 layout images you can use for your control.

Category dropdown

Use this to display a dropdown of categories. This uses the get_categories() function to get a list of all categories. You could also use the wp_dropdown_categories() function but this way you can easily add additional HTML attributes to your dropdown.


<?php

if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * A class to create a dropdown for all categories in your wordpress site
 */
 class Category_Dropdown_Custom_Control extends WP_Customize_Control
 {
    private $cats = false;

    public function __construct($manager, $id, $args = array(), $options = array())
    {
        $this->cats = get_categories($options);

        parent::__construct( $manager, $id, $args );
    }

    /**
     * Render the content of the category dropdown
     *
     * @return HTML
     */
    public function render_content()
       {
            if(!empty($this->cats))
            {
                ?>
                    <label>
                      <span class="customize-category-select-control"><?php echo esc_html( $this->label ); ?></span>
                      <select <?php $this->link(); ?>>
                           <?php
                                foreach ( $this->cats as $cat )
                                {
                                    printf('<option value="%s" %s>%s</option>', $cat->term_id, selected($this->value(), $cat->term_id, false), $cat->name);
                                }
                           ?>
                      </select>
                    </label>
                <?php
            }
       }
 }
?>

Google font dropdown

Use this control to get a list of the most popular Google web fonts. This will even create a cache file on the users machine to make sure you don't have to call the API so many times.


<?php

if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * A class to create a dropdown for all google fonts
 */
 class Google_Font_Dropdown_Custom_Control extends WP_Customize_Control
 {
    private $fonts = false;

    public function __construct($manager, $id, $args = array(), $options = array())
    {
        $this->fonts = $this->get_fonts();
        parent::__construct( $manager, $id, $args );
    }

    /**
     * Render the content of the category dropdown
     *
     * @return HTML
     */
    public function render_content()
    {
        if(!empty($this->fonts))
        {
            ?>
                <label>
                    <span class="customize-category-select-control"><?php echo esc_html( $this->label ); ?></span>
                    <select <?php $this->link(); ?>>
                        <?php
                            foreach ( $this->fonts as $k => $v )
                            {
                                printf('<option value="%s" %s>%s</option>', $k, selected($this->value(), $k, false), $v->family);
                            }
                        ?>
                    </select>
                </label>
            <?php
        }
    }

    /**
     * Get the google fonts from the API or in the cache
     *
     * @param  integer $amount
     *
     * @return String
     */
    public function get_fonts( $amount = 30 )
    {
        $fontFile = '/cache/google-web-fonts.txt';

        //Total time the file will be cached in seconds, set to a week
        $cachetime = 86400 * 7;

        if(file_exists($fontFile) && $cachetime < filemtime($fontFile))
        {
            $content = json_decode(file_get_contents($fontFile));
        } else {

            $googleApi = 'https://www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key={API_KEY}';

            $fontContent = wp_remote_get( $googleApi, array('sslverify'   => false) );

            $fp = fopen($fontFile, 'w');
            fwrite($fp, $fontContent['body']);
            fclose($fp);

            $content = json_decode($fontContent['body']);
        }

        if($amount == 'all')
        {
            return $content->items;
        } else {
            return array_slice($content->items, 0, $amount);
        }
    }
 }
?>

Menu dropdown

Use this control to create a dropdown that is populated with all the menus defined in your WordPress site.


<?php
if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * Class to create a custom menu control
 */
class Menu_Dropdown_Custom_Control 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 );
    }

    /**
     * Render the content on the theme customizer page
    */
    public function render_content()
    {
        if(!empty($this->menus))
        {
            ?>
                <label>
                    <span class="customize-menu-dropdown"><?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
        }
    }
}
?>

Post dropdown

Use this control to create a dropdown of all posts created on your WordPress site.


<?php
if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * Class to create a custom post control
 */
class Post_Dropdown_Custom_Control extends WP_Customize_Control
{
    private $posts = false;

    public function __construct($manager, $id, $args = array(), $options = array())
    {
        $postargs = wp_parse_args($options, array('numberposts' => '-1'));
        $this->posts = get_posts($postargs);

        parent::__construct( $manager, $id, $args );
    }

    /**
    * Render the content on the theme customizer page
    */
    public function render_content()
    {
        if(!empty($this->posts))
        {
            ?>
                <label>
                    <span class="customize-post-dropdown"><?php echo esc_html( $this->label ); ?></span>
                    <select name="<?php echo $this->id; ?>" id="<?php echo $this->id; ?>">
                    <?php
                        foreach ( $this->posts as $post )
                        {
                            printf('<option value="%s" %s>%s</option>', $post->ID, selected($this->value(), $post->ID, false), $post->post_title);
                        }
                    ?>
                    </select>
                </label>
            <?php
        }
    }
}
?>

Post type dropdown

Use this control to create dropdown of all post types on your WordPress site.


<?php
if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * Class to create a custom post type control
 */
class Post_Type_Dropdown_Custom_Control extends WP_Customize_Control
{
    private $postTypes = false;

    public function __construct($manager, $id, $args = array(), $options = array())
    {
        $postargs = wp_parse_args($options, array('public' => true));
        $this->postTypes = get_post_types($postargs, 'object');

        parent::__construct( $manager, $id, $args );
    }

    /**
    * Render the content on the theme customizer page
    */
    public function render_content()
    {
        if(empty($this->postTypes))
        {
            return false;
        }
        ?>
            <label>
                <span class="customize-post-type-dropdown"><?php echo esc_html( $this->label ); ?></span>
                <select name="<?php echo $this->id; ?>" id="<?php echo $this->id; ?>">
                <?php
                    foreach ( $this->postTypes as $k => $post_type )
                    {
                        printf('<option value="%s" %s>%s</option>', $k, selected($this->value(), $k, false), $post_type->labels->name);
                    }
                ?>
                </select>
            </label>
        <?php
    }
}
?>

Tags dropdown

Use this control to create a dropdown off all tags in your WordPress site.


<?php
if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * Class to create a custom tags control
 */
class Tags_Dropdown_Custom_Control extends WP_Customize_Control
{
    private $tags = false;

    public function __construct($manager, $id, $args = array(), $options = array())
    {
        $this->tags = get_tags($options);

        parent::__construct( $manager, $id, $args );
    }

    /**
    * Render the content on the theme customizer page
    */
    public function render_content()
    {
        if(empty($this->tags))
        {
            return false;
        }
        ?>
            <label>
                <span class="customize-tags-dropdown"><?php echo esc_html( $this->label ); ?></span>
                <select name="<?php echo $this->id; ?>" id="<?php echo $this->id; ?>">
                <?php
                    foreach ( $this->tags as $tag )
                    {
                        printf('<option value="%s" %s>%s</option>',
                            $tag->term_id,
                            selected($this->value(), $tag->term_id, false),
                            $tag->name);
                    }
                ?>
                </select>
            </label>
        <?php
    }
}
?>

Taxonomy dropdown

Use this control to create a dropdown for any taxonomy in your WordPress site.


<?php
/**
 * Customize for taxonomy with dropdown, extend the WP customizer
 */

if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

class Taxonomy_Dropdown_Custom_Control extends WP_Customize_Control
{
    private $options = false;

    public function __construct($manager, $id, $args = array(), $options = array())
    {
        $this->options = $options;

        parent::__construct( $manager, $id, $args );
    }

    /**
     * Render the control's content.
     *
     * Allows the content to be overriden without having to rewrite the wrapper.
     *
     * @return  void
     */
    public function render_content()
    {
		// Set defaults
		$this->defaults = array(
			'show_option_none' => __( 'None' ),
			'orderby'          => 'name',
			'hide_empty'       => 0,
			'id'               => $this->id,
			'selected'         => $this->value()
		);

		// parse defaults and user data
		$cats = wp_parse_args(
			$this->options,
			$this->defaults
		);

		?>
		<label>
			<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
				<?php wp_dropdown_categories( $cats ); ?>
		</label>
		<?php
    }
}
?>

User dropdown

Use this control to create a dropdown of all users in your site.


<?php
/**
 * Customize for user select, extend the WP customizer
 */

if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

class User_Dropdown_Custom_Control extends WP_Customize_Control
{

    private $users = false;

    public function __construct($manager, $id, $args = array(), $options = array())
    {
        $this->users = get_users( $options );

        parent::__construct( $manager, $id, $args );
    }

    /**
     * Render the control's content.
     *
     * Allows the content to be overriden without having to rewrite the wrapper.
     *
     * @return  void
     */
    public function render_content()
    {
        if(empty($this->users))
        {
            return false;
        }
	?>
		<label>
			<span class="customize-control-title" ><?php echo esc_html( $this->label ); ?></span>
			<select <?php $this->link(); ?>>
			<?php foreach( $this->users as $user )
                              {
                                printf('<option value="%s" %s>%s</option>',
                                $user->data->ID,
                                selected($this->value(), $user->data->ID, false),
                                $user->data->display_name);
                              } ?>
			</select>
		</label>
	<?php
    }
} // end class
?>

Text editor

Use this control to add a text editor to the customizer screen.


<?php
if ( ! class_exists( 'WP_Customize_Control' ) )
    return NULL;

/**
 * Class to create a custom tags control
 */
class Text_Editor_Custom_Control extends WP_Customize_Control
{
      /**
       * Render the content on the theme customizer page
       */
      public function render_content()
       {
            ?>
                <label>
                  <span class="customize-text_editor"><?php echo esc_html( $this->label ); ?></span>
                  <?php
                    $settings = array(
                      'textarea_name' => $this->id
                      );

                    wp_editor($this->value(), $this->id, $settings );
                  ?>
                </label>
            <?php
       }
}
?>

Textarea

Use this control to add a simple text area to your customizer screen.


<?php
/**
 * Customize for textarea, extend the WP customizer
 *
 */

if ( ! class_exists( 'WP_Customize_Control' ) )
     return NULL;

class Textarea_Custom_Control extends WP_Customize_Control
{
	/**
	 * Render the control's content.
	 *
	 * Allows the content to be overriden without having to rewrite the wrapper.
	 *
	 * @since   10/16/2012
	 * @return  void
	 */
	public function render_content() {
		?>
		<label>
			<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
			<textarea class="large-text" cols="20" rows="5" <?php $this->link(); ?>>
				<?php echo esc_textarea( $this->value() ); ?>
			</textarea>
		</label>
		<?php
	}

}
?>

GitHub Repository

I have created a Github repository for this code, included in this repository is a theme-customizer-demo.php file. This file will instantiate all the of the above controls and will add them to your customizer screen. This will allow you to demo the functionality of each of these controls, to use this file all you have to do is download the repository, and include the files in your WordPress theme. Then open your functions.php file and add a require_once for the demo page.


require_once '/inc/wordpress-theme-customizer-custom-controls/theme-customizer-demo.php';

Navigation to the customizer screen Appearance -> Customize and you will see two new content sections, Default demo controls and Custom Controls Demo. The default demo controls will have all the controls that come within the WordPress core and you can use straight away, have a look at the theme-customizer-demo code for more information on how they are used. The Custom Controls Demo section will have all the above controls so you can see how they all function. WordPress Theme Customizer Custom Controls