Часто при разработке на WordPress возникает задача показать посты, сгруппированные по определённой таксономии — категориям, меткам или кастомным таксономиям. Это полезно для создания удобных архивов, каталогов или витрин контента, чтобы пользователи могли легко ориентироваться по тематическим блокам.
Что такое таксономии в WordPress и зачем нужна группировка
Таксономии — это способ классифицировать записи. В WordPress по умолчанию есть категории (category) и метки (post_tag), но можно создавать и свои таксономии для кастомных типов записей. Группировка постов по таксономии позволяет структурировать вывод и улучшить UX сайта.
Без группировки посты обычно выводятся в одном списке, что неудобно при большом объёме контента. Группировка разбивает их на логические блоки, что улучшает восприятие и навигацию.
Например, если у вас блог о путешествиях, вы можете сгруппировать записи по странам (кастомная таксономия). Или на сайте магазина — по брендам или типам товаров.
Как получить посты с группировкой по таксономии — базовый подход
Основная идея — сначала получить термины нужной таксономии, а затем для каждого термина вывести посты, которые к нему относятся.
Для этого используем функции get_terms() и WP_Query или get_posts(). Вот пример базового шаблона:
$terms = get_terms(array(
'taxonomy' => 'category', // или ваша таксономия
'hide_empty' => true, // показывать только с постами
));
if (!empty($terms) && !is_wp_error($terms)) {
foreach ($terms as $term) {
echo '<h2>' . esc_html($term->name) . '</h2>';
$posts = get_posts(array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => $term->term_id,
),
),
'posts_per_page' => 5, // лимит постов
));
if ($posts) {
echo '<ul>';
foreach ($posts as $post) {
echo '<li><a href="' . get_permalink($post) . '">' . esc_html(get_the_title($post)) . '</a></li>';
}
echo '</ul>';
} else {
echo '<p>Посты не найдены</p>';
}
}
} else {
echo '<p>Таксономии не найдены</p>';
}
Такой подход универсален, но при большом количестве терминов и постов может быть медленным из-за большого количества запросов к базе.
Оптимизация группировки постов по таксономии с использованием одного запроса
Чтобы уменьшить количество запросов, можно получить все посты сразу с нужным таксономическим условием и затем группировать их в PHP. Это экономит ресурсы базы и ускоряет вывод.
Пример кода для группировки постов по таксономии category:
$args = array(
'post_type' => 'post',
'posts_per_page' => -1, // все посты
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => get_terms(array(
'taxonomy' => 'category',
'fields' => 'ids',
'hide_empty' => true,
)),
),
),
);
$query = new WP_Query($args);
$grouped_posts = array();
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
$terms = get_the_terms(get_the_ID(), 'category');
if ($terms && !is_wp_error($terms)) {
foreach ($terms as $term) {
$grouped_posts[$term->term_id]['term'] = $term;
$grouped_posts[$term->term_id]['posts'][] = get_post();
}
}
}
wp_reset_postdata();
}
foreach ($grouped_posts as $group) {
echo '<h2>' . esc_html($group['term']->name) . '</h2>';
echo '<ul>';
foreach ($group['posts'] as $post) {
echo '<li><a href="' . get_permalink($post) . '">' . esc_html(get_the_title($post)) . '</a></li>';
}
echo '</ul>';
}
Так мы делаем всего один запрос к базе, а группировка по терминам происходит уже на уровне PHP.
Использование кастомных таксономий и типов записей для группировки
Если у вас есть кастомные типы записей и таксономии, например, для портфолио или товаров, метод аналогичный. Важно правильно указать параметры в запросе.
Пример: кастомная таксономия project_category и тип записи portfolio:
$terms = get_terms(array(
'taxonomy' => 'project_category',
'hide_empty' => true,
));
foreach ($terms as $term) {
echo '<h2>' . esc_html($term->name) . '</h2>';
$posts = get_posts(array(
'post_type' => 'portfolio',
'tax_query' => array(
array(
'taxonomy' => 'project_category',
'field' => 'term_id',
'terms' => $term->term_id,
),
),
'posts_per_page' => 10,
));
if ($posts) {
echo '<ul>';
foreach ($posts as $post) {
echo '<li><a href="' . get_permalink($post) . '">' . esc_html(get_the_title($post)) . '</a></li>';
}
echo '</ul>';
} else {
echo '<p>Посты не найдены</p>';
}
}
Такой код легко адаптировать под любые свои типы записей и таксономии.
Пример плагина для группировки постов по таксономии — wpvip_group_posts
Чтобы не повторять код, можно сделать мини-плагин, который предоставит шорткод для вывода сгруппированных постов по любой таксономии.
Пример простого плагина:
/**
* Plugin Name: WPVIP Group Posts
* Description: Шорткод [wpvip_group_posts taxonomy="category" post_type="post" posts_per_term="5"] для группировки постов по таксономии
* Version: 1.0
* Author: WPVIP
*/
function wpvip_group_posts_shortcode($atts) {
$atts = shortcode_atts(array(
'taxonomy' => 'category',
'post_type' => 'post',
'posts_per_term' => 5,
), $atts, 'wpvip_group_posts');
$terms = get_terms(array(
'taxonomy' => $atts['taxonomy'],
'hide_empty' => true,
));
if (empty($terms) || is_wp_error($terms)) {
return '<p>Таксономии не найдены</p>';
}
$output = '';
foreach ($terms as $term) {
$output .= '<h2>' . esc_html($term->name) . '</h2>';
$posts = get_posts(array(
'post_type' => $atts['post_type'],
'tax_query' => array(
array(
'taxonomy' => $atts['taxonomy'],
'field' => 'term_id',
'terms' => $term->term_id,
),
),
'posts_per_page' => intval($atts['posts_per_term']),
));
if ($posts) {
$output .= '<ul>';
foreach ($posts as $post) {
$output .= '<li><a href="' . get_permalink($post) . '">' . esc_html(get_the_title($post)) . '</a></li>';
}
$output .= '</ul>';
} else {
$output .= '<p>Посты не найдены</p>';
}
}
return $output;
}
add_shortcode('wpvip_group_posts', 'wpvip_group_posts_shortcode');
Теперь достаточно добавить в запись или страницу шорткод [wpvip_group_posts taxonomy="category" post_type="post" posts_per_term="5"], чтобы вывести сгруппированные записи.
Советы по улучшению и кешированию
Для ускорения работы и снижения нагрузки рекомендуется кешировать результаты группировки. Можно использовать транзиенты (transients) или встроенный кеш WP Object Cache.
Пример кеширования в плагине:
function wpvip_group_posts_shortcode($atts) {
$atts = shortcode_atts(array(
'taxonomy' => 'category',
'post_type' => 'post',
'posts_per_term' => 5,
), $atts, 'wpvip_group_posts');
$cache_key = 'wpvip_group_posts_' . md5(serialize($atts));
$output = get_transient($cache_key);
if ($output === false) {
// код формирования $output как в предыдущем примере
// ...
set_transient($cache_key, $output, 12 * HOUR_IN_SECONDS);
}
return $output;
}
Такой подход значительно уменьшит время ответа и нагрузку базы, особенно на больших сайтах.
Плагины для расширенной работы с таксономиями и группировкой
Если хотите более продвинутый функционал без кода, обратите внимание на плагины:
- List Category Posts — выводит посты из категории с гибкими настройками;
- Clearfy Pro — оптимизация и дополнительные возможности, в том числе по работе с таксономиями;
- WPCommunity — для создания сообществ с расширенной классификацией и выводом контента.
Эти инструменты помогут создать удобный и быстрый вывод группированного контента без глубокого погружения в код.