SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    SitePoint Zealot
    Join Date
    Feb 2008
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    WordPress Menu with wp_list_pages and PHP

    I'm working on a sidebar navigation menu. I have a three level hierarchy (parent -> child -> grandchild) and I am trying to do the following:

    • If the current page is a parent page, only show all parent pages.
    • If the current page is a child page, only show all child pages for that parent, and all parent pages.
    • And if the current page is a grandchild page, show all grandchildren for this child page, show all child pages for this parent, and show all parent pages.


    This is a good case for wp_list_pages but I cannot figure out the how to get this done with PHP. Here is a link to my test site that shows the page behavior the way I would like it to work. The navigation is on the LEFT SIDEBAR.

    Any help is appreciated of course.

  2. #2
    SitePoint Zealot
    Join Date
    Feb 2008
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I can find the post ancestor array and the post_parent using the following code:
    PHP Code:
    <?php
    $node 
    = (int) 234// or whatever id you are working with
    $mypost get_post($node);
    echo 
    "<pre>"print_r($mypost); echo "</pre>";
    ?>
    I will need some assistance using PHP to show/hide the child <ul> list if the current page has (or doesn't have) child pages, while keeping all parent pages visible. I believe this could be done with CSS classes.

    Any help would be greatly appreciated.

  3. #3
    SitePoint Zealot
    Join Date
    Feb 2008
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I came across a great post by Curtis Henson called Dynamic Multi-level Page Menus in WordPress that was very helpful in getting the menu to show or hide sub-pages depending on the current page. Unfortunately for me, this is meant for a horizontal menu. I am looking for help modifying the code to meet my needs. I'll explain below. Here's the code Curtis provides:
    PHP Code:
    <?php
    /**
     * Multi-level pages menu
     */

    function wptt_multilevel_menu() {
        global 
    $post;
        
    // Top level menu is always displayed
        
    $top_level wp_list_pages('title_li=&depth=1&sort_column=menu_order&echo=0');

        
    // Get post ancestors 
        
    $post_ancestors get_post_ancestors($post);

        
    // Check if a page has any parent pages
        
    if ($post_ancestors) {

            
    //get the top page id
            
    $top_page $post_ancestors end($post_ancestors) : $post->ID;

            
    // How many ancestors does this page have? Counts the array adds one.
            
    $n count($post_ancestors) + 1;

            
    // Get the pages children, if it has any
            
    $pages get_pages();
            
    $page_children get_page_children($post->ID$pages);

            
    // Checks if a page has children
            
    if (!empty($page_children)) {
                
    $children wp_list_pages("title_li=&child_of="$top_page ."&echo=0&sort_column=menu_order&depth=" $n);
            } else { 
    // If the page doesn't have children
                
    $children wp_list_pages("title_li=&child_of="$top_page ."&echo=0&sort_column=menu_order&depth=" . ($n 1));
            }

        } else {
            
    $children wp_list_pages("title_li=&child_of="$post->ID ."&echo=0&sort_column=menu_order&depth=1");
        }

        
    // Put it all together
        
    $menu '<ul class="menu top_level">';
        
    $menu .= $top_level;
        
    $menu .= '</ul>';
        
    // Only show child navigation if there are children
        
    if ( $children ) {
            
    $menu .= '<ul class="menu subpages">';
            
    $menu .= $children;
            
    $menu .= '</ul>';
        }
        print 
    $menu;
    }
    ?>
    The last section "if ($children)" will add an additional unordered list of child pages underneath the main menu. I'm looking for help in adding that additional <ul> into the main <ul> to create the right structure for a vertical menu, like this:
    HTML Code:
    <ul class="menu top_level">
      <li><a>Parent Page</a>
        <ul class="menu subpages">
          <li><a>Sub Page</a></li>
        </ul>
      </li>
    </ul>

  4. #4
    SitePoint Zealot
    Join Date
    Feb 2008
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I sincerely hope there is someone out there who has an idea I could try to get this working. Help is certainly appreciated. Thanks.

  5. #5
    SitePoint Zealot
    Join Date
    Feb 2008
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Would it be possible to build an array of child and grandchild pages of the current parent (if any), then show those pages in the list?

  6. #6
    SitePoint Enthusiast m19.5*11's Avatar
    Join Date
    Apr 2010
    Location
    East coast, USA
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You might consider this WP plugin... can do a vertical flyout.
    http://pixopoint.com/products/suckerfish_css/

    customizing sometimes takes a bit of searching the forums but it works really well.

  7. #7
    SitePoint Zealot
    Join Date
    Feb 2008
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Rather than messing with the PHP and trying to build an array of child and grandchild pages to show/hide, this can be done in CSS.

    Step One: grab the code from the WP codex about wp_list_pages showing sub-pages, and make these adjustments
    PHP Code:
    <?php
        
    if(!$post->post_parent){
            
    // will display the subpages of this top level page
        
    $children wp_list_pages("title_li=&child_of=".$post->parent."&echo=0&depth=2&sort_column=menu_order");
        }else{
            
    // diplays only the subpages of parent level
            // $children = wp_list_pages("title_li=&child_of=".$post->post_parent."&echo=0");
            
            
    if($post->ID)
            {
                
    // now you can get the the top ID of this page
                // wp is putting the ids DESC, thats why the top level ID is the last one
                
    $ancestors end($post->ancestors);
                
    $children wp_list_pages("title_li=&child_of=".$post->parent."&echo=0&sort_column=menu_order");
                
    // you will always get the whole subpages list
            
    }
        }
        
        if (
    $children) { ?>
            <ul>
                <?php echo $children?>
            </ul>
        <?php ?>
    Step Two: hide your child and grandchild lists
    Code CSS:
    #sidebar ul li ul, 
    #sidebar ul li ul li ul, 
    #sidebar ul li ul li ul li { display: none; }
    Step Three: show your lists if WP marks them with the 'current_page' class
    Code CSS:
    #sidebar ul li.current_page_item ul,
    #sidebar ul li.current_page_parent ul, 
    #sidebar ul li.current_page_ancestor ul,
    #sidebar ul li ul li.current_page_item ul,
    #sidebar ul li ul li.current_page_item ul li,
    #sidebar ul li ul li.current_page_parent ul,
    #sidebar ul li ul li.current_page_ancestor ul,
    #sidebar ul li ul li.current_page_ancestor ul li,
    #sidebar ul li ul li ul li.current_page_item,
    #sidebar ul li ul li ul li.current_page_item ul li,
    #sidebar ul li ul li ul li.current_page_parent ul,
    #sidebar ul li ul li ul li.current_page_parent ul li { display: block; }

    This forum has given to me in a lot of ways. I hope this helps someone right back.

  8. #8
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanx for sticking to the forum and leaving your answer even though no one really helped. I just found this today, and was exactly what i was looking for.

    However...I am trying to figure out how to use 'include=17,24,25' so the list only shows select pages. I see the problem with this as the include would be sent for parents and children and ancestors.

    What do you suggest?

    [N]

  9. #9
    rajug.replace('Raju Gautam'); bronze trophy Raju Gautam's Avatar
    Join Date
    Oct 2006
    Location
    Kathmandu, Nepal
    Posts
    4,013
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Efishant!

    Welcome to the Sitepoint forums!!!

    If I have come to understand what you asking about, no matter you use include or exclude parameters for parent pages/posts or children pages/posts you can just pass it to the function as other parameters:
    PHP Code:
    $children wp_list_pages("title_li=&child_of=".$post->parent."&echo=0&depth=2&sort_column=menu_order&include=17,24,25"); 
    Mistakes are proof that you are trying.....
    ------------------------------------------------------------------------
    PSD to HTML - SlicingArt.com | Personal Blog | ZCE - PHP 5

  10. #10
    SitePoint Member
    Join Date
    Jun 2010
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by rajug View Post
    Hi Efishant!

    Welcome to the Sitepoint forums!!!

    If I have come to understand what you asking about, no matter you use include or exclude parameters for parent pages/posts or children pages/posts you can just pass it to the function as other parameters:
    PHP Code:
    $children wp_list_pages("title_li=&child_of=".$post->parent."&echo=0&depth=2&sort_column=menu_order&include=17,24,25"); 
    Afraid not...I had been trying different things for hours now. I believe the code basically loops and uses the same function for the parents and ancestors, so the 'include' must have numbers for every level of page. I have proven this by putting the ids of the pages with 'include'...and the correct pages show...but no children. If I add the children's id into the 'include' also, then it will show that child, etc.

    I have been thinking of two ways to work around:

    1) Add another 'if' function to where the parent "id=17||22||24", and bypass if not true.

    2) Use some more CSS to keep hiding everything and only show "page-item-17, page-item-22, etc."

    The problem is I only know the parent ids for now...the client will add indefinite children in the future, so I can't account for them all.

  11. #11
    SitePoint Zealot
    Join Date
    Feb 2008
    Posts
    165
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I like these forums very much, and if I figure it out I'm glad to post my findings. Getting the WP menu to behave exactly the way YOU want it is nothing less than a mind bender (for me at least). Here's something that might help you on your way:

    PHP Code:
    <?php
    global $post$thispage $post->ID// grabs the current post id from global and then assigns it to $thispage

    $pagekids get_pages("child_of=".$thispage."&sort_column=menu_order"); // gets a list of pages that are sub pages of $thispage and assigns it to $pagekids
    ?>

    <?php if ($pagekids) { // if there are any values stored in $pagekids, meaning there are sub-pages of the current page ?>
      <ul>
        <?php wp_list_pages("depth=1&title_li=&sort_column=menu_order&child_of=".$thispage); // display ONLY the sub pages of the current page ?>
      </ul>
    <?php } else { // $pagekids is empty ?>
      <ul>
        <?php wp_list_pages('depth=1&title_li=&child_of='.$post->post_parent.'&sort_column=menu_order'); // display the sub-pages of the current parent page ?>
      </ul>
    <?php ?>
    1. This will tell you whether the current page has child pages or not. Very useful.
    2. the code is ready to do something if the current page has child pages, and do something else if the current page has no child pages.
    3. The wp_list_pages shown here is written do something specific for a site I'm working on, but it might be helpful anyway.

  12. #12
    SitePoint Member
    Join Date
    Aug 2010
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @ ggeigr,

    I've figured out a way to do this using the flexipages plugin however I do not want to use a plugin to accomplish this anymore. I checked your website above and noticed that the sidebar now works (I believe the way you want it to?). Can you share how you did this?

    Thanks in advance.



    Quote Originally Posted by ggeiger View Post
    I like these forums very much, and if I figure it out I'm glad to post my findings. Getting the WP menu to behave exactly the way YOU want it is nothing less than a mind bender (for me at least). Here's something that might help you on your way:

    PHP Code:
    <?php
    global $post$thispage $post->ID// grabs the current post id from global and then assigns it to $thispage

    $pagekids get_pages("child_of=".$thispage."&sort_column=menu_order"); // gets a list of pages that are sub pages of $thispage and assigns it to $pagekids
    ?>

    <?php if ($pagekids) { // if there are any values stored in $pagekids, meaning there are sub-pages of the current page ?>
      <ul>
        <?php wp_list_pages("depth=1&title_li=&sort_column=menu_order&child_of=".$thispage); // display ONLY the sub pages of the current page ?>
      </ul>
    <?php } else { // $pagekids is empty ?>
      <ul>
        <?php wp_list_pages('depth=1&title_li=&child_of='.$post->post_parent.'&sort_column=menu_order'); // display the sub-pages of the current parent page ?>
      </ul>
    <?php ?>
    1. This will tell you whether the current page has child pages or not. Very useful.
    2. the code is ready to do something if the current page has child pages, and do something else if the current page has no child pages.
    3. The wp_list_pages shown here is written do something specific for a site I'm working on, but it might be helpful anyway.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •