• I’m struggling with wp_nav_menu() to output my menu like this

    <nav>
    	<ul class="nav">
    		<li><a href="">First Level</a></li>
    		<li>
    			<a href="">First Level</a>
    			<div class="drop-down">
    					<ul>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    					</ul>
    					<ul>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    					</ul>
    					<ul>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    						<li><a href="#">Second Level</a></li>
    					</ul>
    			</div>
    		</li>
    		<li><a href="">First Level</a></li>
    		<li><a href="">First Level</a></li>
    	</ul>
    </nav>

    I managed to get the <div class="drop-down"> with a custom walker in there, but cannot find a solution to output three equal submenus.

    How do I achieve this?

    Thank you!

Viewing 6 replies - 1 through 6 (of 6 total)
  • wpismypuppet

    (@wordpressismypuppet)

    You’ll probably need a more advanced custom walker… but before I continue, can you clarify a little more? What do you mean by “three equal submenus”? How do you want the final output to look and how is it currently looking? What does your WordPress menu look like in the admin area? The more details you provide (including a link if at all possible) the easier for us to answer quickly.

    Thread Starter mkampitsch

    (@mkampitsch)

    Basically you can just add one submenu to each navigation item. What I mean with “equal submenus” is to group items of those submenus to get multiple parallel submenus for one navigation item.

    I want the final output to look like in my first post.

    What I achieved right now is this, which is the most final it’ll get I assume

    <nav id="nav" role="navigation">
    	<ul id="nav" class="nav">
    		<li><a href="#">level one</a></li>
    		<li><a href="#">level one</a>
    			<div class="drop-down">
    				<ul class="sub-menu">
    					<li><a>level two</a>
    						<ul>
    							<li><a href="#">level three</a></li>
    							<li><a href="#">level three</a></li>
    						</ul>
    					</li>
    					<li><a href="#">level two</a>
    						<ul class="sub-menu-level-2">
    							<li><a href="#">level three</a></li>
    						</ul>
    					</li>
    					<li><a href="#">level two</a>
    						<ul class="sub-menu-level-2">
    							<li><a href="#">level three</a></li>
    						</ul>
    					</li>
    				</ul>
    			</div>
    		</li>
    		<li><a href="#">level one</a></li>
    	</ul>
    </nav>

    My menu structur looks like this
    because I assume without any plugins it would not be possible to group the submenus to look like this

    wpismypuppet

    (@wordpressismypuppet)

    Well yes, it is final in that it is what the function will output, but you can add code to your custom walker to add more code. In your case, I’m assuming you want to have columns of ULs floating left, correct?

    What I would do, if I were you… I would add a class of “break” or “col-break” or something equivalent on your “level two” elements where you want the column to break. You can add this class where you create the menu itself, in the admin area. If you don’t see a field for “class”, then open the screen options and check off the “class” box. Then I would write my custom walker to check each element for that class and, if found, pump out a:

    </div><div class="col">

    So where you have code to create your:

    <div class="drop-down">

    Add in the starting div so it looks like this:

    <div class="drop-down"><div class="col">

    Then whenever you find your class, “col-break” on the li, pump out the:

    </div><div class="col">

    and where you have code to close your “drop-down” div, close the “col”:

    </div></div>

    Make sense? Then use CSS to float the columns (“col”).

    Thread Starter mkampitsch

    (@mkampitsch)

    Yeah makes sense. What I’m doing now comes with less code. I don’t use another column div. I just take `.sub-menu > li’ to float it.

    Do you mind sharing the walker you came up with for this? I’ve been struggling to wrap my first level drop downs in a div for over a week. It’s driving me insane.

    wpismypuppet

    (@wordpressismypuppet)

    Comments should speak for themselves… 90% of this code is the standard WordPress walker class… only a few lines have been added. You’ll see those lines between the comments.

    // Custom walker to allow drop down menus to be in columns
    class Column_Walker extends Walker_Nav_Menu {
    	function start_lvl( &$output, $depth = 0, $args = array() ) {
    		$indent = str_repeat("\t", $depth);
    		$output .= "\n$indent<ul class=\"sub-menu\">";
    		// Add this piece to start to wrap all the <li> tags in a <div class="col">
    		if( $depth == 0 ) {
    			$output .= "\n$indent<div class=\"col\">";
    		}
    		// End
    		$output .= "\n";
    	}
    	function end_lvl( &$output, $depth = 0, $args = array() ) {
    		$indent = str_repeat("\t", $depth);
    		// Add this piece to close the wrap of all the <li> tags in a <div class="col">.
    		// It should be noted that an extra empty <div> is included to allow for clearing any floated column.
    		// Feel free to remove '$indent<div class=\"clear\"></div>' if you have your own clear method
    		if( $depth == 0 ) {
    			$output .= "$indent</div>\n$indent<div class=\"clear\"></div>";
    		}
    		// End
    		$output .= "$indent</ul>\n";
    	}
    	function start_el(&$output, $item, $depth, $args) {
    		global $wp_query;
    		$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    		$class_names = $value = '';
    		$classes = empty( $item->classes ) ? array() : (array) $item->classes;
    		$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
    		$class_names = ' class="' .  esc_attr( $class_names ) . '"';
    		// This piece checks to see if you added a class of 'col-break' to any menu item in the admin area.
    		// If you did, it breaks the column and starts a new one BEFORE the item is displayed
    		if( stripos( $class_names, 'col-break' ) !== false )
    			$output .= '</div><div class="col">';
    		// End
    		$output .= $indent . '<li id="menu-item-' .  $item->ID . '"' . $value . $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 ) . '"' : '';
    		$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) . '"' : '';
    		$item_output = $args->before;
    		$item_output .= '<a' . $attributes . '>';
    		$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    		$item_output .= '</a>';
    		$item_output .= $args->after;
    		$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    	}
    }
Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Custom Mega Menu’ is closed to new replies.