How To Add Multi-Select WP Customizer Setting

By August 14, 2017 Blog, Sage, Wordpress
WordPress Tutorials by Allure Web Solutions

I will show how to add a multi-select input field in the WP Customizer Setting. My specific example will be for the Sage 9 theme, but it can be adjusted slightly to work with any theme or plugin.

What I do in this example is create a multi-select that lets you exclude categories from a custom post loop. In my case “project types” are just categories.

The Functions

In Sage 9, add these to your app/helpers.php file. In other themes, add it to functions.php.

/**
 * Multiselect option for WP Customizer
 *
 * @param $wp_customize
 */
add_action( 'customize_register', __NAMESPACE__ . '\\multiselect_customize_register' );
function multiselect_customize_register( $wp_customize ) {
	/**
	 * Multiple select customize control class.
	 */
	class Sinfonia_Customize_Control_Multiple_Select extends \WP_Customize_Control {

		/**
		 * The type of customize control being rendered.
		 */
		public $type = 'multiple-select';

		/**
		 * Displays the multiple select on the customize screen.
		 */
		public function render_content() {

			if ( empty( $this->choices ) ) {
				return;
			}
			?>
            <label>
                <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
                <select <?php $this->link(); ?> multiple="multiple" style="height: 100%;">
					<?php
					foreach ( $this->choices as $value => $label ) {
						$selected = ( in_array( $value, $this->value() ) ) ? selected( 1, 1, false ) : '';
						echo '<option value="' . esc_attr( $value ) . '"' . $selected . '>' . $label . '</option>';
					}
					?>
                </select>
            </label>
		<?php }
	}
}

/**
 * Get all categories
 * 
 * @return array
 */
function project_types() {
	$cats    = array();
	$cats[0] = 'None';
	foreach ( get_categories() as $categories => $category ) {
		$cats[ $category->term_id ] = $category->name;
	}

	return $cats;
}

/**
 * Validate the options against the existing categories
 *
 * @param  string[] $input
 *
 * @return string
 */
function project_types_sanitize( $input ) {
	$valid = project_types();

	foreach ( $input as $value ) {
		if ( ! array_key_exists( $value, $valid ) ) {
			return [];
		}
	}

	return $input;
}

// Credits: https://stackoverflow.com/questions/10936059/how-to-convert-items-in-array-to-a-comma-separated-string-in-php

Add Customizer Controls

In Sage 9, add these to app/admin.php inside hereĀ add_action( 'customize_register', function ( \WP_Customize_Manager $wp_customize ) {}. In other themes, you can add this to functions.php, but make sure to wrap this in the add_action('customize_register') method.

/**
 * Add Custom Theme Options
 */
$wp_customize->add_panel( 'theme_options', array(
	'priority'       => 10,
	'capability'     => 'edit_theme_options',
	'theme_supports' => '',
	'title'          => __( 'Theme Options', 'textdomain' ),
	'description'    => __( 'Theme specific options', 'textdomain' ),
) );

/**
 * Home Page
 */
$wp_customize->add_section( 'home', array(
	'priority'       => 10,
	'capability'     => 'edit_theme_options',
	'theme_supports' => '',
	'title'          => __( 'Home Page', 'textdomain' ),
	'description'    => 'Settings for the home page',
	'panel'          => 'theme_options',
) );

// Project Types
$wp_customize->add_setting( 'project-types', array(
	'type'       => 'theme_mod',
	'capability' => 'edit_theme_options',
	'transport'  => '',
	'sanitize_callback' => 'App\project_types_sanitize'
) );

$wp_customize->add_control(
	new Sinfonia_Customize_Control_Multiple_Select(
		$wp_customize,
		'multiple_select_setting',
		array(
			'settings' => 'project-types',
			'label'    => 'Select which project types you want to exclude from the home page',
			'section'  => 'home', // Enter the name of your own section
			'type'     => 'multiple-select', // The $type in our class
			'choices'  => project_types() // Your choices
		)
	)
);

The Custom Post Loop

We did all the above for lines 3 and 6. In line 3 we check if any categories are excluded from the customizer and then exclude them from the query.

<?php
	$paged      = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
	$categories = ( get_theme_mod( 'project-types' )[0] !== 0 ? '-' . implode( ',-', get_theme_mod( 'project-types' ) ) : '' );
	$args       = array(
		'post_type'      => array( 'post' ),
		'cat'            => $categories,
		'posts_per_page' => '8',
		'nopaging'       => false,
		'paged'          => $paged,
	);

	$query = new \WP_Query( $args );
?>

 

Mike Doubintchik

Author Mike Doubintchik

More posts by Mike Doubintchik

Leave a Reply