Out-of-the-box the WordPress function wp_dropdown_pages() does not support the multiple attribute. Luckily it’s not that hard to do and even better: you don’t need to do too much hacking to achieve this.
Select list with multiple selected items generated with the wp_dropdown_pages() function.
The codex does not mention the walker option but it is possible to pass a Walker object in the wp_dropdown_pages() argument list. We will need to customize the Walker object in order to get the functionality we want.
When customizing the Walker implementation we simply extend the original Walker_PageDropdown class and do slight adjustments to it so it will respect multiple selected values.
The theme file functions.php could be a good place to define the class; or even in its own plugin.
Implementation of our Walker extension Walker_PageDropdown_Multiple:
<?php if ( !class_exists( 'Walker_PageDropdown_Multiple' ) ) { /** * Create HTML dropdown list of pages. * * @package WordPress * @since 2.1.0 * @uses Walker */ class Walker_PageDropdown_Multiple extends Walker_PageDropdown { /** * @see Walker::start_el() * @since 2.1.0 * * @param string $output Passed by reference. Used to append additional content. * @param object $page Page data object. * @param int $depth Depth of page in reference to parent pages. Used for padding. * @param array $args Uses 'selected' argument for selected page to set selected HTML attribute for option element. * @param int $id */ function start_el(&$output, $page, $depth, $args, $id = 0) { $pad = str_repeat( isset( $args['pad'] ) ? $args['pad'] : '--', $depth ); $output .= "\t<option class=\"level-$depth\" value=\"$page->ID\""; if ( in_array( $page->ID, (array) $args['selected'] ) ) $output .= ' selected="selected"'; $output .= '>'; $title = apply_filters( 'list_pages', $page->post_title, $page ); $title = apply_filters( 'pagedropdown_multiple_title', $title, $page, $args ); $output .= $pad . ' ' . esc_html( $title ); $output .= "</option>\n"; } } } ?>
Now you’re all set to use the wp_dropdown_pages() function with multiple selected values.
Usage example:
<?php $selected = array( 1, 2, 3 ); $args = array( 'echo' => 0, 'walker' => new Walker_PageDropdown_Multiple(), // be sure to pass an instance of our new Walker class 'selected' => $selected // The selected option can now be an array as well as a string ); $pagesDropdown = wp_dropdown_pages( $args ); // Remove the wrapping select tag from the options so we can use // our own select tag with the multiple attribute $options = preg_replace( '#^\s*<select[^>]*>#', '', $pagesDropdown ); $options = preg_replace( '#</select>\s*$#', '', $options ); ?> <select name="my-multiple-valued-select" multiple="multiple"> <?php echo $options; ?> </select>
Bonus feature: You can change the “padding” string with the unofficial pad option. In my implementation it defaults to two hyphens per level (–).