Add filter to wp_dropdown_pages() or wp_dropdown_categories() – no select container?

A filter called wp_dropdown_pages exists in the wp_dropdown_pages() function. That filter allows you to modify the output of the function. However, for the thing you want to do I would not recommend using this filter since this will apply to all code that calls wp_dropdown_pages(), including plugins.

So, one way to approach your situation may be to simply strip off the <select> markup. You could use regular expressions like this:

$ddp = wp_dropdown_pages(array(
    'echo' => FALSE, // return the HTML instead of outputting it
));
$ddp = preg_replace('~^<select[^>]*+>\s*~', '', trim($ddp)); // opening select tag
$ddp = preg_replace('~\s*</select>$~', '', $ddp); // closing select tag

That way you are left with just the <option>s. Do the same for the category dropdown, concatenate the strings and wrap it with your own <select>.

Note: I am well aware that using regex to parse HTML is evil. It’s dirty, yet, it does the job.

A cleaner way to build the select list you want is to avoid the built-in dropdown functions altogether and instead use the functions get_pages() and get_categories(). Those return an array, which you can loop over to build your own markup. A basic example follows.

$pages = get_pages();
$categories = get_categories();

$html="<select>";
foreach ($pages as $page)
{
    $html .= '<option value="page-'.$page->ID.'">'.esc_html($page->post_title).'</option>';
}
foreach ($categories as $category)
{
    $html .= '<option value="category-'.$category->term_id.'">'.esc_html($category->name).'</option>';
}
$html .= '</select>';

Leave a Comment