Post Ancestor and Child Post in Custom Post Type

enter image description here

Hierarchical structure of custom post type “Book” (for example).

Read More

When we are on Post 2-95, I want to know:

  • Does the post has this post ancestor(Post 1-31)?
  • Does it have child posts(Post 3-19, Post 3-10)?

Then, if it has:

  • an ancestor post: retrieve (object) of this post.
  • a child posts: retrieve (objects) of these posts.

Related posts

Leave a Reply

2 comments

  1. Given a post represented by a post object $p, you can find out if post 31 is the parent via:

    if($p->post_parent == 31){
        // it is!
    } else {
        // it isn't
    }
    

    To figure out the children, something like:

    $posts = get_posts(array(
        'post_parent' => $p->ID,
        'post_type'   => $p->post_type
    ));
    // if there are children, they will be contained in `$posts`
    

    Finally, to determine how many levels deep down the hierarchy you are, you will need to recurse up the hierarchy $p->parent_post == 0, and then count how many times you needed to do that.

    e.g.

    $level = 1;
    while($parent->parent_post != 0){
        $level++;
        $parent = get_post($parent->parent_post);
    }
    
  2. Check if current post is in range

    We check with the function, if we are…

    • in the Loop?
    • in the set range?

    Stick all the functions in your functions.php file.

    function wpse52285_is_post_in_range( $post, int $range_from, int $range_to )
    {
        // If we're IN the LOOP @link http://codex.wordpress.org/Function_Reference/in_the_loop
        if ( ! in_the_loop() )
            return false;
    
        // Abort if not in the allowed range
        if ( ! in_array( $post->ID, range( $range_from, $range_to ) ) )
            return false;
    
        return true;
    }
    

    Check if we got children in range

    We check, if we…

    • are inside the loop?
    • got children of the needed post type (can be any custom post type, post, page, attachment, link, etc.)
    • the children are in range?

    In case nothing was found, we return false, so we can make our check easier.

    function wpse52285_get_children_in_range( $post, int $range_from, int $range_to, $post_type = 'post' )
    {
        if ( ! in_the_loop() )
            return false;
    
        // get_children() @link http://codex.wordpress.org/Function_Reference/get_children
        $children = get_children( "post_parent={$post->ID}&post_type={$post_type}" );
        if ( 0 < count( $children ) )
        {
            foreach ( $children as $child )
            {
                in_array( $id, range( $range_from, $range_to ) ) AND $in_range[] = $child;
            }
            if ( 0 < count( $in_range ) )
                return $in_range;
        }
    
        return false;
    }
    

    Check if we got ancestors

    We check, if…

    • we are in the loop?
    • we got ancestors?
    • ancestors are in range?

    In case nothing meets, we again return false.

    function wpse52285_get_ancestors_in_range( $post, int $range_from, int $range_to )
    {
        if ( ! in_the_loop() )
            return false;
    
        // get_post_ancestors @link http://codex.wordpress.org/Function_Reference/get_post_ancestors
        $ancestors = get_post_ancestors( $post->ID );
        foreach ( $ancestors as $ancestor )
        {
            in_array( $ancestor->ID, range( $range_from, $range_to ) ) AND $in_range[] = $ancestor;
        }
        if ( 0 < count( $in_range ) )
            return $in_range;
    
        return false;
    }
    

    Template

    Now we can use it in any template like this:

    // The loop
    if have_posts() : while( have_posts() ): the_post();
        global $post;
    
        // Is our current post in range?
        if ( wpse52285_is_post_in_range( $post, 2, 95 ) )
        {
            // Are any child posts in range?
            $children = wpse52285_get_children_in_range( $post, 3, 19 );
            if ( $children )
            {
                // Do stuff with the children
            }
    
            // Are any ancestors in range?
            $ancestors = wpse52285_get_ancestors_in_range( $post, 1, 31 );
            if ( $ancestors )
            {
                // Do stuff with the ancestors 
            }
        }
    endwhile;
    endif;