Wordpress - Return parent post with its children using WP_Query?
If all you want is results from the "page" post_type then do as @birgire suggested.
Alternatively you can adapt the following to give you a similar result for not only the page
post_type
but any custom post type.
$parent = 2; //change as desired
$type = 'page'; //change as desired
$child_args = array(
'post_type' => $type,
'post_parent' => $parent
);
$ids = array($parent);
$ids = array_merge($keys, array_keys( get_children( $child_args ) ));
$query = new WP_Query(
array(
'post_type' => 'page',
'post_status' => 'publish',
'post__in' => $ids,
'posts_per_page' => -1
)
);
The above is essentially the same thing as hooking onto the posts_where
filter and parsing the SQL clause however, this achieves exactly the same thing.
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