Take a look at the source of wp_dropdown_categories()
. It uses walk_category_dropdown_tree()
to render the output. Right after that you have a filter named wp_dropdown_cats
that allows altering the final MarkUp:
$output = apply_filters( 'wp_dropdown_cats', $output );
You could now use a Regex and preg_replace
or parse it using DOMDocument
, etc.
Keep in mind that you should change the select
elements Name
attribute as well – else you wouldn’t be able to save an array. Example:
<select multiple name="foo[]" ...>
Still you’ll need to change the walker
argument and rewrite the Walker itself. The reason can be read in Walker_CategoryDropdown::start_el
:
if ( $category->term_id == $args['selected'] )
$output .= ' selected="selected"';
As you can see currently it’s checking only a single value, not an array. So basically you’ll need a check against your array. Example overriding method that checks against an array:
public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
$pad = str_repeat(' ', $depth * 3);
$cat_name = apply_filters('list_cats', $category->name, $category);
$output .= "<option class=\"level-{$depth}\" value=\"{$category->term_id}\"";
# >>> HERE WE GO:
if ( in_array( $category->term_id, $args['selected'] ) )
$output .= ' selected="selected"';
$output .= '>';
$output .= $pad.$cat_name;
if ( $args['show_count'] )
$output .= "({$category->count})";
$output .= "</option>";
}
Put above method in a new class that extends Walker_CategoryDropdown
and put that new Walker class as argument into your args array for wp_dropdown_categories()
:
wp_dropdown_categories( array(
'walker' => new Custom_Walker_CategoryDropdown
'selected' => get_option( 'foo' )
# etc…
) );
As you can see, I added the option foo
, which comes from the name="foo[]"
above. The specific implementation is up to you. This answer shall just serve as guide towards your solution.