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