Get it All
Together

The WordPress Customizer is an important part of the toolset of any developer who maintains their own custom base theme, whether we use that theme for projects or offer it up for sale. But I find there is a bit of a bedeviling problem with the Customizer and default theme modifications (theme_mods). Basically: there’s no built-in solution for them.

Consider the following scenario: a theme uses a scaffolding framework like Zurb Foundation to produce completely-custom layouts, and therefore does not have a “base state,” as would be present with most commercial themes. In commercial theme sales, the idea is to create a theme which is hopefully 80% of the way to someone’s perfect website. A developer then buys the theme, making small adjustments in a child theme to cover that last 20%.

But this theme is a toolbox aimed at providing unlimited layout options. If I want a horizontal-stripe layout for one page and a standard blog header/footer/content/sidebar layout on another, this theme will allow it. There are no assumptions as to what you’d want out of the theme. As such, in order for the theme to present ANYTHING on the front end, it’s going to need some default mods. Actually, rather a lot of them. But the solution is pretty simple, in theory: just load a default set of mods if nothing has been saved in the Customizer.

Here’s where it gets tricky: unless you’ve modified a value in the WordPress Customizer, it does not save to the theme mods for the theme. So if you open a WordPress Customizer, change a few values, then hit “Publish”, those mods and ONLY those mods would get saved to the database. That makes life difficult if you’re looking to quickly check to see if anyone has modified the theme as in the above scenario.

Digging around, I discovered that the WordPress Customizer ships with a number of filters. But for our purposes, there is the customize_save hook, where we will insert our own check for default values:

I’m sure I’m not alone among developers who are continually frustrated by the lack of imagination shown for implementing the Customizer in WordPress. Sure, I have praised its existence and support its use to replace the labyrinthine system of developer-created admin pages. But then once I got into serious development work, I quickly found that having all the HTML controls handed to you means having the ability to decide how they get rendered taken away from you.

For example, I’d like to give users of my core theme the option to define the number and content of columns on their site. Doing so obviously means creating repeating fields: first, you define the user-specified number of columns, then you produce enough identical fields as necessary to define each column. In my case, that meant providing an ID, column width at various responsive sizes and of course, the content of the column.

Yes. I could certainly decide that no one needs more than four columns and just assign each column it’s own static block of controls. If there’s no Column 4, then those settings are just ignored. But this is a sloppy way to build a UI that is going to naturally lead to some confusion when changing settings never seem to have any effect. Better, then to just have dynamically created settings blocks. One drawback: the Customizer API has no repeating fields and doesn’t even include a vehicle for a button that doesn’t submit, leaving you without the option to create a JS-driven solution.

After months of frustration, I eventually found Kirki. Now, we are talking! I currently include Kirki as a Composer package into the core of my base theme, but it’s also available as a plugin for those who would be more comfortable with that solution. From the Kirki homepage:

Kirki is a Toolkit allowing WordPress developers to use the Customizer and take advantage of its advanced features and flexibility by abstracting the code and making it easier for everyone to create beautiful and meaningful user experiences.

So, it’s not an entirely new API or a replacement. It simply harnesses the power already manifest in the Customizer, but gives it a few gooses that make it a whole heck of a lot easier and more flexible to use.

Using Kirki

Kirki frees you to create forms that properly express what your theme does, rather than having to build all that functionality into your theme or worse than this, simply allow your theme to be driven by the limitations of the current Customizer UI. A full spectrum of HTML5 form elements is introduced, along with a plethora of more exotic controls. Especially useful for me – beside the repeater control – were the multicheck and radio-image controls. But there’s so many more that I’d like to play around with! Maybe for some custom implementations, I suppose.

Replacing the existing Customizer API calls with the Kirki API calls was a snap in fact, about the only confusion was that there was so much less code than before, I had to keep checking that I’d actually gotten all the controls passed over:

 // Icon Fonts:
Kirki::add_field( 'hn_reactive', array(
'type' => 'multicheck',
'settings' => 'icon_fonts',
'label' => esc_attr__( 'WeLoveIconFonts', 'hn_reactive' ),
'section' => 'icon_fonts',
'priority' => 10,
'choices' => ReactiveCustomizer::$icon_fonts,
) );

I use nine fonts from WeLoveIconFonts.com, so as you might imagine, a huge selection of code simply disappeared when this Kirki version replaced it. Who doesn’t love that??

As for building repeatable blocks of controls, this too is a simple matter:

/* 
// Columns:
*/
Kirki::add_field( 'hn_reactive', array(
	'type'        => 'repeater',
	'label'       => esc_attr__( 'Column Definitions', 'hn_reactive' ),
	'section'     => 'hn_layout_defaults',
	'priority'    => 9,
	'settings'    => 'column_contents',
	'default'     => array(
		array(
			'content' 	=> 'post_data',
			'small'		=> '9'
		),
		array(
			'content'	=> 'default',
			'small'		=> '3'
		),
	),
	'row_label'		=> array(
		'type'		=> 'text',
		'value'		=> 'Column'
	),
	'fields' => array(
		'col_id' => array(
			'type'			=> 'text',
			'label'			=> esc_attr__( 'CSS Column ID', 'my_textdomain' ),
			'description'	=> esc_attr__( 'Any XHTML-compatible ID you like', 'my_textdomain' )
		),
		'content' => array(
			'type'			=> 'select',
			'label'			=> esc_attr__( 'Content', 'my_textdomain' ),
			'description'	=> esc_attr__( 'Specify what kind of content will go in this column', 'my_textdomain' ),
			'choices'		=> $this->content_choices(),
		),
		'small' => array(
			'type'			=> 'text',
			'label'			=> esc_attr__( 'Cols at small', 'my_textdomain' ),
			'description'	=> esc_attr__( 'How many grid columns this column takes up at small and up sizes.', 'my_textdomain' ),
		),
		'medium' => array(
			'type'			=> 'text',
			'label'			=> esc_attr__( 'Cols at medium', 'my_textdomain' ),
			'description'	=> esc_attr__( 'How many grid columns this column takes up at medium and up sizes.', 'my_textdomain' ),
		),
		'large' => array(
			'type'			=> 'text',
			'label'			=> esc_attr__( 'Cols at large', 'my_textdomain' ),
			'description'	=> esc_attr__( 'How many grid columns this column takes up at large and up sizes.', 'my_textdomain' ),
		)
	)
) );

I have so far found Kirki to be exactly the tool that I need, until of course WordPress comes up with their own solution.. and who knows when that will be?