Recently I was faced with building a sub-nav menu that displays all the child pages contained in that parents menu. An example would be, say we a navigation menu called “Products”, and within that menu is a list of child pages such as “Computers”, “TVs”, “Phones”. I needed to create a menu that would display all child pages of “Products” in a side bar menu. This would seem fairly straight forward in most cases, but if we add a third level to here, things get complicated.
I put together a script that will, no matter the level of child pages, always return the list child pages from the main parent.
Here’s the script –
Since we are dealing with a sidebar navigation, we’ll be fetching post information outside of the loop, we need to set the $post object scope to global. This will allow us to deal with the information retrieved by this WordPress object.
Next we need to set an if statement checking if the current $post object has a Parent ID. The $post object holds all the specific information for each post. If $post does contain a Parent ID, we will run some code, if not, we run a default.
Now for the best part! If our if statement returns true with a parent ID this is the code we will run. We will use the _get_post_ancestors() function to return an array of all the Parent ID’s for the current post. We will assign a variable called $parentids so we can refer to the data in a second.
In the last line we will use the end() function to grab the last ID in the _$parentids array. The reason we do this is because the top most parent ID is always last in the array, so we will need that ID to display the child pages as we need to. Even if it returns one ID, we’ll still be able to return the correct parent ID. We then assign the end() function to a variable called $id.
If our if statement returns false, we will just grab the current posts ID and assign it to a variable called $id.
And the last line of the whole script is the WordPress function _wp_list_pages()_. This function can take a number of parameters, for the complete list, I highly suggest checking out the details at the WordPress Codex. We don’t need anything too extensive for this so we’ll be using two parameters, _titleli and _childof. Let’s dig into what these parameters are exactly.
- title_li - This parameter will set a title to the top of your menu. Assuming you want more control over the title of the function you can set your own title and enter this parameter with an empty value to have _wp_listpages() ignore a title. I normally prefer this method so I usually add this parameter. If you want to use it, just add a value or have WordPress add one for you by omitting this line completely in the function.
- child_of - This is the bread and butter of the script. With this parameter we can feed a post ID here to return the child pages of this post ID. If the post ID doesn’t have any children, it will just return blank.
Now that we know what these parameters are, we can dive a little further into what we are doing. Inside the parenthesis of the _wp_listpages() function we will send a string containing our empty _titleli and _childof parameters, separating each with an ampersand. Since we don’t want to use a title we’ll define _titleli with a blank value (_titleli=). Lastly we will add _childof at the end (placement isn’t really required for it to work) and concatenate our $id variable into the value area (_childof=’ . $id). Concatenating is a PHP operator that will allow us to attach variables, functions to strings. We first need to close the string by adding the single quote after the equal sign, then use the period (.) to attach our $id variable to it.
And that’s it! Let me know what your thoughts are or if there are any questions about the script.