Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

wp_list_pages, how to display only top pages and their children ? WordPress

  • SOLVED

Hello,

I have a menu that uses wp_list_pages. The problem is that i just need to display the top pages and their direct children. Not grandchildren....


Here is the code :

<ul id="tiered-nav">
<?php wp_list_pages('sort_column=menu_order&include=5,16,36,26&title_li=&depth=1' ); ?>
</ul>
<?php if($post->post_parent)
$children = wp_list_pages("depth=1&sort_column=menu_order&title_li=&child_of=".$post->post_parent."&echo=0");
else
$children = wp_list_pages("depth=1&sort_column=menu_order&title_li=&child_of=".$post->ID."&echo=0");
if ($children) { ?>
<ul id="sub-tiered-nav"><?php echo $children; ?></ul>
<?php } else { ?>
<ul id="sub-tiered-nav"></ul>
<?php } ?>


Here is the structure needed :
PAGE > display
<blockquote> SUB-PAGE > display</blockquote>
<blockquote><blockquote> SUB-SUB-PAGE > don't display</blockquote></blockquote>
<blockquote><blockquote><blockquote> SUB-SUB-SUB-PAGE > don't display</blockquote></blockquote></blockquote>
<blockquote><blockquote><blockquote> SUB-SUB-SUB-PAGE > don't display</blockquote></blockquote></blockquote>
<blockquote><blockquote><blockquote> SUB-SUB-SUB-PAGE > don't display</blockquote></blockquote></blockquote>



I need 3 things :

1. display only the top page and children not grandchildren and next sub-level. When we are in a sub-sub-page or sub-sub-sub-page.

2. Top parent and first level Children stays active when we are in the grandchildren, grandgrandchildren.

3. Top parent ID : for the moment Wordpress gives a body class parent-pageid-X… but this class is related to the previous ancestor not the top ancestor. IS there a way to add the top ancestor page id to the body class ?

Thanks

Answers (3)

2013-04-20

Giri answers:

Sorry, I still don't understand your structure. Could you edit your question and organize the structure by giving spaces and tabs. So I can understand clearly.

From what I understood I guess you would like to display only the current children of the parent and hide other parents and children.

If thats correct I think you can use like this..

<?php
global $post;
wp_list_pages( array(
'sort_column' => 'menu_order',
'include'=> array(5,16,36,26),
'child_of' => $post->post_parent,
'depth' => 2
) );
?>


For more info check this page..
http://wordpress.stackexchange.com/a/31939/5074


angang comments:

If you read the questions... I want exactly the opposite :)

http://codex.wordpress.org/Function_Reference/wp_list_pages

0 (default) Displays pages at any depth and arranges them hierarchically in nested lists


angang comments:

No prob and sorry for the structure display. I have corrected it.

What i need is to display :
1. the first ancestor in the tree. Not the previous parent.
2. the children of the top ancestor.

So if we are in a sub-sub-sub-sub-page. THe menu display the top ancestor + first children...


Giri comments:

Ok here are some codes that might help you to accomplish this.

http://codex.wordpress.org/Function_Reference/get_post_ancestors

That function returns the ancestors as array.

It usually return like this

array($level3_parent_postid,$level2_parent_postid,$level1_parent_postid);

So use that function to get that top ancestor id..

global $post; $cur_page = $post->ID;
$array = get_post_ancestors($cur_page);
$top_ancestor = end($array);
if ($top_ancestor) {
$children = wp_list_pages("depth=1&sort_column=menu_order&title_li=&child_of=".$post->ID."&echo=0");
if ($children) { ?>
<ul id="sub-tiered-nav"><?php echo $children; ?></ul>
<?php }
}



If you would like to get the depth of current page then use this function.

function get_current_page_depth(){
global $wp_query;

$object = $wp_query->get_queried_object();
$parent_id = $object->post_parent;
$depth = 0;
while($parent_id > 0){
$page = get_page($parent_id);
$parent_id = $page->post_parent;
$depth++;
}

return $depth;
}


you can test your current depth like this

if (get_current_page_depth() > 1) {
echo "current level is grandchildren";
}


I hope that helps

2013-04-20

jazbek answers:

Use <?php wp_list_pages('depth=2'); ?>

To add the top ancestor page ID to the body class, put this in your functions.php:


<?php

add_filter('body_class','wpq_top_body_class');

function wpq_top_body_class($classes) {

global $post;
$top_page_ancestor = $post->ID;

if ($post->ancestors) {
$top_page_ancestor = end($post->ancestors);
}

$classes[] = "parent-pageid-$top_page_ancestor";
return $classes;
}

?>


angang comments:

Dear jazbek,

Your code is working perfectly

function wpq_top_body_class($classes) {
global $post;
$top_page_ancestor = $post->ID;
if ($post->ancestors) {
$top_page_ancestor = end($post->ancestors);
}
$classes[] = "parent-pageid-$top_page_ancestor";
return $classes;
}



So this is the perfect answer for :
3. Top parent ID : for the moment Wordpress gives a body class parent-pageid-X… but this class is related to the previous ancestor not the top ancestor. IS there a way to add the top ancestor page id to the body class

Thank you so much


angang comments:

<?php wp_list_pages('depth=2'); ?> is not working... it displays all the parents...not only the top ancestor + its children.


jazbek comments:

It displays all the parents of the page you are on right now?


angang comments:

Exactely


jazbek comments:

All you need is one wp_list_pages.. (you can add the additional title_li and include arguments that I left out):

<ul id="tiered-nav">
<?php wp_list_pages('depth=2&sort_column=menu_order&title_li=&include=5,16,36,26'); ?>
</ul>


angang comments:

<?php wp_list_pages('depth=2&sort_column=menu_order&title_li=&include=5,16,36,26'); ?>
Only dispay the included ids that are top ancestors in this context.

In this picture http://wpquestions.com/uploads/angang_phpGGPHMP.jpg we see the structure.

page1
-----sub-page1.1
-----sub-page1.2
-----sub-page1.3
page2
-----sub-page2.1
-----sub-page2.2
-----sub-page2.3

So if we are in top ancestor 1, we have to display its direct children only. If we are in grandchildren always show the children of the yop ancestor.
In ancestor 2, display its direct children...




jazbek comments:

Ah, I see what you're saying. The way most people accomplish this is to always output all the top level parents and all of the children (of all the parents), and then use CSS to only show the children of the current parent.

You can use :


#tiered-nav li li { display: none; } /* hide all the children by default */
#tiered-nav li. current_page_ancestor li {display: block} /* show only the children of the current page ancestor */


angang comments:

Ok, i have just to choose exclude instead of include to get the children of previous included only ancestors.
Here is the code (no matter the excluded id, but it is working..i just need to adpat the css :
<?php wp_list_pages('exclude=100,81,407,528,419,91,89,83,85,87&sort_column=menu_order&include=&title_li=&depth=2' ); ?>

Now it is strange that i have no li li but li on the same level as you can see on my attached picture ?