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 ); ?>