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 am currently developing a custom theme.

I need to generate menu with submenu.

By default wordpress provides me result like below:

<ul id="side-menu" role="navigation" class="main-menu nav">

    <li class="selected" id="menu-item-485">
        <p> <a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/">Home</a> </p>
    </li>

    <li class="parent menu-item" id="menu-item-486">
        <p> <a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/">About Us</a> </p>

        <div>
            <ul id="side-menu" class="sub-menu-new">
                <li class="menu-item" id="menu-item-488">
                    <p><a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/values/">Values</a></p>
                </li>
                <li class="menu-item" id="menu-item-489">
                    <p><a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/vision-mission/">Vision & Mission</a></p>
                </li>
                <li class="menu-item" id="menu-item-487">
                    <p><a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/quality/">Quality</a></p>
                </li>
            </ul>
        </div>
    </li>
 </ul>

I want the sub menu to come out from main ul.

I need to exact result as below:

<ul id="side-menu" role="navigation" class="main-menu nav">
    <li class="selected" id="menu-item-485">
        <p> <a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/">Home</a> </p>
    </li>

    <li class="parent menu-item" id="menu-item-486" data-submenuid="about">
        <p> <a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/">About Us</a> </p>
    </li>
 </ul>

<ul data-submenuid="about" id="side-menu" class="sub-menu-new">
    <li class="menu-item" id="menu-item-488">
        <p><a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/values/">Values</a></p>
    </li>
    <li class="menu-item" id="menu-item-489">
        <p><a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/vision-mission/">Vision & Mission</a></p>
    </li>
    <li class="menu-item" id="menu-item-487">
        <p><a href="http://10.0.1.46/iir/sites/icegen/wordpress/IIR_icegen/about-us/quality/">Quality</a></p>
    </li>
</ul>

And I tried using the below php class in wordpress but the result is failure

class menu_default_walker extends Walker_Nav_Menu
{

    function start_lvl(&$output, $depth){
        $output .= '<div><ul class="sub-menu-new" id="side-menu">';
    }

    function display_element($element, &$children_elements, $max_depth, $depth=0, $args, &$output){
        $id_field = $this->db_fields['id'];
        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
        }
        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        global $rb_submenus;

        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $new_output = '';
        $open_class = '';
        $depth_class = ($args->has_children ? 'parent ' : '');

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

        $current_indicators = array('current-menu-item','current-menu-parent','current_page_item','current_page_parent');

        $newClasses = array();
        foreach($classes as $el)
            if(in_array($el,$current_indicators))
            array_push($newClasses,$el);

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

        if(strpos($class_names, 'current-menu-parent') > 0 || strpos($class_names, 'current_page_parent') > 0) {
            $class_names = ' class="' . $depth_class . $open_class . 'opened"';
        } else if($class_names != '') {
            $class_names = ' class="' . $depth_class . $open_class . 'selected"';
        } else if($class_names == '') {
            $class_names = ' class="' . $depth_class . $open_class . 'menu-item"';
        }

        if ( !get_post_meta( $item->object_id , '_members_only' , true ) || is_user_logged_in() ) {
            $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $class_names . '>';
        }

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        if($item->object != 'portfolio_category' && $item->object != 'gallery_category')
            $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
        else
            $attributes .= ' href="#"';

        $portfolio_count;
        $gallery_count;

        if($item->object == 'portfolio_category'){
            $terms = get_terms('portfolio_category', array('include' => $item->object_id));
            $portfolio_count = $terms[0]->count;
            $attributes .= ' data-category="true" data-filter="' . $terms[0]->slug .'"';
        }

        if($item->object == 'gallery_category'){
            $terms = get_terms('gallery_category', array('include' => $item->object_id));
            $gallery_count = $terms[0]->count;
            $attributes .= ' data-category="true" data-filter="' . $terms[0]->slug .'"';
        }

        if($item->attr_title == 'allportfolio' || $item->attr_title == 'allgallery'){
            $attributes .= ' data-all="true" data-filter="*"';
        }

        $item_output = $args->before;
        $item_output .= '<p><a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= ($item->object == 'category' ? ' ('. get_category($item->object_id)->count . ')' : '');
        $item_output .= ($item->object == 'portfolio_category' ? ' ('. $portfolio_count . ')' : '');
        $item_output .= ($item->object == 'gallery_category' ? ' ('. $gallery_count . ')' : '');
        $item_output .= ($item->attr_title == 'allblog' ? ' ('. wp_count_posts()->publish . ')' : '');
        $item_output .= ($item->attr_title == 'allportfolio' ? ' ('. wp_count_posts('portfolio')->publish . ')' : '');
        $item_output .= ($item->attr_title == 'allgallery' ? ' ('. wp_count_posts('gallery')->publish . ')' : '');
        $item_output .= '</a></p>';
        $item_output .= $args->after;

        if ( !get_post_meta( $item->object_id, '_members_only' , true ) || is_user_logged_in() ) {
            $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
        }

        $output .= $new_output;

    }

    function end_el(&$output, $item, $depth) {
        if ( !get_post_meta( $item->object_id, '_members_only' , true ) || is_user_logged_in() ) {
            $output .= "</li>\n";
        }
    }

    function end_lvl(&$output, $depth) {

        $output .= "</ul></div>\n";

    }

}
share|improve this question
    
Seems like overkill for something a few lines of CSS could fix. –  Chip Bennett Apr 23 at 19:29

1 Answer 1

up vote 1 down vote accepted

You could use Javascript to move the Submenu items where ever you please.

<script>

    jQuery(document).ready(function() { 
        (function ($) { 
            $('.sub-menu-new').after( $('.main-menu') );        

        })(jQuery);
    });

</script>

OR...

You could take a look at the wp_nav_menu_objects filter hook

It could allow you to do a check against every menu item and maybe store the submenu items somewhere else to be displayed elsewhere

add_filter( 'wp_nav_menu_objects', 'your_wp_nav_menu_items', 10, 2 );
function your_wp_nav_menu_items($items, $args) {
    if ($args->theme_location == 'primary'):
        foreach($items as $item):
            //only display items you want; and store the other items for later output
        endforeach;
    endif;
}

BUT I WOULD NOT WASTE TIME DOING THAT. Why don't you just make more than one menu and output them where you please?

share|improve this answer

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.