Вам нужно черех хук
pre_get_posts модифицировать основной запрос WP_Query, и указать выборку только из конкретной категории, без детишек. Есть 2 варианта.
Вариант 1 – на всех архивах категорий всегда выводить только записи конкретно из запрошенного термина:
/**
* For category archives, always show only the posts in queried category, not their children.
*
* @param \WP_Query $query
*/
function exclude_category_children( $query ) {
if ( $query->is_category() && $query->is_main_query() ) {
$query->set( 'tax_query', [
[
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $query->query_vars['category_name'],
'include_children' => false
],
] );
}
}
add_action( 'pre_get_posts', 'exclude_category_children' );
Вариант 2 – то же самое, только без явного Tax_Query, хотя с промежуточным получением текущего термина:
function exclude_category_children( $query ) {
if ( $query->is_category() && $query->is_main_query() ) {
$category = get_category_by_slug( $query->query_vars['category_name'] );
$query->set( 'category__in', $category->term_id );
}
}
add_action( 'pre_get_posts', 'exclude_category_children' );
Параметр
category__in
заставляет WP_Query возвращать по строгому совпадению, поэтому будет без дочерних. Но нужно сначала получить ID категории, поэтому будет один дополнительный запрос. При использовании хука pre_get_posts первый вариант лучше. При использовании произвольного вторичного цикла WP_Query второй метод будет лучше (передать сразу ID категории в параметры нового WP_Query).