Самый простой вариант, хотя и не самый производительный, если таких "групп записей" много:
// Сначала получаем термины кастомной таксономии:
$terms = get_terms( [
'taxonomy' => 'taxonomy_name', // тут укажите правильное название вашей таксономии
'hide_empty' => true,
] );
// Далее циклом выводим эти блоки:
foreach ( $terms as $term ) :
echo '<div>';
// Получаем Х записей с конкретным термином, формируем параметры запроса:
$args = [
'post_type' => 'post_type_name', // тут укажите правильное название вашего custom post type
'posts_per_page' => 5 // количество записей
'tax_query' => [
[
'taxonomy' => 'taxonomy_name', // тут укажите правильное название вашей таксономии
'field' => 'term_id', // term_id, slug или name - что удобнее
'terms' => $term->term_id, // ID текущего термина в цикле
'include_children' => false,
],
],
];
// Получаем Х записей с конкретным термином:
$posts_with_term = new WP_Query( $args );
// Выводим записи циклом:
while ( $posts_with_term->have_posts() ) : $posts_with_term->the_post();
// Тут форматируйте вывод как угодно:
the_title();
endwhile;
wp_reset_postdata();
echo '</div>';
endforeach;
Дополнительно почитайте про все параметры WP_Query, чтобы оптимизировать их (например, отключить пагинацию, кеширование метаданных и терминов так как здесь они вам не нужны и тд) - это позволит уменьшить общее количество запросов к БД и повысить производительность.
Очевидно, что если терминов у вас много, то каждый термин будет давать дополнительный WP_Query. Производительность будет немножко падать по мере роста количества терминов, которые требуется вывести. Впрочем, эти списки не будут меняться прям очень часто, поэтому тут сразу просится кеширование.
Кеширование я бы делал так:
1. Каждый WP_Query кешируется в transients / object cache (только почитайте как правильно кешировать именно $query->results а не весь объект WP_Query).
2. Каждому такому блоку в кеше присваиваем рандомное (в определенном диапазоне) время жизни. Чтобы все блоки не сбрасывались и не пересоздавались одновременно. Так регенерация кеша будет незаметна, если есть более-менее стабильный трафик.
3. При добавлении новой записи смотреть в какой блок она входит и удалять этот блок из кеша. Это предотвратит отображение устаревшей информации.
P.S.: Писал не проверяя прямо здесь, так что мог где-то опечататься, но в целом должно работать.
P.P.S.: Сложность этого вопроса "средний", а не "сложный" - это все делается стандартными средствами и подробно расписано в документации.