I would like to display a custom 3.0 menu in my sidebar. I want the list to be in order of name, and the list to be sequential down the list of the left column and flow down, then into the right column.

enter image description here

I currently am using css and floating the li's but the problem is the list goes back and forth from left to right column, rather than down the list sequentially.

I am using

<?php wp_nav_menu('menu=canon-camcorders'); ?> in my sidebar.php

Then, #sidebar ul#menu-canon-camcorders li.menu-item {width:89px; float:left; margin-right:18px;}

What I would like to do is count how many list items there are, then divide it into two and create two ul's from that. My php abilities are sort of patched together without any formal training, so I am kind of lost. I know some jquery, but don't know how to do this in either way.

I read this post: How to count nav menu items? But, I couldn't figure it out for my needs.

Any help is greatly appreciated.

Thank you, Larry


You'll need to register your own custom walker, but it's pretty simple as you only need to have one function(start_el) inside the custom walker.

We'll have to add the code from the thread you referenced to work out how many items there are, then work out what half is and end the current list when that value is met and start another.

I'm not always good at explaining these things, so first take a look at this walker i wrote for you. It's based off the default nav menu walker, so nothing special going, except a few lines here and there that work out when to create a new list.

class example_nav_walker extends Walker_Nav_Menu {

    var $current_menu = null;
    var $break_point  = null;

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

        global $wp_query;

        if( !isset( $this->current_menu ) )
            $this->current_menu = wp_get_nav_menu_object( $args->menu );

        if( !isset( $this->break_point ) )
            $this->break_point = ceil( $this->current_menu->count / 2 ) + 1;    

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

        $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 ) . '"' : '';

        if( $this->break_point == $item->menu_order )
            $output .= $indent . '</li></ul><ul><li' . $id . $value . $class_names .'>';
            $output .= $indent . '<li' . $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 );

I create two variables inside the class, the first $current_menu is going to hold the menu object, and we don't want to be fetching that we every iteration of a menu item, so i give that a default null value and fetch the menu object when that variable isn't set, this ensures it only makes the call once. The second variable $break_point will hold the break point, ie. the value we'll use to determine when to end the current list and start another, again we don't want to needless work this out with every iteration, so it's set just on the first item's iteration.

The break point will always be plus one because we're not using a traditional counter which would usually increment at the end of an iteration(so the value is one higher that you may expect) and the call to ceil deals with cases when the menu has an odd amount of items, ie. if you had 9 items, it would start a new list after the 5th.

Basically the only custom parts of this walker, are..

    var $current_menu = null;
    var $break_point  = null;

..and this..

if( !isset( $this->current_menu ) )
    $this->current_menu = wp_get_nav_menu_object( $args->menu );

if( !isset( $this->break_point ) )
    $this->break_point = ceil( $this->current_menu->count / 2 ) + 1; 

..and finally this..

if( $this->break_point == $item->menu_order )
    $output .= $indent . '</li></ul><ul><li' . $id . $value . $class_names .'>';
    $output .= $indent . '<li' . $id . $value . $class_names .'>';

I'm pointing them out, so can pay attention to the important parts without wondering if anything else is relevant.

Lastly, you'll also need to set you wp_nav_menu call to use a custom walker, which also means you'll need to pass the args as an array, here's an example.

<?php wp_nav_menu( array(
    'menu' => 'your-menu',
    'walker' => new example_nav_walker
) ); ?>

You can use this walker with any menu you like, just make sure when you use it, that you do so as i've shown above(setting the walker and menu args).

The big chunk of code(the walker) can go into your theme's function file, if that's easiest for you, it's also where i tested it.

Hope that helps, and if you have any questions please let know.

  • Thanks, t3los. I tried following your instructions, but I think I am lacking quite a bit of know-how to make this work. Your answer did open me up to knowledge of the the nav_walker which I was unfamiliar with. However, I am still confused about how to implement your solution. Thank you so much for spending the time to answer. I am certain others with more know-how will find it very useful. – Larry4Design Dec 15 '11 at 21:21
  • So tell me where you're having problems.. :) Copy the big chunk of code into your functions file, after the opening PHP tag, and update your wp_nav_menu call inline with the example i gave..(all there is to it). – t31os Dec 15 '11 at 21:38
  • Thank you t3los! I think I was a little intimidated with so much, but once you explained it as above, I thought I'd give it a try. It works wonderfully! It basically split the one UL into two, then I could style them appropriately. – Larry4Design Jan 3 '12 at 21:28
  • Happy to have helped. :) – t31os Jan 6 '12 at 19:13
  • Doesn't the above code leave an open <ul> tag? It never gets closed at the end. – greatwitenorth Dec 18 '14 at 20:56

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