How to display 2 equal columns of li based on the count of items in wp_nav_menu divided by 2?

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

Read More

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

Related posts

Leave a Reply

1 comment

  1. 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 .'>';
            else
                $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 .'>';
    else
        $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.