Creating Context-Sensitive Sidebar Navigation in WordPress

Sometimes I get a client job that requires a site built entirely on pages. No fancy database queries, no extra template files - just a whole bunch of pages in a hierarchical structure.

A very large site built on pages can become unwieldy and confusing for users if the navigation isn't done right, so it's helpful to provide a list of all the pages in the current branch of the page hierarchy on each page. 

For example, if your site is for an organization and each of the organization's functions has a top level page with subpages for individual departments, then you'll want to list all of those departments along with a link to the top level function page. You'll want to do this on each of those department pages and on any subpages they might have as well as with the top level page itself.

To do this, you won't be able to output lists of related content by running queries on the current post type or taxonomy term. Instead, you'll have to identify where in the structure the current page is and then display a list of links accordingly.

Here, I'll show you how to do just this, by creating a function you can add to your sidebar file or perhaps above the content in your template files (or activate via a hook if your theme uses those).

This consists of two stages:

  1. identifying where the current page is in the structure
  2. outputting a list of pages

What You'll Need

To complete this tutorial, you'll need:

  • an installation of WordPress
  • a text editor

Creating Your Plugin

I'm going to create this function in a plugin so that its theme independent. So your first step is to create a plugin file. Mine is called tutsplus-list-subpages.php.

Open your plugin file and add the following:

Obviously, your code will be different as the plugin author and URL will change, and you might want to amend the description. 

Including the name of the function in the description is helpful as it means that when you install your plugin on a site, you don't need to check the code to remind yourself how to use it.

Identifying the Current Page in the Hierarchy

To find out where the current page is in the page hierarchy, you need to do four things:

  1. Check that this is actually a page
  2. Check if this post has parents
  3. If not, then you know it's the top level ancestor for this part of the hierarchy
  4. If so, you need to identify the top level ancestor using get_post_ancestors()

So let's do it!

Create a new function with a conditional tag in it to check we're on a page:

Now, inside the is_page() conditional tag, start by defining the $post global variable:

Next you need to identify whether the current page has parents, which you do using if( &post->post_parent ):

If the page does have ancestors, you need to identify the top-most of these, which you do using get_post_ancestors():

This defines a new variable of $parents whose value is the ID of the topmost page in the current branch of the hierarchy. The line return $parents[0]; outputs that value so that you can use it in a later function.

Finally, you need to define what happens if the current page doesn't have parents, i.e. if it's the topmost ancestor itself. In that case you want to output the current page's ID, so you add the following to your function:

Your entire function will now look like this:

Outputting a List of Subpages

Now that you know the ID of the topmost page in the current branch of the hierarchy, outputting a list of its subpages is relatively straightforward. You use get_pages() to identify the child pages of the page whose ID you've identified. You'll also need to output a link to the ancestor page at the beginning of the list.

Using list_pages() to Identify Subpages

Start by creating a new function with a check that we're on a page:

Note that if you're going to add this function to your page.php template, you can leave out the check that a page is being displayed.

The first thing you need to do inside that conditional tag is pull in the page ID you identified in the tutsplus_check_for_page_tree() function, which you do with this line of code:

Below that, define the arguments for the get_pages() function:

Let's have a quick look at the arguments I've used:

  • 'child_of' => $ancestor identifies those pages which are a child of the $ancestor page
  • 'depth' => '-1' tells the function to go to as many levels in the hierarchy as there are in the site. You can change this if you just want to display one or two levels.
  • 'title_li' => '' ensures that what's output isn't wrapped in any HTML tags - as I'll be adding those later.

Next, you need to run the list_pages() function:

Outputting the List of Pages

Now that you have your pages, you need to output them with links. To do this, first check that list_pages() hasn't returned an empty array:

Inside that check, the first link is to the top level page:

And then below that first <li> element but still inside the <ul>, use the wp_list_pages() function to output a list of the pages wrapped in hyperlinks to them:

This will display a list of the page titles as links.

Your entire tutsplus_list_subpages() function will now look like this:

Activating the Function

You can activate the function in one of two ways:

  • By calling tutsplus_list_subpages() in one of your theme's template files, such as the sidebar.php file
  • By attaching it to a hook in your theme.

For example, if your theme has a tutsplus_sidebar hook in the sidebar.php file, you'd add the following to your functions.php file:

Summary

The code I've demonstrated lets you automatically add a list of related pages to a page anywhere in your site's hierarchy.

If you're using it for client sites, you'll need to make sure the client understands how to create pages hierarchically, but other than that it won't mean they have to think about it at all.

If you wanted to make the code even more user-friendly for clients you could create a widget (or maybe a shortcode) to output the list of pages, but that's a topic for another day!

Tags:

Comments

Related Articles