0

I am trying to redevelop a HTML site as a Wordpress theme, and the HTML menu is as follows:

<ul>
    <li class="current"><a href="#"><div>Home</div></a></li>
    <li><a href="#"><div>Link 1</div></a>
        <ul>
            <li><a href="#"><div class="flintstone-nav">Sublink 1</div></a></li>
            <li><a href="#"><div class="flintstone-nav">Sublink 2<br><div class="flintstone-nav-small">Smaller Text</div></div></a></li>
            <li><a href="#"><div class="flintstone-nav">Sublink 3<br><div class="flintstone-nav-small">Smaller Text</div></div></a></li>
        </ul>
    </li>
</ul>

I have removed the default menu wrapper and default menu class, and declared a custom nav menu walker using the following:

<?php wp_nav_menu( array( 'container' => 'false', 'menu_class' => '', 'items_wrap' => '%3$s', 'theme_location' => 'header-menu', 'walker' => new themeslug_walker_nav_menu ) ); ?>

And my walker is this:

class themeslug_walker_nav_menu extends Walker_Nav_Menu {

// add classes to ul sub-menus
function start_lvl( &$output, $depth = 0, $args = array() ) {
    // depth dependent classes
    $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
    $display_depth = ( $depth + 1); // because it counts the first submenu as 0
    $classes = array(
        'sub-menu',
        ( $display_depth % 2  ? 'menu-odd' : 'menu-even' ),
        ( $display_depth >=2 ? 'sub-sub-menu' : '' ),
        'menu-depth-' . $display_depth
        );
    $class_names = implode( ' ', $classes );

    // build html
    $output .= "\n" . $indent . '<ul>' . "\n";
}

// add main/sub classes to li's and links
 function start_el(  &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
    global $wp_query;
    $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent

    // depth dependent classes
    $depth_classes = array(
        ( $depth == 0 ? 'main-menu-item' : 'sub-menu-item' ),
        ( $depth >=2 ? 'sub-sub-menu-item' : '' ),
        ( $depth % 2 ? 'menu-item-odd' : 'menu-item-even' ),
        'menu-item-depth-' . $depth
    );
    $depth_class_names = esc_attr( implode( ' ', $depth_classes ) );

    // passed classes
    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );

    // build html
    $output .= $indent . '<li class="' . $class_names . '">';

    // link attributes
    $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        ) .'"' : '';
    $attributes .= ' class=""';

    $item_output = sprintf( '%1$s<a%2$s><div>%3$s%4$s%5$s</div></a>%6$s',
        $args->before,
        $attributes,
        $args->link_before,
        apply_filters( 'the_title', $item->title, $item->ID ),
        $args->link_after,
        $args->after
    );

    // build html
    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}

As you can see on the HTML menus, there are divs within the anchors, I have managed to insert these within the walker in the $item_output . But there are divs with classes in the sub menu anchors, how do I get the classes in to the divs only on sub menu items?

Not so worried about the smaller text divs as these can go in the Wordpress Menu items Title field which I believe accepts HTML, this is just for a few words to appear under the menu item title.

Thank you for any help in advance.

Adrian

1 Answer 1

1

Sounds like you want to check the $depth variable. A depth of 0 is a top level item, a depth of 1 is a child of a top level item, etc.

So in keeping with your current code, you could factor out that logic this way:

$format = '%1$s<a%2$s><div>%3$s%4$s%5$s</div></a>%6$s';
if( $depth > 0 ) $format = '%1$s<a%2$s><div class="flintstone-nav">%3$s%4$s%5$s</div></a>%6$s';
$item_output = sprintf( $format,
        $args->before,
        $attributes,
        $args->link_before,
        apply_filters( 'the_title', $item->title, $item->ID ),
        $args->link_after,
        $args->after
    );

As a side note, I wouldn't but a <br> tag inside your anchor, as it's unnecessary. I'd also recommend you use the core menu item field "Description" to set up your "smaller text", rather than having to add markup in the Menus panel, which can get messy. The Description field can be revealed in the Screen Options tab, and its value can be accessed via $item->description. Doing it that way will keep things a lot cleaner.

1
  • Thank you so much, I added the item description using this: $description .= ! empty($item->description) ? '<div class="flintstone-nav-small">' . esc_attr( $item->description ) . '</div>' : '';
    – Adrian
    Oct 9, 2015 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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