How to Set Up the WordPress Theme Customizer

The WordPress Theme Customization API is wonderful. It’s an extremely simple way to build customization options directly into your theme or plugin without having to build custom options through the Settings API.

Introduced in WordPress 3.4, it’s a fairly new feature that will most certainly stay around for a while. So it’s safe to use in your theme.

In this article, I want to talk to you about how to create customizer options in your theme and how to build different types of options.

How to Set Up the WordPress Theme Customizer

Let’s get right into it. It’s assumed you’re working with a basic WordPress theme and you have access to its files in a code editor.

From here on out, we’ll be working inside of a theme’s functions.php file. However, if you’re familiar with theme structure and PHP, you’re more than free to create a file like customizer.php and place it anywhere in your theme. Don’t forget to call that file from your functions file, though.

The first thing you want to do is create your function (we’re taking a procedural approach) and action to build the customizer.

function bwpy_customizer( $wp_customize ) {
	// customizer build code
}
add_action( 'customize_register', 'bwpy_customizer' );

Every option we build into the customizer from here forward will be inside of our bwpy_customizer() function.

3-Part Options Building Process

Read this part carefully. You’ll have to wrap your head around the three parts of building an option before actually building it. Just trust me on this one.

Let’s talk about Sections, Settings, and Controls.

Part 1 – Customizer Section

customizer-sectionCustomizer sections are the main sections you see in the customizer screen. They are the accordion titles you click to show/hide options.

You’ve probably noticed that some customizer sections are there by default. I’ll show you how to remove those later.

You’d use sections to logically separate your theme option groupings. If you are creating options that won’t make more sense being underneath a default section, create a new section to use.

We’re going to do just that right now. Our new section will be called “Content Options” where we eventually create an option to show or hide the comments and comments form on WordPress Pages.

Thanks to the $wp_customize object passed to our function, which is an instance of the WP_Customize_Manager class, we’ll use methods from that class to complete tasks, the first of which is adding our section. Here we’ll use the add_section() method like so.

$wp_customize->add_section( 'bwpy_content_options_section' , array(
	'title'      => __( 'Content Options', 'bwpy' ),
	'priority'   => 200,
) );

With that code inside of your bwpy_customizer() function, our new section is built. The value of the “title” is what displays as the section title in the customizer. The “priority” determines where it’s displayed in relation to the position of other sections (I gave it such a high number to make sure it came last). The bwpy_content_options_section section ID is what we will use to identify our section.

You will not see your new section just yet. It has no options in it so WordPress knows not to display it. Smart.

With that saved, we’re ready to move on.

Part 2 – Customizer Setting

Customizer settings are what really let you hack into WordPress with minimal effort. Creating theme options is not just about HTML forms. The information passed through those forms need to save, be accessible, etc. That’s what customizer settings do for you.

That said, for every single option you want to create, you need to build a setting for it.

Just like with the sections, we can use a special method to add settings. That method is add_setting() and we’ll use it like so.

$wp_customize->add_setting( 'bwpy_page_comment_toggle', array( 
	'default' => 1 
) );

What we’ve done here is use our add_setting() method to give this particular setting an ID of bwpy_page_comment_toggle and a default value of “1” (more on that default value shortly).

With that saved, we still can’t see any difference in our customizer! That’s okay, though. We haven’t actually built the option control yet. Let’s do that now.

Part 3 – Customizer Control

Now it’s time for our customizer control. This is the final step in creating an option and where things get the most detailed. Here you determine what kind of option to create, what its label will be, and what section it will fall under, among other things.

Just like the first two parts of this process, we’ll be using another method to add our control. The method is add_control(). Here’s how we’ll use it.

$wp_customize->add_control( 'bwpy_page_comment_toggle', array(
	'label'     => __( 'Show comments on pages?', 'bwpy' ),
	'section'   => 'bwpy_content_options_section',
	'type'      => 'checkbox',
	'priority'  => 10
) );

We’ve done here is used add_control() to add our checkbox option. We set the control ID to match the setting ID from our setting method, bwpy_page_comment_toggle. We used the “label” key to set our text label for the checkbox. We specified the “section” for this control using the section ID we created earlier, bwpy_content_options_section. We used the “type” key to said the option was to be a checkbox. Lastly, we set a priority to control the order in which this control displays in relation to other controls in its section.

Understand that WordPress saves checkbox options with two values – 1 and 0. 1 means it’s checked. 0 means it’s unchecked. Therefore, the default value we gave in the add_setting() method controls what the option choice will be by default.

Completed Customizer Code

Here’s what everything looks like once completed.

function bwpy_customizer( $wp_customize ) {

	// add "Content Options" section
	$wp_customize->add_section( 'bwpy_content_options_section' , array(
		'title'      => __( 'Content Options', 'bwpy' ),
		'priority'   => 100,
	) );
	
	// add setting for page comment toggle checkbox
	$wp_customize->add_setting( 'bwpy_page_comment_toggle', array( 
		'default' => 1 
	) );
	
	// add control for page comment toggle checkbox
	$wp_customize->add_control( 'bwpy_page_comment_toggle', array(
		'label'     => __( 'Show comments on pages?', 'bwpy' ),
		'section'   => 'bwpy_content_options_section',
		'priority'  => 10,
		'type'      => 'checkbox'
	) );
}
add_action( 'customize_register', 'bwpy_customizer' );

With this code saved to your functions file (or wherever you chose to build it), you should now see a new accordion section in your customizer titled “Content Options.”

customizer-content-options

Our option is built! At this point, we have a fully functional option ready to use in our theme because WordPress will store its value in the database based on what has been selected and saved.

You can check, uncheck, and save it all day long, though… it still means nothing at this point. Let’s put it to use in our theme by retrieving its value and using it in some simple conditional logic.

How to Use Theme Customizer Option Values

With our new control working in the customizer, we now have to put it to use in our theme. The goal was to show or hide the comments and comment form for WordPress pages based on this option. Let’s do that.

Because the setting section above hacked our new option into WordPress’ ability to save and retrieve option values, we can now use an awesome function to retrieve the saved values – get_theme_mod().

get_theme_mod() takes two simple parameters, the second of which is optional.

The first (and required) parameter is the ID of the control you’re retrieving the value for. The second (and optional) parameter is the default value. In this case, we don’t need to use it with our checkbox. So here’s what we’re left with.

get_theme_mod( 'bwpy_page_comment_toggle' )

This function returns a string meaning you can use it in a conditional to make a quick comparison like so.

if ( get_theme_mod( 'bwpy_page_comment_toggle' ) == 1 ) :
	// code to execute if our option value equals 1
endif;

If the option value equals 1, which means the box is checked, execute the code in the conditional… otherwise, don’t. Simple stuff.

So that’s how we’ll use it inside of our page.php template file. I’m working inside of a fresh of the Underscores (_s) Starter Theme so I’m going to use its page template for my example.

<?php get_header(); ?>

<div id="primary" class="content-area">
	<main id="main" class="site-main" role="main">

		<?php while ( have_posts() ) : the_post(); ?>

			<?php get_template_part( 'content', 'page' ); ?>
			
			<?php if ( get_theme_mod( 'bwpy_page_comment_toggle' ) == 1 ) : // show page comments? ?>

				<?php
					// If comments are open or we have at least one comment, load up the comment template
					if ( comments_open() || '0' != get_comments_number() ) :
						comments_template();
					endif;
				?>
			
			<?php endif; ?>

		<?php endwhile; // end of the loop. ?>

	</main>
</div>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

The part of our page template that’s responsible for displaying comments and the comment form is now wrapped in our conditional based on the option we created.

With the same setup built and saved into your development theme, go back to the customizer (make sure it’s refreshed) and in the preview, navigate to an actual WordPress page. Then toggle your control checkbox and watch the comments appear and disappear.

You now have a theme option. Endless possibilities, right?

WordPress Theme Customizer Possibilities

There are way too many ways to use the customizer to list them all here. We’d still be going another 1,500 words later.

Instead, let me give you a list of tips for using the customizer in your theme.

Controlling Built-in Customizer Sections

You may have already noticed that the customizer is part of your WordPress functionality whether you knowingly set it up to be or not. Here’s how that happens.

WordPress Default Customizer Sections

Site Title & Taglinetitle_tagline
Colorscolors
Header Imageheader_image
Background Imagebackground_image
Static Front Pagestatic_front_page

These section are already built into WordPress. Some of them display by default, like “Site Title & Tagline.” Others display when other functions built into a theme require theme, like add_theme_support( 'custom-header' ). That function adds custom header functionality to a theme and automatically builds a customizer option to control it.

The bottom line is that the above sections may appear in the customizer though you never wrote the actual customizer code to display them.

Remove Default Sections

Colors, Header Image, and Background Image are not built directly into the customizer. They’re built into WordPress and activated in the customizer when other code is written in your theme that depends on them.

Therefore, removing any of those sections means removing the theme features that created them. It’s your theme so you control that.

“Site Title & Tagline” and “Static Front Page” are slightly different.

These sections pertain to regular WordPress functionality. All WordPress installs have a field for the site title and tagline as well as the ability to choose a page as the front page.

So removing those sections is actually done in a similar fashion to adding sections. It’s done in the customize function you built before. All you need is the remove_section() method and the ID (given to you above) for the section you’re removing.

$wp_customize->remove_section( 'title_tagline' );
$wp_customize->remove_section( 'static_front_page' );

With those two lines of code inside of your bwpy_customizer() function, both the “Site Title & Tagline” and “Static Front Page” sections are gone. Too easy.

Change Default Section Titles

Because I just gave you the section IDs of the built in customizer sections, you probably realize that you can add new settings/controls to the built-in sections. That is 100% true.

For example, if you wanted to add an image uploader to the “Site Title & Tagline” section for logo functionality, it makes sense to change the default section title to something like “Site Title (Logo) & Tagline.”

Using the get_section() method, we can target the title of a section and easily overwrite it like so.

$wp_customize->get_section( 'title_tagline' )->title = __( 'Site Title (Logo) & Tagline', 'bwpy' );
Change Default Section Priorities

When we were building our custom section, we set the priority but didn’t really discuss it in detail. Why? Because we had nothing to compare it to. Now we do.

For every custom section that you create, you can set the priority yourself. But for the built-in sections, you’ll need to set them manually in order to logically position them along with your section. You can let it all flow naturally if you’d like. This is simply an option.

Here’s how you’d adjust built-in section priority using the get_section() method again along with the section IDs.

$wp_customize->get_section( 'title_tagline' )->priority = 30;
$wp_customize->get_section( 'static_front_page' )->priority = 70;

You may have noticed that I made all of the priorities multiples of 10 throughout this entire tutorial. This is something you want to do every time you’re ordering things using integers. Why? Because you leave yourself room to wiggle.

Say you have 45 options built into your theme customizer. That’s a little ridiculous but for the sake of this example, how horrible would it be if you realized you needed to add a new option right after the 22nd option and each option had a priority that was only one higher than the last?

That means you’d have to adjust every priority after your new option! Put priorities in multiples of 10 and you leave yourself plenty of room to adjust things later down the line without hassle.

WordPress Theme Customizer Resources

Normally I would link you to the WordPress Codex first but instead I’m going to link you to my favorite resource for building customizer options.

The WordPress Theme Customizer: A Comprehensive Developer’s Guide

I guess at this point it makes sense to link you to the official WordPress Codex page. The information is limited, though, so don’t stop there.

WordPress Theme Customization API

That’s just about all you will need. As long as you understand what the customizer does, how to add to it, and how to take away from it, the information you need to create options is all over the internet… especially here.

19 Comments:
  1. Many thanks for your post. You helped me a lot. Is there any option for upload image or choosing it from media library? I have found only ‘text’, ‘checkbox’ and other types for option control, but nothing for choosing image. Could you help me? Thanks

  2. Im pretty new to WP and webpage making and dont have deep insight into development. I’d like to make two “pages” with different languages, e.g. mydomain.com and mydomain/german. On each of these, I’d like to set different theme customizers with different settings, excerpt texts, etc. How to set/make two different theme customizers for the two pages? Thank you kindly

    • The theme customizer is meant to be functionality for the theme itself, not the pages of your WordPress site, which is independent from your theme. That’s not to say it can’t be done, but it will take custom development.

      If mydomain.com/german is a separate WordPress install from mydomain.com, this will not matter. Is this your own site or are you building a theme for distribution? If it’s just your own site, there’s no real reason to worry about the customizer. Just customize the theme.

  3. Thanks for the great article! Getting ready to add a bunch of customizer options to a client’s new site and this is exactly what I needed!

  4. Hi Sean,

    when I try to grab the ‘nav’ section, I get a PHP error: “Warning: Creating default object from empty value”. I’ve searched through the Internet more about this, and it seems that other people had this problem too, but had no luck in finding a solution. Also, when I do: var_dump( $wp_customize->sections() ); in order to inspect all the sections of the object, I just can’t find nav anywhere as a section, like it doesn’t exist.

    Do you have an idea how to deal with this issue?

    Many thanks, Nenad

    • Hi Nenad,

      WordPress 4.3 introduced a new structure to the core customizer and they completely changed the entire menu section. Unfortunately, nav no longer exists and that’s going to throw errors if you’re changing any of the sections values, as I’ve done in this article.

      At the moment, I don’t have time to study the new menus section to see what can be done about customizing it but because it’s an actual menu controls area now, I personally advise against customizing it. It’s no longer just an area for setting navigation locations. It’s now equivalent to going to Appearance -> Menus in the WordPress dashboard.

      That said, I’m going to remove all of the references to nav as it only matters prior to WordPress 4.3.

  5. Thanks for this text, it’s very useful. I want to know is there any way to add new Setting to default Section? Like to add Logo uploader into Site Identity section?

    Thanks again!

    • Hi Valeka. Sorry for the delayed reply. The default Site Identity section has an ID of title_tagline. So adding a logo uploader to it would be something like this:

      // logo uploader
      $wp_customize->add_setting( 'custom_logo', array( 'default' => null ) );
      $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, 'custom_logo', array(
      	'label'     => __( 'Custom Site Logo', 'custom' ),
      	'section'   => 'title_tagline',
      	'settings'  => 'custom_logo',
      	'priority'  => 20
      ) ) );
  6. That was probably the most simplest way to explain such a difficult topic. Thank a lot sean for making it easier to learn building theme options using the customizer.

  7. Hi.
    Thank you for the advice and thoughtful responses. Unfortunately, I’m such a newbie that it hasn’t answered my own question, which must be simple but I can’t find the answer elsewhere. I hope you can help. I’m setting up my site using (temporarily) the Twenty Sixteen theme and noticed that the header text is very small, even smaller than my post’s title. I wanted to make the header text larger, so I tried changing the CSS that is displayed when I right-click “Inspect Element” but nothing is saved/changed after changing the font size. Then I tried installing the Custom CSS plugin, but I have no idea how to make my change because there are no step-by-step directions. Can you help? Thank you in advance for any guidance you can provide!

  8. I probably did something stupid, but don’t know what it would be. When I save changes on the customizer, it saves the first time, but if I make more changes, and press save changes, it doesn’t save them. It also never changes the button to say saved. Any idea why that would be? Or where I could look for help?

Leave a Reply

Your email address will not be published. Required fields are marked *

*