How to extend customize control types to list pages

I have:
I’m currently using $wp_customize to add options to the customize theme area.

My Goal:
My goal is to extend $wp_customize so that I can display a list of available pages as checkboxes. I’ve been using Otto’s tutorial, but it only covers text areas. I’m aware that there is a dropdown-pages control type, but I’d like to be able to display the pages as a list of checkboxes, not a select element. So far I’ve managed the following:

Read More
add_action( 'customize_register', 'my_theme_customize_register' );

function my_theme_customize_register($wp_customize) {

     // CREATE A CLASS FOR DISPLAYING PAGES AS OPTIONS
    class Customize_Pages_Control extends WP_Customize_Control {
        public $type = 'pages';
        public function render_content() {
            $pages = get_pages(); ?>
            <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span> <?php
            foreach ($pages as $page) { ?>
                <label>
                    <input type="checkbox" value="<?php $page->ID ?>" data-customize-setting-link="<?php $page->ID ?>">
                    <?php echo $page->post_title; ?>
                </label> <?php
            }
        }
    }
    // ADD SECTION
    $wp_customize->add_section( 'home_page', array( 
        'title' => __( 'Home Page' ), 
        'priority' => 37, 
    ) );
    // ADD SETTING & CONTROL
    $wp_customize->add_setting( 'slideshow_pages' , array(
        'capability'    => 'edit_theme_options',
    ) );
    $wp_customize->add_control( new Customize_Pages_Control ( $wp_customize, 'slideshow_pages', array(
        'label' => __( 'Add pages to slideshow' ),
        'section' => 'home_page',
        'settings' => 'slideshow_pages',
        'type' => 'pages',
    ) ) );
}

This successfully adds the controls and lists the pages in the options menu, but I can’t figure out how to actually save the changes once the user checks the boxes off. Likewise I can’t currently use the any data that is saved (i.e. I can’t check which pages have been selected within the theme itself.)

Any help or pointers are greatly appreciated

Related posts

Leave a Reply

1 comment

  1. I realised I didn’t fully understand the link() function; now I realise that it links the control to the proper setting, making it problematic trying to point multiple controls to one setting. I modified my original function to instead add a hidden input that will hold my final value, along with the checkboxes. I then enqueued a small javascript that checks for changes to the checkboxes, adds the value to my hidden input and triggers a click event so that the page gets updated:

    class Customize_Pages_Control extends WP_Customize_Control {
        public $type = 'pages';
        public function enqueue() { // Enqueue script
            wp_register_script( 'lma-page-selector', get_stylesheet_directory_uri() . '/library/js/libs/lma-page-selector.js', array(), '', false );
            wp_enqueue_script( 'lma-page-selector' );
        }
        public function render_content() {
            $pages = get_pages(); ?>
            <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span> 
            <input type="hidden" value="" <?php $this->link()?>/> <?php // Field to hold final values
    
            foreach ($pages as $page) { // Loop through pages and add checkboxes 
            ?>
            <label>
                <input type="checkbox" value="<?php echo $page->ID ?>">
                <?php echo $page->post_title; ?>
            </label> <?php
            }
        }
    }
    

    And the javascript:

    jQuery(document).ready(function($) {
        $('.customize-control-pages input[type="checkbox"]').change(function() {
            var vals = $('.customize-control-pages input:checked').map(function() {
                return $(this).val();
            }).get().join(',');
            $('.customize-control-pages input[type="text"]').val(vals).trigger('change');
        }); 
    });
    

    It feels kludgy to me, but it seems to work. I’ll still need to add some sanitization there, but it’s a start. Hopefully someone might find it useful