Custom Controls in WP Admin

Posted: March 30, 2013 in Php, Wordpress

Introduction

WordPress 3.4 has a fucking cool new feature on the themes page. Next to each theme theres a preview or a customize link that pops up a new overlay that lets the user live edit their themes. Adding extra theme options has been constant a pain the arse since I started developing themes all those few years ago. To make things easier for myself I even created a theme admin plugin. I was never that happy with the plugin however and always too busy to make it work so the new theme customizer seems like a good timesaver for me and I decided to take a look at how to implement it.

The first thing I found was that as with all new WP features no-one has written any documentation for customising (Hey WP core developers, customise is spelled with a damn s!) it yet. All I could find was this description of the beta version. Also there doesn’t seem to be an API yet, it must be coming in a future release. However, there is an object called $wp_customize that you can add your custom theme settings to.

Getting Started

On loading up my starter theme in the preview I was suprised in seeing a half built menu already there. This is because WordPress is pulling the options for custom headers, backgrounds that you’ve added using the add_theme_support() function. It also pulls some core options like site title and displays them there.

Custom Options

Time for custom options. Going through the blog post I found I saw that the first thing you need to do is hook a function to the customize_register action like this:

1
2
3
4
function themename_customize_register($wp_customize){
    //STUFF IN HERE
}
add_action('customize_register', 'themename_customize_register');

All your custom options go into there.

Adding a Section

This is simple enough as far as I can tell. You add one using the following:

1
2
3
4
$wp_customize->add_section('themename_color_scheme', array(
    'title' => __('Color Scheme', 'themename'),
    'priority' => 120,
));

So you pass through a unique slug and an array of arguments to the add_section method. I’m not 100% sure of all the arguments to pass through in the array, all I passed was the title and the priority. The priority is where you want the section to appear in the menu order. 1 is on the top and 120 seems to be the bottom.

Adding options

There are two methods you need to call to add an option. One to tell WordPress that an option exists and one to display whatever input box it needs. This is similar how the add_option()/update_option()/get_option() API works and it should be because it uses those functions to save the settings as far as I can tell/be bothered to check.

The first option type I’m going to show you is a standard text input box then I’ll breeze through the other types. You need to first call the add_setting() method to tell WP that you wish to save some new data. You do that like this:

1
2
3
4
5
$wp_customize->add_setting('themename_theme_options[text_test]', array(
    'default'        => 'Arse!',
    'capability'     => 'edit_theme_options',
    'type'           => 'option',
));

Similar to the add_section() method you pass through a slug and an array of args. You need to pass through a unique slug to this as the first parameter and it also allows you to pass the slug as an array index. The advantages of this is all your options are then available in the template in the one array keeping things nice and neat. The args I’ve found are:

  • Default: The default value for the input.
  • Capability: This is the user role that is capable of editing these settings, I assume you would always set it to ‘edit_theme_options’.
  • Type: The way you want to store the data in WordPress, you can set it to ‘option’ or ‘theme_mod’. I’ve always used option for saving theme preferences but if you prefer using theme mod then you can set it to save those here.

Next you want to display your option in your custom section:

1
2
3
4
5
$wp_customize->add_control('themename_text_test', array(
    'label'      => __('Text Test', 'themename'),
    'section'    => 'themename_color_scheme',
    'settings'   => 'themename_theme_options[text_test]',
));

Again this works similarly to add_setting() and add_section() you pass a unique slug (Don’t really know why here as it’s only used as the list item css id) and an array of args. Some of the args are used for every input and some differ depending on the input element you want to display. The universal ones are:

  • label: The form items label.
  • section: The section in which you want the form item to appear.
  • type: The type of form item you want. These are text, radio, checkbox and select. And are standard form elements. Textareas and HTML5 input types aren’t supported.
  • settings: This is the setting you want to use to save the values from the file input. You put in the unique slug of of the setting you want to use.
  • choices: These are only needed for radio buttons and dropdowns and contain the different options you want to display.

You can also add options to the sections created by the WordPress core by passing their slug in the section arg. The ones I found are:

  • Colors: colors
  • Header Image: header_image
  • Background Image: background_image
  • Static Front Page: static_front_page
  • Site Title & Tagline: title_tagline
  • Navigation: nav

Standard Input Types

These are just standard form items.

Radio

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
$wp_customize->add_setting('themename_theme_options[color_scheme]', array(
    'default'        => 'value2',
    'capability'     => 'edit_theme_options',
    'type'           => 'option',
));
$wp_customize->add_control('themename_color_scheme', array(
    'label'      => __('Color Scheme', 'themename'),
    'section'    => 'themename_color_scheme',
    'settings'   => 'themename_theme_options[color_scheme]',
    'type'       => 'radio',
    'choices'    => array(
        'value1' => 'Choice 1',
        'value2' => 'Choice 2',
        'value3' => 'Choice 3',
    ),
));

Checkbox

To be honest, I think I’m missing something here. It’s acting a bit wonkey. Maybe it’s broken?

01
02
03
04
05
06
07
08
09
10
11
$wp_customize->add_setting('themename_theme_options[checkbox_test]', array(
    'capability' => 'edit_theme_options',
    'type'       => 'option',
));
$wp_customize->add_control('display_header_text', array(
    'settings' => 'themename_theme_options[checkbox_test]',
    'label'    => __('Display Header Text'),
    'section'  => 'themename_color_scheme',
    'type'     => 'checkbox',
));

Select Box

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
$wp_customize->add_setting('themename_theme_options[header_select]', array(
    'default'        => 'value2',
    'capability'     => 'edit_theme_options',
    'type'           => 'option',
));
$wp_customize->add_control( 'example_select_box', array(
    'settings' => 'themename_theme_options[header_select]',
    'label'   => 'Select Something:',
    'section' => 'themename_color_scheme',
    'type'    => 'select',
    'choices'    => array(
        'value1' => 'Choice 1',
        'value2' => 'Choice 2',
        'value3' => 'Choice 3',
    ),
));

Page Dropdown

This displays a list of your pages. I guess you could allow the user to set pages for something custom. It’s weird that this is in there but not a category dropdown option.

01
02
03
04
05
06
07
08
09
10
11
12
$wp_customize->add_setting('themename_theme_options[page_test]', array(
    'capability'     => 'edit_theme_options',
    'type'           => 'option',
));
$wp_customize->add_control('themename_page_test', array(
    'label'      => __('Page Test', 'themename'),
    'section'    => 'themename_color_scheme',
    'type'    => 'dropdown-pages',
    'settings'   => 'themename_theme_options[page_test]',
));

You can hack in a category dropdown like this however:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$categories = get_categories();
$cats = array();
$i = 0;
foreach($categories as $category){
    if($i==0){
        $default = $category->slug;
        $i++;
    }
    $cats[$category->slug] = $category->name;
}
$wp_customize->add_setting('themename_theme_options[header_select]', array(
    'default'        => $default,
    'capability'     => 'edit_theme_options',
    'type'           => 'option',
));
$wp_customize->add_control( 'example_select_box', array(
    'settings' => 'themename_theme_options[header_select]',
    'label'   => 'Select Something:',
    'section' => 'themename_site_options',
    'type'    => 'select',
    'choices' => $cats,
));

Fancy Input Types

These are custom input types and use javascript to work. They also all vary slightly from the others in that a new object needs to be created for each control.

Image Upload

Image upload is a file input type and allows users to upload an image. Handy for letting them set their logo.

01
02
03
04
05
06
07
08
09
10
11
$wp_customize->add_setting('themename_theme_options[image_upload_test]', array(
    'default'           => 'image.jpg',
    'capability'        => 'edit_theme_options',
    'type'           => 'option',
));
$wp_customize->add_control( new WP_Customize_Image_Control($wp_customize, 'image_upload_test', array(
    'label'    => __('Image Upload Test', 'themename'),
    'section'  => 'themename_color_scheme',
    'settings' => 'themename_theme_options[image_upload_test]',
)));

File Upload

Adds a custom file input. Good for allowing the end user to upload files I guess. Maybe a custom favicon would use this?

01
02
03
04
05
06
07
08
09
10
11
12
$wp_customize->add_setting('themename_theme_options[upload_test]', array(
    'default'           => 'arse',
    'capability'        => 'edit_theme_options',
    'type'           => 'option',
));
$wp_customize->add_control( new WP_Customize_Upload_Control($wp_customize, 'upload_test', array(
    'label'    => __('Upload Test', 'themename'),
    'section'  => 'themename_color_scheme',
    'settings' => 'themename_theme_options[upload_test]',
)));

Color Picker

Displays a colour picker. Gives the user the option to destroy your theme with their bad taste. This input seems to have a hex colour callback for sanitizing the value.

01
02
03
04
05
06
07
08
09
10
11
12
13
$wp_customize->add_setting('themename_theme_options[link_color]', array(
    'default'           => '000',
    'sanitize_callback' => 'sanitize_hex_color',
    'capability'        => 'edit_theme_options',
    'type'           => 'option',
));
$wp_customize->add_control( new WP_Customize_Color_Control($wp_customize, 'link_color', array(
    'label'    => __('Link Color', 'themename'),
    'section'  => 'themename_color_scheme',
    'settings' => 'themename_theme_options[link_color]',
)));

Displaying these options in your theme.

Displaying this stuff is easy. Depending on if you set your setting_type() to option or theme_mod you can display it in the two following ways:

Option:

1
<?php $options = get_option('themename_theme_options'); echo $options['input_name']; ?>

Theme Mod:

1
<?php $options =  get_theme_mod('themename_theme_options'); echo $options['input_name']; ?>

In Closing

Thats as far as I got in a couple of hours research (fucking about), you can download a working gist of the examples that you can copy straight into your themes functions.php file below and have a fiddle with it yourself. Please feel free to correct whatever I have wrong up there as I made quite a few assumtions and have probably made a mistake or two.

Download the code

Courtesy:-abandon.ie/exploring-wordpress-theme-customizer/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s