WordPress shows posts from all subcategories by default. This sometimes leads to mess. We will exclude these posts from the main category.
Before loop if (have_posts()) you need to insert this code:
// Get ID of current category
$category = get_queried_object();
$categories = get_categories(
['parent' => $category->term_id]
);
// Collect the child category IDs of this parent:
$children = [];
foreach ($categories as $k => $v) {
$children[] = $v->term_id;
}
// Add new argument:
$args = [
'category__not_in' => $children,
];
// Merge new arg with global query_posts
global $wp_query;
query_posts(
array_merge(
$wp_query->query,
$args
)
);
$category = get_queried_object();
$categories = get_categories(
['parent' => $category->term_id]
);
// Collect the child category IDs of this parent:
$children = [];
foreach ($categories as $k => $v) {
$children[] = $v->term_id;
}
// Add new argument:
$args = [
'category__not_in' => $children,
];
// Merge new arg with global query_posts
global $wp_query;
query_posts(
array_merge(
$wp_query->query,
$args
)
);
And then adding original loop code:
if (have_posts()) : while (have_posts()) : the_post();