Creating a Submenu in WordPress
For a project I’m currently working on I wanted to create a submenu that included the parent page as well as the supbages. I just wanted to display the submenu only if the parent page had subpages. Searching the WordPress Codex and googling for a solution I couldn’t quite find an example that took all these factors into consideration so I had to figure it out myself. Here’s the approach I came up with.
Checking if the page has subpages
I searched in vain for a method to determine if the current page has any subpages or not. I first assumed that there would be a has_subpages() method, but so far I haven’t found any. Lacking that, I came up with a very crude way of checking it. I explicitly had to try to fetch all the subpages with the function wp_list_pages() and then check if it returned anything. It’s not pretty but it works.
$children = wp_list_pages('&child_of='.$post->ID.'&echo=0');
if($children) {
// This page has subpages
}
Checking if it’s a parent page or a subpage
The next thing I had to figure out was how to check i the current page is a parent page or a subpage. That’s done with the following code.
if(is_page() && $post->post_parent) {
// This is a subpage
} else {
// This a parent page
}
Fetching the submenu
Now I needed a way to fetch the subpages. This is done with the wp_list_pages() function. The tricky part about this is that there’s no way to get both the parent page and the subpages in the same call. So therefor we have to call the function twice. The call also looks a little different depending on if we’re on the parent page or on the subpage.
if(is_page() && $post->post_parent) {
// This is a subpage
$children = wp_list_pages("title_li=&include=".$post->post_parent ."&echo=0");
$children .= wp_list_pages("title_li=&child_of=".$post->post_parent ."&echo=0");
} else if($has_subpages) {
// This is a parent page that have subpages
$children = wp_list_pages("title_li=&include=".$post->ID ."&echo=0");
$children .= wp_list_pages("title_li=&child_of=".$post->ID ."&echo=0");
}
There are other ways of doing this, but the benefit of this approach is that we automatically get class="current_page_item" on the list-item that represents the page that we’re currently on. That’s handy if you want to style that item in any particular way.
Outputting the HTML
The last step is to output the actual HTML. I’ve chosen to output it as an unordered list.
<?php // Check to see if we have anything to output ?>
<?php if ($children) { ?>
<ul class="submenu">
<?php echo $children; ?>
</ul>
<?php } ?>
Putting it all together
Now it’s time to put all the pieces together. Just put this code in your page template one of the pages in your template, like for example page.php or sidebar.php and you’re good to go. These pages are located in /wp-content/themes/your-theme/.
<?php
$has_subpages = false;
// Check to see if the current page has any subpages
$children = wp_list_pages('&child_of='.$post->ID.'&echo=0');
if($children) {
$has_subpages = true;
}
// Reseting $children
$children = "";
// Fetching the right thing depending on if we're on a subpage or on a parent page (that has subpages)
if(is_page() && $post->post_parent) {
// This is a subpage
$children = wp_list_pages("title_li=&include=".$post->post_parent ."&echo=0");
$children .= wp_list_pages("title_li=&child_of=".$post->post_parent ."&echo=0");
} else if($has_subpages) {
// This is a parent page that have subpages
$children = wp_list_pages("title_li=&include=".$post->ID ."&echo=0");
$children .= wp_list_pages("title_li=&child_of=".$post->ID ."&echo=0");
}
?>
<?php // Check to see if we have anything to output ?>
<?php if ($children) { ?>
<ul class="submenu">
<?php echo $children; ?>
</ul>
<?php } ?>
Conclusion
I think that WordPress is an absolutely awesome CMS/Blog engine, but it do lack some handy methods. Fortunately it’s almost always possible to create workarounds. I hope that you will find this useful in your own WordPress Template. Don’t hesitate to tell me if you have a smarter way of doing this.
Pingback: wantusiak.com » Wordpress: How to style wp_list_pages
Pingback: How to style wp_list_pages « MalarVizhi
Pingback: WordPress Menus on the top « Amen
Pingback: Incluir páginas y subpáginas en WordPress | SummArg