Return parent post with its children using WP_Query?

We can filter the posts_where clause of the generated SQL to also return the parent post/page and not just the parent’s children. Here we will set our own custom argument called wpse_include_parent, which, when set to true, will alter the generated SQL accordingly.

All we need to do inside our posts_where filter is to check if our custom argument is set and that the post_parent argument is set. We then get that value and pass it to the filter to extend our SQL query. What is nice here, post_parent excepts a single integer value, so we only need to validate the value as an integer.

THE QUERY

$args = [
    'wpse_include_parent' => true,
    'post_parent'         => 256,
    'post_type'           => 'page'
    // Add additional arguments
];
$q = new WP_Query( $args );

As you can see, we have set 'wpse_include_parent' => true to “activate” our filter.

THE FILTER

add_filter( 'posts_where', function ( $where, \WP_Query $q ) use ( &$wpdb )
{
    if ( true !== $q->get( 'wpse_include_parent' ) )
        return $where;

    /**
     * Get the value passed to from the post parent and validate it
     * post_parent only accepts an integer value, so we only need to validate
     * the value as an integer
     */
    $post_parent = filter_var( $q->get( 'post_parent' ), FILTER_VALIDATE_INT );
    if ( !$post_parent )
        return $where;

    /** 
     * Lets also include the parent in our query
     *
     * Because we have already validated the $post_parent value, we 
     * do not need to use the prepare() method here
     */
    $where .= " OR $wpdb->posts.ID = $post_parent";

    return $where;
}, 10, 2 );

You can extent this as you need and see fit, but this is the basic idea. This will return the parent passed to post_parent and it’s children

Leave a Comment