0

I'm using FontAwesome and hence I need to include some extra code next to parent menu options that have a sub-menu, such as:

<li>
    <a href="">About <span class="fa fa-angle-down"></span></a>
    <ul class="sub-menu">
        <li><a href="">About Us</a></li>
        <li><a href="">Why Choose Us?</a></li>
    </ul>
</li>

However I am unsure how to do this when using wp_nav_menu.

My code:

wp_nav_menu( array(
    'menu' => 'main',
    'container' => 'div',
    'container_id' => 'mr_nav',
    'container_class' => 'mr_nav collapse navbar-collapse',
    'menu_class' => 'clearfix',
    'menu_id' => 'main_menu' )
);

Is there anyway to add the span tag as above when the menu item has a sub-menu?

2 Answers 2

1

Filtering menu items is something that I don't enjoy much. :-) So I'm going to give you another idea. Instead of using extra HTML, I have a purely CSS solution. It targets the top level of your menu, and leaves the submenu alone. If you're on the FontAwesome site, you can get unicode for the symbol you want. I grabbed the unicode for your choice.

See if this works for you. (You may have a different ID or class on your top level). You'll probably need to adjust for spacing. I do all FontAwesome stuff on my sites this way.

ul#menu-top-navigation-menu > li > a:after  {
    content: "\f107";
    font-family: 'FontAwesome';
    font-size: 27px;
    padding-left: 12px;
    speak: none;
}
2
  • Wouldn't this add it to all menu items and not just the ones that have a sub-menu?
    – Brett
    Commented May 29, 2015 at 15:52
  • Yessir! I anticipated that, and added a nice little bit of instructions. gist.github.com/davechu/000d81aca9e9ddd373d1
    – Flamenco
    Commented May 29, 2015 at 20:20
0

Ok, figured it out. You need to use a walker instance which is passed in as an instance via the wp_nav_menu function, like so:

wp_nav_menu( array(
                    'menu' => 'main',
                    'container' => 'div',
                    'container_id' => 'mr_nav',
                    'container_class' => 'mr_nav collapse navbar-collapse',
                    'menu_class' => 'clearfix',
                    'menu_id' => 'main_menu',
                    'walker' => new My_Walker,
                    )
            );

Then you put the following inside your functions.php file:

class My_Walker extends Walker_Nav_Menu {

    function start_el(&$output, $item, $depth, $args) {

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

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;

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

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth );
        $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

        $output .= $indent . '<li' . $id . $class_names .'>';

        $atts = array();
        $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
        $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
        $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
        $atts['href']   = ! empty( $item->url )        ? $item->url        : '';


        $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );

        $attributes = '';
        foreach ( $atts as $attr => $value ) {
            if ( ! empty( $value ) ) {
                $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
                $attributes .= ' ' . $attr . '="' . $value . '"';
            }
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        /** This filter is documented in wp-includes/post-template.php */
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= ($this->has_children) ? ' <span class="fa fa-angle-down"></span>' : '';
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

    }

}

To break it down... the above is basically a copy of the default Walker_Nav_Menu method with one small addition:

        $item_output .= '<a'. $attributes .'>';
        /** This filter is documented in wp-includes/post-template.php */
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= ($this->has_children) ? ' <span class="fa fa-angle-down"></span>' : '';
        $item_output .= '</a>';

In the above code I merely added the line:

$item_output .= ($this->has_children) ? ' <span class="fa fa-angle-down"></span>' : '';

...before the closing </a> was added.

That's it! :)

Your Answer

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

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