2

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

        $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:\xampp\DEV\Stace\trunk\wp-content\themes\philosophy\functions.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?

  • 1
    Why don't use CSS for styling? – Mamaduka Aug 23 '11 at 13:16
  • @Mamaduka - Because of a number of reasons. – Scott Aug 23 '11 at 13:21
  • I agree with @Mamaduka. CSS is the way to go here. I can't think of many valid reasons to reinvent the entire walker just to add a pipe between links. – Chip Bennett Aug 23 '11 at 13:35
  • @Chip - No its not the way to go. If you want to join chat I'll gladly explain why CSS will NOT work here. – Scott Aug 23 '11 at 13:37
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        ) .'"' : '';
        $output .= '<a'. $attributes .'>';
        $output .= apply_filters( 'the_title', $item->title, $item->ID );
        $output .= '</a>';
    }
}
| improve this answer | |
  • Don't know how I missed this. Well spotted. Just one thing though. Is there any chance that the first item's menu order is not 1? If so this would fail. – Scott Mar 26 '12 at 8:05
3

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        ) .'"' : '';
        $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 );
    }
}
| improve this answer | |
  • Thanks Rarst you genius! walk() needed 3 args and needed to be returned. I'd have never worked that out myself. – Scott Aug 23 '11 at 14:06
  • Is there a way to reset the count for every submenu? – JacobTheDev Jun 18 '14 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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