Add home & other items directly in WP Nav Menu using wp_nav_menu_items filters

So, this is going to be the last of the WordPress Nav Menu series. Previously, we have talked about the basics of WordPress custom navigation menu and dealing the empty nav menus with custom fallbacks. In this post, we shall see how we can directly add some links to the nav menu using filters. This would become useful, if you want to customize the user’s own navigation menus. We shall see, how we can add the home button and also the dynamic login/logout button through user defined custom navigation menus using WordPress Filters.

#1: Understanding the concept:

The filter we will be using is wp_nav_menu_items. It lets the function get two arguments. One is $items, which is the HTML of all the items in the navigation. Other is the $args, which holds the information of the nav itself. We shall use the $args variable to identify our target navigation menu and then will add our links.

#2: Adding the Navigation menu:

First we hook our two navigation menus, primary & footer as follows:

/**
 * Register our nav menus
 * @see http://codex.wordpress.org/Function_Reference/register_nav_menus
 */
function my_theme_nav_bars() {
    register_nav_menus(array(
        'primary' => 'Primary Menu',
        'footer' => 'Footer Menu',
    ));
}
add_action('init', 'my_theme_nav_bars');

#3: Add filters to customize:

Now, we customize the navigation menus using filters like this:

/**
 * Filter the navigation menus and add customized links
 *
 * We are usign wp_nav_menu_items filter to do this.
 * Also, $args is used to identify the location of the nav menu
 * and change it accordingly.
 *
 * @param string $items The HTML of the generated items
 * @param array $args The information of the navigation
 * @return string
 */
function filter_my_theme_nav_bars($items, $args) {
    if($args->theme_location == 'primary') {
        $homelink = '<li class="home' . ((is_home() || is_front_page())? ' current_page_item' : '') . '"><a href="' . get_bloginfo('url') . '">' . __('Home') . '</a></li>';
        $items = $homelink . $items;
    }

    if($args->theme_location == 'footer') {
        $dlink = '<li class="login">' . wp_loginout('', false) . '</li>' . wp_register('<li class="admin">', '</li>', false);
        $items .= $dlink;
    }

    return $items;
}
add_filter('wp_nav_menu_items', 'filter_my_theme_nav_bars', 10, 2);

The code is quite self explanatory. It adds a nice Home button to the primary nav and nice login/logout button to the footer navigation. We use the wp_nav_menu_items to hook to the filter. The argument 10 represents the priority, which is the default and 2 represent the number of arguments which should be two ($items & $args).

Now, for the sake of completeness, let us see how we can do even more.

#3.1: Add a search bar to the navigation:

function add_search_through_filter($items, $args) {
    if($args->theme_location == 'primary') {
        $searchlink = '<li class="search">' . get_search_form(false) . '</li>';
        $items .= $searchlink;
    }
    return $items;
}
add_filter('wp_nav_menu_items', 'add_search_through_filter', 10, 2);

#3.2: Add feed link to the navigation:

function add_rss_link_through_filter($items, $args) {
    if($args->theme_location == 'primary') {
        $rsslink = '<li class="rss"><a href="' . get_bloginfo('rss2_url') . '">RSS</a></li>';
        $items .= $rsslink;
    }
    return $items;
}
add_filter('wp_nav_menu_items', 'add_rss_link_through_filter', 10, 2);

#3.3: Show some text:

function add_custom_text_through_filter($items, $args) {
    if($args->theme_location == 'footer') {
        $clink = '<li class="copyright">&copy; Copyright ' . get_bloginfo('name') . ' ~ 2010-' . date('Y') . '</li>';
        $items .= $clink;
    }
    return $items;
}
add_filter('wp_nav_menu_items', 'add_custom_text_through_filter', 10, 2);

So, that was all. I hope you found this interesting. If you have any doubt then feel free to ask.

2 comments

  1. Gabriel Reply

    Hello Swashata,

    Thank you for the great explanation. I was looking at the nav-menu_template.php file to get a better idea of what the $items variable does through the script. How did you figure out that $items holds the html for the nav? There’s no documentation stating that.

Leave a Reply