Add description to wordpress navigation menu items

Ok, so I know that this method of adding a visible description inside a navigation element is over two years old and there are many methods that ‘better’ this hands down, but, I’m gunner post it for my own resource and just because I want to. So lets get on it, follow the method below to quickly add the nifty little feature of including a description under a singe menu item to improve your WordPress design. The great part about this is you or a client can edit or add their own descriptions as they see fit!

This is an example of what we’re going to make.

nav-bar-example

First things first

Go to your WordPress back-end and navigate to Appearance > Menus. Click Screen Options, then open your menu element and you’ll see a text field titled “Description”, add your description in here and then click “Save Menu”.

backend-example

Second

Crack open your themes functions.php file and drop in the code below appropriately. You can add you own class name to the span tag on line 43, its up to you what you use.

class Description_Walker extends Walker_Nav_Menu
{
    /**
     * Start the element output.
     *
     * @param  string $output Passed by reference. Used to append additional content.
     * @param  object $item   Menu item data object.
     * @param  int $depth     Depth of menu item. May be used for padding.
     * @param  array $args    Additional strings.
     * @return void
     */
    function start_el(&$output, $item, $depth, $args)
    {
        $classes     = empty ( $item->classes ) ? array () : (array) $item->classes;

        $class_names = join(
            ' '
        ,   apply_filters(
                'nav_menu_css_class'
            ,   array_filter( $classes ), $item
            )
        );

        ! empty ( $class_names )
            and $class_names = ' class="'. esc_attr( $class_names ) . '"';

        $output .= "<li id='menu-item-$item->ID' $class_names>";

        $attributes  = '';

        ! empty( $item->attr_title )
            and $attributes .= ' title="'  . esc_attr( $item->attr_title ) .'"';
        ! empty( $item->target )
            and $attributes .= ' target="' . esc_attr( $item->target     ) .'"';
        ! empty( $item->xfn )
            and $attributes .= ' rel="'    . esc_attr( $item->xfn        ) .'"';
        ! empty( $item->url )
            and $attributes .= ' href="'   . esc_attr( $item->url        ) .'"';

        // insert description for top level elements only
        // you may change this
        $description = ( ! empty ( $item->description ) and 0 == $depth )
            ? '<span class="nav_desc">' . esc_attr( $item->description ) . '</span>' : '';

        $title = apply_filters( 'the_title', $item->title, $item->ID );

        $item_output = $args->before
            . "<a $attributes>"
            . $args->link_before
            . $title
            . '</a> '
            . $args->link_after
            . $description
            . $args->after;

        // Since $output is called by reference we don't need to return anything.
        $output .= apply_filters(
            'walker_nav_menu_start_el'
        ,   $item_output
        ,   $item
        ,   $depth
        ,   $args
        );
    }
}

Third

Open the themes header.php file and replace the existing “wp_nav_menu” call with this below. I’ve included the HTML5 tag <nav> tag within the php call. If you’re intending to use this as a secondary or footer nav simply change ‘primary’ for your chosen menu name and code up accordingly.

<?php wp_nav_menu( array( 'container' => 'nav', 'fallback_cb' => 'breckpoint_menu', 'theme_location' => 'primary', 'walker' => new Description_Walker ) ); ?>

Forth

Add a little CSS and you’re underway, what I’ve provided here is simply a starting point…

nav ul li span.nav_desc {
	font-family: Arial; /* add your own font */
	font-size: 0.8em; /* set your font size */
	line-height: normal;
	color: inherit; /* use colour hierarchy */}

And that’s about it, add, change, enjoy…