parent
is your answer here. Every term have a parent value set in its parent
property. This value is an integer value, and represent the term id of its parent term. All top level terms have a value of 0
which just simply means it is a top level term
First we need to build an array with parent terms and the specific terms from get_the_category
. We will skip 0
values. Once we have our array of ids, we will get all unique values and pass the array of ids to a tax_query
in order to save on multiple queries
(The following code is untested and require PHP 5.4+)
function get_related_category_posts()
{
// Check if we are on a single page, if not, return false
if ( !is_single() )
return false;
// Get the current post id
$post_id = get_queried_object_id();
// Get the post categories
$categories = get_the_category( $post_id );
// Lets build our array
// If we don't have categories, bail
if ( !$categories )
return false;
foreach ( $categories as $category ) {
if ( $category->parent == 0 ) {
$term_ids[] = $category->term_id;
} else {
$term_ids[] = $category->parent;
$term_ids[] = $category->term_id;
}
}
// Remove duplicate values from the array
$unique_array = array_unique( $term_ids );
// Lets build our query
$args = [
'post__not_in' => [$post_id],
'posts_per_page' => 3, // Note: showposts is depreciated in favor of posts_per_page
'ignore_sticky_posts' => 1, // Note: caller_get_posts is depreciated
'orderby' => 'title',
'no_found_rows' => true, // Skip pagination, makes the query faster
'tax_query' => [
[
'taxonomy' => 'category',
'terms' => $unique_array,
'include_children' => false,
],
],
];
$q = new WP_Query( $args );
return $q;
}
You can then use the code as follows in your single post page
$q = get_related_category_posts();
if ( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
// Your loop
}
wp_reset_postdata();
}