Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question
1  
Why don't use CSS for styling? –  Mamaduka Aug 23 '11 at 13:16
    
@Mamaduka - Because of a number of reasons. –  Brady 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. –  Brady Aug 23 '11 at 13:37
add comment

2 Answers

up vote 1 down vote accepted

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>';
    }
}
share|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. –  Brady Mar 26 '12 at 8:05
add comment

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 );
    }
}
share|improve this answer
    
Thanks Rarst you genius! walk() needed 3 args and needed to be returned. I'd have never worked that out myself. –  Brady Aug 23 '11 at 14:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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