Video icon 64
Learning to code? Skill up faster with our practical video courses. Start your free trial today.
Advertisement

Digging Into the Theme Customizer: Practicing I

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →
This post is part of a series called Digging Into the Theme Customizer.
Digging Into the Theme Customizer: Components
Digging Into the Theme Customizer: Practicing II

After going through previous posts in this series, I presume that you understand the Theme Customizer components and how to add, remove, and configure them.

It seems there are many things to figure out, and it will be a good exercise to put into action everything we've learned.

In this post, I will cover some of the most important things about the Theme Customizer through several examples. This should result in greater understanding of the features as opposed to simply reading an article that doesn't include any code.


Before We Start

  • Ensure you've already read the previous part covering details of components in the Theme Customizer. Of course, refer to it if you forget something.
  • Theme Customizer ties to theme's structure, of course, so the best way to integrate it to your theme is to implement it right when you're developing your theme; however, in a limited post, we won't create a new theme to do that, I will use TwentyEleven and will modify it for demonstration purposes.

Adding a New Section

Opening the functions.php file, write the following code inside it:

function wptuts_theme_customizer( $wp_customize ) {
	$wp_customize->add_section( 'wptuts', array(
		'title' => 'WPTuts+', // The title of section
		'description' => 'Settings of WPTuts section', // The description of section
	) );

	// The latter code snippets go here.
}
add_action( 'customize_register', 'wptuts_theme_customizer', 11 );

First of all, the wptuts_theme_customizer function will hook onto the customize_register action which an important action used to register new options in the Theme Customizer. Note that this function has a parameter of $wp_customize, as previously mentioned, is a global variable and an instance of WP_Customize_Manager class which manages all other components in the Theme Customizer.

In order to add a new section, $wp_customize has a method named add_section. As you can see, the "our news section" has the id wptuts, this is an important thing to remember for later.

The title and description attributes indicate what to display when rendering a component.

Notice that the new section will never display in menu bar in Theme Customize page until it has at least one setting and one control.


Setting Up Options

Inside the wptuts_theme_customizer function, append the following code:

$wp_customize->add_setting( 'wptuts_welcome_text', array(
	'default' => 'Hello world',
	// Let everything else default
) );

Then, to integrate this setting into our section, we have to create a new control which connects the new section and the new setting:

$wp_customize->add_control( 'wptuts_welcome_text', array(
	// wptuts_welcome_text is a id of setting that this control handles
	'label' => 'Welcome text',
	// 'type' =>, // Default is "text", define the content type of setting rendering.
	'section' => 'wptuts', // id of section to which the setting belongs
	// Let everything else default
) );

With the id wptuts_welcome_text, the new control would associate the setting that has this id with the respective section. And the results will be:

digging-into-theme-customizer-part-3-practicing-1

The first thing you need to notice is we don't need to declare the id of the new control is the same as the id of the setting. We can also do this:

$wp_customize->add_control( 'some_other_setting1', array(
	'label' => 'Welcome text',
	'settings' => 'wptuts_welcome_text',
	'section' => 'wptuts',
) );

It works the same as the first time we used it. Essentially, if we don't pass the value for the settings property, then the control will use its id as the id of the setting it controls.

This point lets us know that each setting can be used by many different controls. This also means that each setting can be displayed many times in numerous sections (although this seems unnecessary). For example, replace our control by:

$wp_customize->add_control( 'some_other_setting1', array(
	'label' => 'Welcome text',
	'settings' => 'wptuts_welcome_text',
	'section' => 'wptuts',
) );

$wp_customize->add_control( 'some_other_setting2', array(
	'label' => 'Welcome text',
	'settings' => 'wptuts_welcome_text',
	'section' => 'title_tagline',
) );

Check the results, our setting displays in both Site title & Tagline and WPTuts section.

digging-into-theme-customizer-part-3-practicing-2

Each setting can be used by many controls.

Secondly, the default value of this setting is retrieved from the current theme's wptuts_welcome_text option using the get_theme_mod function.

Since this theme option does not exist, the default property will be used. So we have a textbox with the value of "Hello world". To check if it works with the Theme Customizer or not, we might try to output the value of this setting somewhere in our template.

Let's open the header.php file and prepend the following code to the end and save:

<?php echo get_theme_mod( 'wptuts_welcome_text' ); ?>

Go back to the Theme Customizer page, refresh and try to change some other value of our settings, "Hi, thanks for reading!", for example, and see the changes. The results display instantly right in the Preview frame, so cool!

digging-into-theme-customizer-part-3-practicing-3

Thirdly, we don't assign any values for the type setting, then the default value for theme_mod would be applied, this explains the reason why we use the get_theme_mod function to get the value of this setting. You could change this value to option, and use get_option to get the value instead of get_theme_mod. Try to add the following snippets to the end of the above wptuts_theme_customizer function:

	$wp_customize->add_setting( 'wptuts_welcome_again', array(
		'default' => 'Hello again',
		'type' => 'option',
	) );

	$wp_customize->add_control( 'some_other_setting3', array(
		'label' => 'Welcome text again',
		'settings' => 'wptuts_welcome_again',
		'section' => 'wptuts',
	) );
digging-into-theme-customizer-part-3-practicing-4

Output the value of wptuts_welcome_again right after get_theme_mod( 'wptuts_welcome_text' ) in header.php.

<?php
echo get_theme_mod( 'wptuts_welcome_text' ) . " ";
echo get_option( 'wptuts_welcome_again' );
?>

Check the result:

digging-into-theme-customizer-part-3-practicing-5

Great, let's try out another example by adding one more setting:

	$wp_customize->add_setting( 'wptuts_footer', array(
		'default' => 0,
	) );

	$wp_customize->add_control( 'wptuts_footer', array(
		'label' => 'Hide footer section',
		'type' => 'checkbox',
		'section' => 'wptuts',
	) );

We just add a new option displaying a checkbox which allows us to choose whether or not to hide the footer section. Next, open the footer.php file, find the following code:

<div id="site-generator">

and replace by:

<div id="site-generator" <?php echo ( get_theme_mod( 'wptuts_footer' ) ) ? "style='display:none;'" : "" ?> >

The above code will check if get_theme_mod('wptuts_footer') returns false (or value of 0), then display the style='display:none;' attribute-value pair which hides the div element containing it, if not, output nothing. Finally, we have a simple checkbox option, try to click it, the footer section's content will hide instantly.

digging-into-theme-customizer-part-3-practicing-10

So what happens if the id setting we intend to use existed? Well, the setting will simply use the existing option without adding a new option entry. In the next section, we will show a simple demo about that.


Using Existing Option

Settings -> Discussion in the admin dashboard has an option whose title is Default Avatar. I will bring this option to the Theme Customizer page. This option has the id avatar_default, so:

	$wp_customize->add_setting( 'avatar_default', array(
		'default' => get_option( 'avatar_default' ),
		'type' => 'option',
	) );

	$wp_customize->add_control( 'avatar_default', array(
		'label' => 'Avatar Default',
		'section' => 'wptuts',
		'type' => 'radio',
		'choices' => array(
			'mystery' => 'Mystery Man',
			'blank' => 'Blank',
			'gravatar_default' => 'Gravatar Logo',
			'identicon' => 'Identicon (Generated)',
			'wavatar' => 'Wavatar (Generated)',
			'monsterid' => 'MonsterID (Generated)',
			'retro' => 'Retro (Generated)',
		),
	) );

The above control defines the setting's content type as radio, and radio must have a list of choices. I passed the values and titles of each choice though the choices attribute where the key is the value of the option (would be used as value attribute in HTML tag), and the value of the key is the title that displays after the radio button.

The result:

digging-into-theme-customizer-part-3-practicing-6

Try to change the value:

digging-into-theme-customizer-part-3-practicing-7

or

digging-into-theme-customizer-part-3-practicing-8

You also change the type in the control to select. And we would have:

digging-into-theme-customizer-part-3-practicing-9

Let's try another type of control: dropdown-pages yourself. You will see a selection containing all pages and the value of settings will be the ID of the selected page when retrieving it.


Safely Create a New Component

Adding a new component whose id is a duplicate of an existing one can cause serious errors, and can even affect other components' activities and data.

So before creating something new, checking whether or not a component with the same id exists.

	// Check section
	if ( ! in_array( 'section_id_to_check', array_keys( $wp_customize->sections() ) ) ) {
		$wp_customize->add_section( 'section_id_to_check', array(
			//
		) );
	}
	// Check setting
	if ( ! in_array( 'setting_id_to_check', array_keys( $wp_customize->settings() ) ) ) {
		$wp_customize->add_setting( 'setting_id_to_check', array(
			//
		) );
	}
	// Check control
	if ( ! in_array( 'control_id_to_check', array_keys( $wp_customize->controls() ) ) ) {
		$wp_customize->add_control( 'control_id_to_check', array(
			//
		) );
	}

The $wp_customize->sections() method will return an array containing id-object pairs of all sections in the Theme Customizer. By using the array_keys function, I obtain a new array containg all IDs of the old array.

Next, check if the id of the component we suppose to add is in that new array or not, then decide to add new component or do nothing.


Creating a Group of Settings

Like with the Settings API, when you create a setting option, it will be written into the option database table as an entry. If we have 10 setting options, then we would have 10 entry rows in the option table, it seems so wasteful. Why don't we put all our setting options into only a single entry. It makes the database tidy and easy to manage. Below is an example:

	$wp_customize->add_setting( 'wptuts[number]', array(
		'default' => 1,
		'type' => 'option',
	) );

	$wp_customize->add_control( 'wptuts[number]', array(
		'label' => 'WPTuts+ number',
		'section' => 'wptuts',
	) );

	$wp_customize->add_setting( 'wptuts[email]', array(
		'default' => 'mail@mail.com',
		'type' => 'option',
	) );

	$wp_customize->add_control( 'wptuts[email]', array(
		'label' => 'WPTuts+ email',
		'section' => 'wptuts',
	) );

	$wp_customize->add_setting( 'wptuts[ads]', array(
		'default' => 0,
		'type' => 'option',
	) );

	$wp_customize->add_control( 'wptuts[ads]', array(
		'label' => 'Display advertise banners',
		'type' => 'checkbox',
		'section' => 'wptuts',
	) );

As you can see, now, we have a wptuts option group containing our other setting options. To get the value of a particular setting, we might do it like this:

$wptuts = get_option( 'wptuts' ); // array
$number = $wptuts['number'];
$email = $wptuts['email'];
$ads = $wptuts['ads'];

Then use those variables anywhere you want. It seems simple, I highly recommend to do it this way.


Conclusion

We've covered a lot, but it's not enough. In the next part, we will look at several other important factors such as Sanitization, Transport attributes and Extended components.

Again, I'm looking forward to hearing from you, any comments would be appreciated!

Advertisement