8

I need to output different html code only for the first item of my submenus. How can I check in start_el() function if current item is first or not?

Example:

Menu voice 1
-- Sub 1
-- Sub 2
-- Sub 3
Menu voice 2
Menu voice 3
Menu voice 4

I would know when I'm in Sub1

UPDATE - I've solved using Static Var:

class my_walker_nav_menu extends Walker_Nav_Menu {
    static $count=0;
    function start_el(&$output, $item, $depth, $args) {         
        global $wp_query;

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

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $output .= $indent . '<li id="menu-item-'. $item->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 .'>';

        if ($depth==0) self::$count=0;  // reset var when we are in first level


        if ($depth==1 && self::$count==1) {  // if we are in submenu and items count is 1...

            //your custom code              

        }

        $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 );

        self::$count++;  // increase counter
    }


}
6
  • There is a variable $depth, 0 is the parent, 1 is one level down and so forth.
    – user23654
    Sep 5, 2013 at 14:14
  • Yes I know, but itsn't the problem. I don't want to know the dept of menu, but when I'm on the first item of submenu. For example I want to know when I'm on Sub1 in the following menu: Main 1 > Sub1 | Sub2 | Sub3 | Sub4
    – Supertramp
    Sep 5, 2013 at 14:19
  • 2
    I don't think there is an elegant way to do this other than add a counter and reset the counter on every parent depth. So if ( $depth = 1 && $counter = 0 ) { // do something }
    – user23654
    Sep 5, 2013 at 14:44
  • mmm it seems not so easy... which is the right way to declare var?
    – Supertramp
    Sep 5, 2013 at 15:20
  • 2
    THANK YOU SO MUCH! I spent 4 hours trying to do this yesterday, I didn't know about the self bit. Jun 19, 2014 at 13:40

1 Answer 1

1

Count the level 0 elements in a static variable in the method and add an extra class if you hit the third. Sample code:

function start_lvl(&$output, $depth) {
    static $column = 1;
    $indent = str_repeat("\t", $depth);
    if ($depth > 0)
    {
        $output .= "\n$indent<ul class='subsubmenu'>\n";
    }
    else
    {
        $column += 1;
        $extra = 3 === $column ? ' third-column' : '';
        $output .= "\n$indent<ul class='submenu$extra'>\n";
    }
}

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.