В WordPress стандартно поддерживается иерархия только для страниц (post_type = 'page'), тогда как записи (post_type = 'post') не имеют такой возможности из коробки. Однако в ряде проектов возникает необходимость создавать иерархию для кастомных типов записей или даже для стандартных постов, чтобы структурировать контент более гибко.
Почему нужна иерархия постов с кастомной логикой
Чаще всего иерархия нужна для построения сложных структур каталога, портфолио, документации или справочников. В стандартном WordPress иерархия для постов не предусмотрена, что ограничивает разработчиков. Создание собственной иерархии позволяет формировать древовидные структуры с родителями и дочерними элементами, а также строить навигацию и фильтры по ним.
Такое решение полезно на крупных сайтах, где важна логическая группировка контента, например, в тематических блогах, образовательных порталах и корпоративных ресурсах.
Кейс: иерархия постов с родительскими связями
Рассмотрим, как реализовать иерархию для постов с помощью пользовательского поля, которое будет хранить ID родительского поста. Это позволит создать связь "родитель-дочерний" для произвольных записей.
Создаем пользовательское поле для родителя
Для начала добавим мета-поле "wphierarchy_parent_post" типа select, где можно выбрать родительский пост из списка. Для удобства используем плагин Advanced Custom Fields (ACF) или создадим поле вручную:
function wphierarchy_register_parent_post_meta() {
register_post_meta('post', 'wphierarchy_parent_post', [
'show_in_rest' => true,
'single' => true,
'type' => 'integer',
'default' => 0,
]);
}
add_action('init', 'wphierarchy_register_parent_post_meta');Далее нужно вывести поле в админке при редактировании записи. Практичнее всего это сделать через ACF или мета-бокс, где будет выпадающий список всех постов для выбора родителя.
Вывод иерархии постов на фронтенде
Для отображения иерархии реализуем рекурсивную функцию, которая построит дерево с вложенностью по родительским связям.
function wphierarchy_get_child_posts($parent_id = 0) {
$args = [
'post_type' => 'post',
'meta_key' => 'wphierarchy_parent_post',
'meta_value' => $parent_id,
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
];
$posts = get_posts($args);
$output = '';
if ($posts) {
$output .= '<ul>';
foreach ($posts as $post) {
$output .= '<li><a href="' . get_permalink($post->ID) . '">' . esc_html($post->post_title) . '</a>';
$output .= wphierarchy_get_child_posts($post->ID);
$output .= '</li>';
}
$output .= '</ul>';
}
return $output;
}Вывести иерархию можно вызовом:
echo wphierarchy_get_child_posts(0); // 0 - корневой уровеньУлучшение: пагинация и AJAX-загрузка дочерних элементов
При большом количестве постов строить всю иерархию сразу неэффективно. Для этого стоит реализовать AJAX-загрузку дочерних элементов при клике на родителя. Можно использовать WP AJAX API и добавить обработчик, который вернет вложенные записи динамически.
Пример регистрации обработчика AJAX:
add_action('wp_ajax_wphierarchy_load_children', 'wphierarchy_load_children_callback');
function wphierarchy_load_children_callback() {
$parent_id = intval($_POST['parent_id']);
echo wphierarchy_get_child_posts($parent_id);
wp_die();
}На фронтенде добавьте JS, который будет по клику отправлять запрос и подгружать список.
Советы по оптимизации и безопасности
При работе с кастомной иерархией важно:
- Кэшировать результаты запросов, чтобы снизить нагрузку на базу.
- Обрабатывать пользовательский ввод через
intvalиesc_htmlдля безопасности. - Использовать nonce-поля для AJAX-запросов, чтобы защитить от CSRF.
Плагины, которые могут помочь
Если не хочется писать код с нуля, можно использовать готовые решения:
- Hierarchical Posts — добавляет иерархию для постов.
- Clearfy Pro — улучшает производительность и управление, включая работу с иерархиями.
Также для визуальной настройки иерархий удобно использовать ABC Pagination для постраничной навигации по спискам.
Вывод
Создание пользовательской иерархии постов в WordPress — задача решаемая и достаточно востребованная. Используя пользовательские мета-поля, кастомные запросы и AJAX-загрузку, можно реализовать удобный и гибкий интерфейс для управления вложенными структурами. Это значительно расширяет возможности стандартного CMS и упрощает работу с большим объемом контента.