Creating settings with the Customize JS API

My article from last week was about creating panels, sections, and controls with the JS API of the customizer. This post describes how to register settings with the Customize JS API, which usually are created via the PHP API.

Mostly you know exactly which settings are needed, so it is not a problem to create them via PHP. But, for example, currently, I have the case that I want to let the user create additional instances of sections with controls, similar to the menu management in the customizer. So I do not know how many settings I need to save the values, and for that, it is useful to create the settings via JS, but that is slightly more complicated than registering panels, sections, and controls.

For preparation, we enqueue a JS file into the customizer like described in the post from last week, and insert the following code:

/**
 * Custom JavaScript functions for the customizer controls.
 *
 * @version 2.0.0
 *
 * @package Hannover
 */
;(function (api) {
	api.bind('ready', function () {
		// Create a setting.
		var setting = new api.Setting( 'portfolio_category_page' );
		api.add( setting );
	});
})(wp.customize);

That is the JS part for creating a setting with the ID portfolio_category_page. That looks easier than the part of last week’s article, but we need to use a PHP filter to get the portfolio_category_page setting working. For that, we add the following code into an appropriate PHP file, for example, the file you used for enqueuing the JS file:

// Filter the dynamically created customizer settings.
add_filter( 'customize_dynamic_setting_args', 'hannover_filter_dynamic_setting_args', 10, 2 );

/**
 * Filters a dynamic setting’s constructor args.
 *
 * For a dynamic setting to be registered, this filter must be employed
 * to override the default false value with an array of args to pass to
 * the WP_Customize_Setting constructor.
 *
 * @link https://wordpress.stackexchange.com/a/286503/112824
 *
 * @param false|array $setting_args The arguments to the WP_Customize_Setting constructor.
 * @param string      $setting_id   ID for dynamic setting, usually coming from `$_POST['customized']`.
 *
 * @return array|false
 */
function hannover_filter_dynamic_setting_args( $setting_args, $setting_id ) {
	if ( 'portfolio_category_page' === $setting_id ) {
		$setting_args = [
			'type' => 'theme_mod',
		];
	}
	return $setting_args;
}

We hook the hannover_filter_dynamic_setting_args() function to the customize_dynamic_setting_args filter, which gets the arguments of the setting and the ID as params. This function now gets called for every setting – $setting_args is false by default for settings that are registered via the JS API, and if this is the value that gets returned, the setting is not registered.

So we need to modify $setting_args for all settings we registered via the JS API and convert it to an array. In our example, we check for the exact ID portfolio_category_page and modify $setting_args in that case. Here you can use all options from the PHP method to add a setting, so for example, define a sanitize callback.

If you have settings with the format portfolio_category_page[1], portfolio_category_page[2], and portfolio_category_page[3], the check in hannover_filter_dynamic_setting_args() should be done via a regex, to match multiple settings. Weston Ruter linked to various examples in core and plugin in an answer on wordpress.stackexchange.com.

Now it should be possible to use the setting portfolio_category_page for a control.

Related posts

Leave a Comment

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