Justin Tadlock

Easy navigation menus in WordPress

Easily modifying your navigation in WordPress usually requires diving into your theme’s code a bit. For novice users, this can be pretty tough. What if I told you that you could that you could set it and forget it even if you want to make changes later?

That’d be a pretty cool, right?

I’m going to give you a few lines of code that’ll make your life immensely easier in the future and allow you to change your navigation whenever you want from the WordPress backend.

Using bookmarks for your navigation

I put out a call for people to start thinking about using bookmarks more effectively a few weeks back, but no one really answered. I suppose I’ll have to step up and show you a cool way to use them myself.

Bookmarks are those things called Links in your WordPress dashboard. We’re going to use them to create our navigation menu. Go to Link Categories. From there, create a new category. I’m naming my category Navigation.

WordPress Link Categories

Once you’ve created your category, you need to create your links. Go to Add New under the Links menu in your WordPress dashboard. Type a name for the link and a URL. The most important step here is to select the category that you created in the previous step. There are other things you can enter as well but aren’t necessary.

Create as many links as you like. You can change them, update them, or add new ones later.

New WordPress bookmark (link)

Creating your custom menu

If you’re using one of my themes, just go to my support forums, and I’ll show you how to implement this into your theme.

Now, what we’re going to do is add a new function to our theme’s functions.php file. Skip to the next section of this tutorial if your theme uses the wp_page_menu() function to create its menu.

<?php

function custom_bookmark_menu($cat_id = false) {
    $page_uri = str_replace("/", "", $_SERVER['REQUEST_URI']);
    $class = "page_item";

    $bookmarks = get_bookmarks(array('category' => $cat_id));

    $menu = '<div id="page-nav"><ul class="bookmarks xoxo">';
    foreach($bookmarks as $bookmark) :

        if(!$page_uri && (get_bloginfo('url') == $bookmark->link_url))
            $class .= " current_page_item";
        elseif($page_uri && strchr($bookmark->link_url, $page_uri))
            $class .= " current_page_item";

        $menu .= '<li class="' . $class . '"><a href="' . $bookmark->link_url . '" title="' . $bookmark->link_name . '" rel="' . $bookmark->link_rel . '">' . $bookmark->link_name . '</a></li>';

    endforeach;
    $menu .= '</ul></div>';

    echo $menu;
}

?>

Find your theme’s navigation menu and change it to something like this. Add any classes and/or IDs that your theme’s menu would have. Also change the 3 to the ID of the link category you chose in the first step.

<div id="page-nav">
    <ul>
        <?php custom_bookmark_menu(3); ?>
    </ul>
</div>

Just save your files and check out your new menu with your custom links.

Filtering wp_page_menu

If your theme uses the new wp_page_menu() function introduced in WordPress 2.7, you can use this function and not have to edit your template files. This is the method you would use with my Hybrid theme.

Open your theme’s functions.php file and paste this code in (change the 3 to the ID of your link category:

<?php

add_filter('wp_page_menu', 'custom_bookmark_menu');

function custom_bookmark_menu($menu) {
    $menu = false;
    $page_uri = str_replace("/", "", $_SERVER['REQUEST_URI']);
    $class = "page_item";

    $bookmarks = get_bookmarks(array('category' => 3));

    $menu = '<div id="page-nav"><ul class="bookmarks xoxo">';
    foreach($bookmarks as $bookmark) :

        if(!$page_uri && (get_bloginfo('url') == $bookmark->link_url))
            $class .= " current_page_item";
        elseif($page_uri && strchr($bookmark->link_url, $page_uri))
            $class .= " current_page_item";

        $menu .= '<li class="' . $class . '"><a href="' . $bookmark->link_url . '" title="' . $bookmark->link_name . '" rel="' . $bookmark->link_rel . '">' . $bookmark->link_name . '</a></li>';

    endforeach;
    $menu .= '</ul></div>';

    return $menu;
}

?>

Just save the file and you’ll be finished. You didn’t have to edit a single template file in your theme.

Problems with using this method

While this will make updating your navigation menu much easier because it’s all done from your WordPress dashboard, there are still some issues.

  • Dynamic menu highlighting I don’t know of any way that you could dynamically highlight the link to the page the visitor is on. If anyone knows how this can be accomplished, I’ll be happy to update the post with the information. Code has been updated to account for dynamic menu highlighting.
  • Drop-down lists While it’s not impossible to add a drop-down menu, it’s much more complicated using this method.

Enjoy your new navigation menu

After the initial setup of your menu, you don’t have to edit the code whenever you want to change links. Just create, update, and/or delete links as you see fit from your WordPress dashboard. Of course, you might have to style it if you’re creating your own theme.

I encourage you all to help me think of more creative ways to use our WordPress bookmarks. Since the Era of the Blogroll is now dead, we may as well do something useful with them. Another thing I could do is just package this thing up as a plugin whenever I’m feeling a little less lazy.

Some of you theme developers may wonder why I didn’t filter wp_list_pages() in the first method, but there’s a good reason for this. Users may want to have an actual page menu in their sidebar and use a widget to do so. Using a filter for this would filter all page lists. It is unlikely that wp_page_menu() will be used more than once on a page, which is why I used a filter in the second method.