I know javascript pretty well now but I am new to php and wordpress theme building. I have searched a fair bit and can’t find a solution to something that seems like a pretty simple task, all I would like to accomplish is get all the grandchildren of a page only, not the direct children, like so:

Portfolio

  • child 1
    • grandchild 1A
    • grandchild 1B
  • child 2
    • grandchild 2A
    • grandchild 2B

My page is “Portfolio” and I would like to “get_pages” but only the ones that are grandchildren of “Portfolio, so in this case it would return only: -“grandchild 1A”, “grandchild 1B”, “grandchild 2A”, “grandchild 2B”.

any suggestions?

3 Answers
3

There is no native way to do this AFAIK. The easiest way will be:

  • to simply query all the pages in the hierarchy of the page ID passed

  • then return all the parent ID’s ($post_parent property of the post object) from all pages in an array

  • loop through the pages and compare the page ID against the ID’s in the parent ID’s array

  • any page which has its ID in the parent ID’s array we will simply skip and exclude

  • any page which ID is not in the parent ID array, we will use this to build a new array, these pages will be the lowest level pages

The easiest will be to build our own custom function which we can call in any page template. Here is the function:

function get_lowest_level_pages( $page_id = '' )
{
    // Check if we have a page id, if not, return false
    if ( !$page_id )
            return false;

    // Validate the page id
    $page_id = filter_var( $page_id, FILTER_VALIDATE_INT );

    // Check if this is a page, if not, return false
    if ( !is_page() )
        return false;

    // Get all pages in hierarchy of the current page
    $args = [
        'child_of' => $page_id,
    ];
    $q = get_pages( $args );

    // Check if there are pages, if not, return false
    if ( !$q )
        return false;

    // Use wp_list_pluck to get all the post parents from all return pages
    $parents = wp_list_pluck( $q, 'post_parent' );
    // Set the $new__page_array variable that will hold grandchildren/lowest level pages
    $new__page_array = [];

    // Loop through all the pages
    foreach ( $q as $page_object ) {
        // Simply skip any page if it has child page
        if ( in_array( $page_object->ID, $parents ) )
            continue;

        // Create a new array holding only grandchild pages
        $new__page_array[] = $page_object;
    }

    return $new__page_array; 
}

You can then use it as follow: (Just remember to pass the id of the parent page you need to get the grand children from)

$page_id = get_queried_object_id(); // Returns the current page ID
$q = get_lowest_level_pages( $page_id );

if ( $q ) {
    foreach ( $q as $post ) {
        setup_postdata( $post );

        the_title();

    }
    wp_reset_postdata();
}

Leave a Reply

Your email address will not be published. Required fields are marked *