Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have multiple menus in my blog. I have Top Menu and Header menu. These menus appear separately in the desktop version of my website. However, I would like to merge both these menus into a single dropdown menu with the appropriate headings. Example follows:

<select>
  <optgroup label="Top Menu">
    <option value="Home">Home</option>
    <option value="Contact Us">Contact Us</option>
  </optgroup>
  <optgroup label="Header Menu">
    <option value="Category 1">Category 1</option>
    <option value="Category 2">Category 2</option>
    <option value="Category 3">Category 3</option>
    <option value="Category 4">Category 4</option>
  </optgroup>
</select>

I am currently using the Walker function below to populate the existing dropdown with a single menu item list:

//Code in header.php

<?php wp_nav_menu(array(
                      'theme_location' => 'menu_main', // your theme location here
                      'walker'         => new Walker_Nav_Menu_Dropdown(),
                      'items_wrap'     => '<select id="nav_iphone" name="nav_iphone" onchange="if (this.value) window.location.href = this.value;"><option value="">Select an option to navigate</option>%3$s</select>',
                        ));
                    ?>

//Code in function.php
        class Walker_Nav_Menu_Dropdown extends Walker_Nav_Menu{

            var $to_depth = -1;

            function start_lvl(&$output, $depth)
            {

                $output .= '</option>';

            }

            function end_lvl(&$output, $depth)
            {

                $indent = str_repeat("\t", $depth); // don't output children closing tag

            }


            function start_el(&$output, $item, $depth, $args)
            {

                $indent = ( $depth ) ? str_repeat( "&nbsp;", $depth * 4 ) : '';

                $class_names = $value = '';

                $classes = empty( $item->classes ) ? array() : (array) $item->classes;

                $classes[] = 'menu-item-' . $item->ID;



                $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );

                $class_names = ' class="' . esc_attr( $class_names ) . '"';



                $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );

                $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';



                $value = ' value="'. $item->url .'"';

                $output .= '<option'.$id.$value.$class_names.'>';



                $item_output = $args->before;

                $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;

                $output .= $indent.$item_output;

            }


            function end_el(&$output, $item, $depth)
            {

                if(substr($output, -9) != '</option>')

                    $output .= "</option>"; // replace closing </li> with the option tag

            }
        }

How can I extent the above solution to accommodate my requirement as I specified? Or is there a totally different solution? If yes, I am open to it as well.

share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.