For a Web project I am working on I wanted to use WordPress as a CMS for flat pages only. No blog posts, no categories, simply a hierarchical page tree (too complicated for the user). Thus I installed the CMS Tree Page View plugin, set some permissions and tried to render a hierarchical menu in the navigation bar of the Web site.
Well, I tried. It is not as simple as it seems to render a hierarchical menu in WordPress that does the following:
- always display all top level (root) pages
- always display the current path down to the current page
- always display all child pages of the current page
- always display siblings of the current page
This is pretty much the behavior I’d expect from a hierarchical menu in a CMS.
Unfortunately it seems this is not very easy to implement in WordPress. The wp_list_pages function with all its options does not allow to render a page tree that goes up to the top level. And none of the samples on the page is the right solution (on a side note: the advanced samples on the page are not targeting the latest WordPress releases and won’t work out of the box as they target the wrong database tables) – they render the current parent page or siblings or… something.
Anyhow, here is a short snippet that provides a hierarchical page menu in WordPress, simply add this to the template where ever you would otherwise just have the call to wp_list_pages:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php
global $blog_id;
// anchestor pages
$relations = get_post_ancestors($post->ID);
// select child pages, siblings and top level pages
$result = $wpdb->get_results( "SELECT ID FROM wp_{$blog_id}_posts WHERE ( " .
"post_parent = $post->ID OR ". // child pages
"post_parent = $post->post_parent OR ". // siblings
"post_parent = 0 ) ". // top level pages
"AND post_type='page'" );
if ($result) {
foreach($result as $pageID){
array_push($relations, $pageID->ID);
}
}
// move the chain up until we are at the root
$parent = $post->post_parent;
while($parent) {
array_push($relations, $parent);
$result = $wpdb->get_results( "SELECT ID, post_parent FROM ".
"wp_{$blog_id}_posts WHERE id = $parent AND post_type='page'" );
if($result && $result[0]->ID) {
$parent = $result[0]->post_parent;
}
else {
$parent = 0; // quit the loop
}
}
// build a relations string...
$relations_string = implode(",",$relations);
// ... and list all pages
wp_list_pages('title_li=&depth=0&sort_column=menu_order&&include='.
$relations_string);
?> |
I hope this helps someone who runs into the same issue… and – if there is a better, simpler solution that I did not see or find, please leave a comment!
I am using one of those 


