Subscribe to our updates:

A Design, WordPress and Tutorials Blog.

Dedicated to helping you learn the art and science of the web.

Use the Link Description in WordPress 3.0 Menus

One of the great new features that the recent WordPress 3.0 release has given us is the new and improved menu system. Those of you who have built complex websites in WordPress will undoubtably share my pain in working with menu systems in WordPress. Previously it seemed that we would have to use a mixture of plug-in cocktails and hard coded sub-menus.

The new menu system alleviates a lot of these problems and gives us easy control over our menus. With multiple menu support, drag and drop ordering and easy title changes it is hard to imagine needing much more.

The new system even addresses a challenge I have always had with WordPress, and that is of using link descriptions. Link descriptions typically are one or two lines of descriptive text below a primary navigation item used to  describe the section or link. They are a nice visual touch and can really enhance usability in a significant way.

Until now there wasn't a great way to do this, even with the use of plug-ins. Even with the use of custom fields and some hacking it was never perfect.

The new menu system allows us to do a bit more customization to our menus, such as adding custom classes, titles and even including a description.

Working with Link Descriptions

The first step is of course enabling custom menu support through your theme. This can be done with the following simple code in your functions.php file:

add_action( 'init', 'register_menus' );
     function register_menus() {
                     'primary-menu' => __( 'Primary Menu' )

You will then find a "Menu" link in your appearance tab with in the WordPress administration interface. Once clicked on make sure that you turn on "link description" with in the Screen Options.

At this point we can now define where we would like our menu to display in our theme by adding the following function to our theme files:

<?php wp_nav_menu( array( 'theme_location' => 'primary-menu' ) ); ?>

This will output the menu with our defined order and menu titles. It won't however output the description by default, in order to do so we will have to take advantage of the $walker function with in WordPress.

This is done by creating a custom class in our functions.php, such as the following:

class My_Walker extends Walker_Nav_Menu
	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 = '';

		$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 .'>';
		$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
		$item_output .= '<span>' . $item->description . '</span>';
		$item_output .= '</a>';
		$item_output .= $args->after;

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

This will add the description with in a span element when we tweak our template code to the following:

       $walker = new My_Walker;
                'theme_location' => 'primary-menu',
		'walker' => $walker

Tada, now we can have menu descriptions such as on this Buddypress project we worked on here.

Leave a comment on Stylized Web Have some feedback? Leave a comment

44 Comments So Far

  1. By Ahmet posted on August 17, 2010 at 9:57 am

    Hey, thanks for great tuttorial.

    Can i translate and publish on my blog?

    Of course i will give a link to this blog if you say yes :)

  2. you have write a nice blog, i really want to use this in my next blog,Thnaks for share it with us.

  3. So SEO is getting more stronger in this version.

  4. Hi Ahmet, absolutely! Thanks for your interest.

  5. thank you very nice….

  6. Veryy good Posd Thank yOu

  7. Message Corp takes text messaging to a new level.
    Our interactive text messaging makes it possible to engage
    in a highly personalized and fully-automated customer dialog.
    As a result, customers can access product inquiries,authorize
    payments, and confirm transactions – conveniently from their
    mobile phone and without the assistance of an agent.And for
    those customer interactions that require special handling,
    we make it possible for your agents to seamlessly interact
    with your customers via text.

  8. We offers wholesale belt buckles, western, belt, batman, superman and also rhinestone, skull belt buckles, visit our belt buckle store and leather belts also wholesale buckles.

    Thanks :)

  9. This is a really great addition to WordPress. Thanks for the tutorial I will be adding to my next free theme.

  10. By TheMassofToe posted on October 4, 2010 at 2:31 pm

    Hi, thanks very much… your post pointed me in the right direction. One thing though, I think your updated My_Walker php dosen’t include class names for the list items… which means you can’t style your menu properly!

    Here is a suggested correction:

    class My_Walker extends Walker_Nav_Menu
    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 ) );

    $output .= $indent . ‘ID . ‘”‘ . $value . ‘ class=”‘ . $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 .= ‘‘;
    $item_output .= $args->link_before . apply_filters( ‘the_title’, $item->title, $item->ID ) . $args->link_after;
    $item_output .= ” . $item->description . ”;
    $item_output .= ‘
    $item_output .= $args->after;

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

    //disable auto p – annoying paragraph thing
    //remove_filter (‘the_content’, ‘wpautop’);


    I’m quite new to php so let me know if this is completely bad or something!

    best, and thanks

  11. StylizedWeb is a web design, WordPress and tutorials blog … Learn SEO basics; query_posts() Pagination problem … the plugin will give you will make your entire blog an SEO …


  12. Nice solution for descriptions, i always hand coded those in the main/ptimary menu.

  13. Hi
    I found this site through search engines.
    – Very interesting and useful information.
    This information helped me a lot as I was using Word press 3.0
    The Winnipeg Painters – The Best House Painting Contractors In MB – We offer complete interior painting and exterior painting services for both residential and commercial locations. House painters Winnipeg, MB / Manitoba are the best.


  14. Hi
    Thanks for the wonderful post. I like this as it helped me a lot and sorted my problem. I appreciate the

    work.Enjoyed it.

    The Best FREE Foreclosure Investing Courses And Information Online. FREE Information On Foreclosure

    Investing And Short Sale Deals.


  15. Can this be made to work with menus that are added via the custom menus widget?

  16. By pablotrabajo posted on November 14, 2010 at 1:03 am

    man, i was looking for this a week. tried themeshaper and various other options out there without the expected outcome. you made my day. thanks!

  17. By pablotrabajo posted on November 14, 2010 at 1:23 am

    one question though.

    is there a way to avoid getting empty tags for my (dropdown) submenu?

    so basically just include descriptions for the main menu.

  18. By ReTox posted on March 19, 2011 at 4:15 pm

    Is this code correct?

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

    And what about $value variable? Where is this set up?


  19. throat cancer surgeries used to be looked at and all of these operations were made more frequently in the larynx was taken. Now for the disease in the early diagnosis can be caught earlier. Laser application, the problem of hoarseness can be treated and residents can go from the hospital the same day. These steps away from cigarettes and alcohol to absent oneselfsumomax
    need to focus.

  20. By ying posted on August 29, 2011 at 10:47 am
  21. By ying posted on August 29, 2011 at 10:47 am
  22. I lost the “current_page_item” class…

  23. Copied and paste on my file, works well, Excellent! :)

  24. By Tom Newbold posted on September 26, 2011 at 4:46 am

    Hey there! Firstly Thanks for the wonderful tutorial! i used this a week or 2 ago… I was just wondering… is it possible to use highlighting in the navigation to show the user what page they are on using this dynamic menu process?

    Thanks in advance.. Tom

  25. Yeah, the current-menu-item class gets lost with this.. I’m gonna try and find a solution coz else its kinda a bummer

  26. hohoho its nice baby

  27. vaaau its perfect

  28. By Mandy Barrington posted on June 2, 2012 at 5:09 pm

    You just ended a 4-hour quest to get this feature on my WordPress menu. I’ve been through dozens of tutorials, but you explained points that wouldn’t be obvious to a novice like me – so THANK YOU!

  29. polla nice

  30. Very nice and helpful information has been given in this article. I like the way you explain the things. Keep posting. Thanks

  31. I have read a few excellent stuff here. Certainly worth bookmarking for revisiting. I surprise how much effort you set to create this sort of fantastic informative site.

  32. By Manohar posted on January 8, 2013 at 11:10 am

    Thank you very much for this code!

  33. By Стара Загора posted on January 13, 2013 at 3:53 pm

    Сайт доминируют среди сайтов в городе Стара Загора, когда люди ищет в Гугля словосочетание Стара-Загора и слова: новости, видео, автобусы, юристы, банки и так далее.

  34. Thanks for the code, I have made some modification so that you can get the class names. Let me know if this works.

    class My_Walker extends Walker_Nav_Menu
    function start_el(&$output, $item, $depth, $args) {
    global $wp_query;
    $indent = ( $depth ) ? str_repeat( “\t”, $depth ) : ”;

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

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

    $output .= $indent . ‘ID . ‘”‘ . ‘class=”‘ . $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 .= ‘‘;
    $item_output .= $args->link_before . apply_filters( ‘the_title’, $item->title, $item->ID ) . $args->link_after;
    $item_output .= ” . $item->description . ”;
    $item_output .= ‘
    $item_output .= $args->after;

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

  35. Very nice post. I just stumbled upon your blog and wished
    to mention that I’ve truly enjoyed browsing your weblog posts. After all I will be subscribing for your feed and I hope you write again very soon!

  36. By Adeel Khanzada posted on May 9, 2013 at 1:30 pm

    primary nav description are not save html tags any idea ….

  37. Hey there. I stumbled upon the website the utilization of ask. It is a really intelligently composed document. We’ll make sure to search for that plus revisit read more of your practical facts. Just publish. Let me unquestionably come back.

  38. Вступление в Проектное СРО. Не посредник 5000 руб./месяц!

  39. By peter posted on November 19, 2013 at 4:16 pm

    hello, this code removes the other classes for me (eg: current-menu-item
    ) in WP 3.7.1, help

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>