Adding arbitrary HTML to a WordPress Theme Customizer section

Say you have built a really amazing WordPress theme, and have enabled its users to tailor it to suit their needs with a really amazing custom section in the Theme Customizer (that you put together after following one or more of these Theme Customizer tutorials):

customizer1

Well, the theme really takes off, enough so that at the next WordCamp, people are coming up and complimenting you on your great work. Then one particularly enthusiastic blogger shakes your hand and says, “You know, I really love how you let users customize The Important Stuff, but I’m a little confused about the Fox setting. I’ve watched that video at least 100 times now, and at no point is the guy with the ears singing about ossifers or, uh, alfalfa, or whatever.”

“Oh!” you say. “Oss-en-fay. Sha fafa. Those are for the Frim Fram Sauce.”

At which point the blogger, misinterpreting your explanation, backs away slowly before turning and running over to the event security booth. Meanwhile you are sitting there lamenting the fact that there’s no good method for visually separating and labeling checkbox controls in a way that is consistent with the other available types of controls in the Customizer.

Fortunately, I have a solution to the problem in this highly realistic scenario. You can create a custom control that doesn’t actually control a setting, and have it output arbitrary HTML into your Theme Customizer section. Here’s what the control looks like:

if ( class_exists( 'WP_Customize_Control' ) && ! class_exists( 'ThemeName_Customize_Misc_Control' ) ) :
class ThemeName_Customize_Misc_Control extends WP_Customize_Control {
	public $settings = 'blogname';
	public $description = '';


	public function render_content() {
		switch ( $this->type ) {
			default:
			case 'text' :
				echo '<p class="description">' . $this->description . '</p>';
				break;

			case 'heading':
				echo '<span class="customize-control-title">' . esc_html( $this->label ) . '</span>';
				break;

			case 'line' :
				echo '<hr />';
				break;
		}
	}
}
endif;

Let’s break this down a bit:

public $settings = 'blogname';
public $description = '';

Each control has to be related to a Theme Customizer setting, or you’ll get an error. This control doesn’t relate to a setting, so the first line is a bit hacky, but it’s just assigning the control to one of the default settings that is unlikely to be modified by another process (the site title). The second line is declaring a property that isn’t found in the parent WP_Customize_Control class so that you can use it later on with the text type.

public function render_content() {

The name of this method is important, because it needs to overwrite the method in the parent class.

switch ( $this->type ) {

Using the type property is kind of arbitrary, but it lets you follow the same convention as the parent class for specifying the type of control to output, e.g. checkbox, radio etc. The switch cases that follow are where you define your own types and the HTML that will be output for each.

So how do you use this class? In the same function that you’re using to add other settings and controls, like this:

$wp_customize->add_control(
	new ThemeName_Customize_Misc_Control(
		$wp_customize,
		'themename_frimfram-heading',
		array(
			'section'  => 'the-important-stuff',
			'label'    => __( 'The Frim Fram Sauce', 'themename' ),
			'type'     => 'heading',
			'priority' => 35,
		)
	)
);

Note that in the control class, the heading case uses the label property for the heading text. So this will get you something that looks like this:

customizer2

All well and good. But the Frim Fram Sauce still needs a bit more explanation…

$wp_customize->add_control(
	new ThemeName_Customize_Misc_Control(
		$wp_customize,
		'themename_frimfram-text',
		array(
			'section'     => 'the-important-stuff',
			'description' => __( 'I don\'t want fish cakes and rye bread / You heard what I said / Waiter please, I want mine fried.', 'themename' ),
			'type'        => 'text',
			'priority'    => 36,
		)
	)
);

There. See how the $description property defined above in the control class is being used here? You could technically use label again, or any other property name you want to define, but I chose description because it follows a similar convention to the add_section method.

customizer3

With a sigh, you realize that someone is still not going to comprehend the separateness of the Fox and the Frim Fram. You need to DRAW A LINE between the Norwegian synthpop and the 1940′s jazz classic:

$wp_customize->add_control(
	new ThemeName_Customize_Misc_Control(
		$wp_customize,
		'themename_frimfram-line',
		array(
			'section'  => 'the-important-stuff',
			'type'     => 'line',
			'priority' => 34,
		)
	)
);

customizer4

Subtlety be damned.

Leave a Reply