Bar separated navigation by extending Walker_Nav_Menu

The question:

I have the following menu in my header:

<?php
$args = array(
    'menu'            => 'Main Menu',
    'container'       => false,
    'depth'           => 1,
    'items_wrap'      => '%3$s',
    'walker'          => new Bar_List_Walker_Nav_Menu
);
wp_nav_menu($args);
?>

and I want to make the output look like this:

link1 | link2 | link3 | link4 | link5

So I set out to make a walker function here is where I got to:

class Bar_List_Walker_Nav_Menu extends Walker_Nav_Menu {
    public $count;
    function start_lvl(&$output, $depth) {}
    function end_lvl(&$output, $depth) {}
    function start_el(&$output, $item, $depth, $args) {
        $attributes = ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener"' : '';

        $item_output .= '<a'. $attributes .'>';
        $item_output .= apply_filters( 'the_title', $item->title, $item->ID );
        $item_output .= '</a>';

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
    function end_el(&$output, $item, $depth) {
        static $count;
        $count++;
        if(!$this->count >= $count) {
            $output .= " | ";
        }
    }
    function walk( $elements, $max_depth ) {
        $this->count = count($elements);
        parent::walk( $elements, $max_depth );
    }
}

This outputs the following error:

Warning: Missing argument 4 for Bar_List_Walker_Nav_Menu::start_el() in C:xamppDEVStacetrunkwp-contentthemesphilosophyfunctions.php on line 100

If I remove the function walk() from my walker class it works fine except the count is no longer grabbed and as a result one | too many is added to the end of my navigation.

Can anyone work the code to get to my desired output?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

You can use the menu order inside the item to see if it’s not first. If it isn’t have it draw the character before the anchor.

class Bar_List_Walker_Nav_Menu extends Walker_Nav_Menu {
    private $separator = " | ";
    function start_el(&$output, $item, $depth, $args) {
        if($item->menu_order > 1){
            $output .= $this->separator;
        }
        $attributes  = ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener"' : '';
        $output .= '<a'. $attributes .'>';
        $output .= apply_filters( 'the_title', $item->title, $item->ID );
        $output .= '</a>';
    }
}

Method 2

After some discussion in chat:

class Bar_List_Walker_Nav_Menu extends Walker_Nav_Menu {
    public $count;
    function start_el(&$output, $item, $depth, $args) {
        $attributes  = ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener" rel="nofollow noreferrer noopener"' : '';
        $output .= '<a'. $attributes .'>';
        $output .= apply_filters( 'the_title', $item->title, $item->ID );
        $output .= '</a>';
    }
    function end_el(&$output, $item, $depth) {
        static $count;
        $count++;
        if($this->count > $count)
            $output .= " | ";
    }
    function walk( $elements, $max_depth, $r ) {
        $this->count = count($elements);
        return parent::walk( $elements, $max_depth, $r );
    }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment