Как создать динамическую иерархию постов в WordPress

|

В WordPress стандартно реализована иерархия страниц, но для обычных записей (постов) такой функционал отсутствует. Многие разработчики и владельцы сайтов сталкиваются с необходимостью создать структуру, в которой записи будут связаны между собой в виде родитель-потомок, то есть иерархично. В этой статье мы подробно разберём, как реализовать динамическую иерархию постов с помощью пользовательских типов записей, метаполей и таксономий, а также приведём пример кода, который поможет вам быстро внедрить такую функциональность на вашем сайте.

Почему стандартные посты в WordPress не поддерживают иерархию

По умолчанию записи в WordPress не имеют свойства "родитель" — они плоские, что упрощает организацию блога, но ограничивает возможности структурирования контента. При этом страницы поддерживают иерархию, что позволяет создавать вложенные страницы и строить дерево контента. Однако иногда требуется иерархия именно для постов, например, для новостных лент с подтемами, каталогов или обучающих материалов с разделами и подразделами.

Обычное решение — создавать кастомные типы записей с поддержкой иерархии. Но это не всегда удобно, если контент уже в стандартных постах. Поэтому мы рассмотрим способ динамического построения иерархии постов с помощью кастомных полей и мета-запросов.

Создание пользовательского поля для указания родительского поста

Первый шаг — добавить метаполе, где можно выбрать родительскую запись для каждого поста. Для этого можно использовать плагин Advanced Custom Fields (ACF) или создать метабокс вручную.

Пример создания метабокса через код

Добавим метабокс с выпадающим списком постов:

function wphierarchy_add_parent_post_metabox() {
    add_meta_box(
        'wphierarchy_parent_post',
        'Родительский пост',
        'wphierarchy_parent_post_callback',
        'post',
        'side',
        'default'
    );
}
add_action('add_meta_boxes', 'wphierarchy_add_parent_post_metabox');

function wphierarchy_parent_post_callback($post) {
    wp_nonce_field('wphierarchy_save_parent_post', 'wphierarchy_parent_post_nonce');
    $parent_id = get_post_meta($post->ID, '_wphierarchy_parent_post', true);
    $args = [
        'post_type' => 'post',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'post__not_in' => [$post->ID], // исключаем текущий пост
    ];
    $posts = get_posts($args);
    echo '<select name="wphierarchy_parent_post" id="wphierarchy_parent_post">';
    echo '<option value="">Без родителя</option>';
    foreach ($posts as $p) {
        $selected = $parent_id == $p->ID ? 'selected' : '';
        echo "<option value=\"{$p->ID}\" $selected>{$p->post_title}</option>";
    }
    echo '</select>';
}

function wphierarchy_save_parent_post_meta($post_id) {
    if (!isset($_POST['wphierarchy_parent_post_nonce']) || !wp_verify_nonce($_POST['wphierarchy_parent_post_nonce'], 'wphierarchy_save_parent_post')) {
        return;
    }
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    if (isset($_POST['wphierarchy_parent_post'])) {
        $parent_post = intval($_POST['wphierarchy_parent_post']);
        // Предотвращение циклов
        if ($parent_post !== $post_id) {
            update_post_meta($post_id, '_wphierarchy_parent_post', $parent_post);
        }
    }
}
add_action('save_post', 'wphierarchy_save_parent_post_meta');

Данный код добавляет на страницу редактирования поста поле для выбора родителя из существующих записей. При сохранении значение сохраняется в мета-поле _wphierarchy_parent_post.

Вывод иерархии постов на фронтенде

Чтобы вывести иерархию, нужно получить все посты и построить дерево на основании сохранённых связей. Для этого проще всего сначала загрузить все посты с мета-полем, а затем рекурсивно сформировать вложенный список.

Функция для получения дочерних постов

function wphierarchy_get_children_posts($parent_id = 0, $all_posts = []) {
    $children = [];
    foreach ($all_posts as $post) {
        $post_parent = get_post_meta($post->ID, '_wphierarchy_parent_post', true);
        if (!$post_parent) $post_parent = 0;
        if (intval($post_parent) === intval($parent_id)) {
            $children[] = $post;
        }
    }
    return $children;
}

Функция для построения дерева

function wphierarchy_build_tree($parent_id = 0, $all_posts = []) {
    $tree = '';
    $children = wphierarchy_get_children_posts($parent_id, $all_posts);
    if ($children) {
        $tree .= '<ul>';
        foreach ($children as $child) {
            $tree .= '<li><a href="' . get_permalink($child->ID) . '">' . esc_html($child->post_title) . '</a>';
            $tree .= wphierarchy_build_tree($child->ID, $all_posts);
            $tree .= '</li>';
        }
        $tree .= '</ul>';
    }
    return $tree;
}

Пример вывода иерархии в шаблоне

$args = [
    'post_type' => 'post',
    'posts_per_page' => -1,
    'post_status' => 'publish',
];
$all_posts = get_posts($args);
echo wphierarchy_build_tree(0, $all_posts);

Такой подход позволяет вывести вложенный список постов, где каждый уровень соответствует уровню иерархии. Можно стилизовать список через CSS для удобства восприятия.

Обработка циклических ссылок и другие нюансы

При создании иерархии важно учитывать, что пользователь может по ошибке указать в качестве родителя самого себя или создать циклы (например, пост А - родитель поста В, а пост В - родитель поста А). Для предотвращения таких ситуаций в функции сохранения метаполя мы проверяем, что родитель не совпадает с самим постом.

Для более сложной проверки, чтобы избежать циклов глубже, можно реализовать обход дерева при сохранении и проверять, что родитель не является потомком текущей записи. Это можно сделать, добавив рекурсивную функцию проверки.

Интеграция с плагинами WPShop.ru

Если вы хотите расширить возможности иерархии, например, добавить визуальный редактор структуры или улучшить SEO, обратите внимание на плагины с WPShop.ru, например, Clearfy Pro для оптимизации и управления метаданными, а также ABC Pagination для удобной навигации по вложенным спискам постов.

Кроме того, если на вашем сайте много контента, используйте кэширование и фильтрацию запросов, чтобы не перегружать базу данных при построении иерархии.

Заключение

Создание динамической иерархии постов в WordPress — задача, которую можно решить с помощью метаполей, кастомных функций и аккуратного построения дерева. Такой подход позволяет строить гибкие структуры контента без необходимости перехода на кастомные типы записей.

Используйте предложенный код как основу и адаптируйте под свои задачи. При необходимости расширяйте функционал, интегрируя полезные плагины и оптимизируя вывод.

Создание дерева категорий с подсчетом постов в WordPress
06.03.2026
Как создать дерево разделений в WordPress с подсчетом и фильтрацией
14.03.2026
Как создать и использовать иерархию пользователей в WordPress для управления доступом
15.12.2025
Как создать иерархию для пользовательских метаполей в WordPress
01.02.2026
Как реализовать иерархию с нюансами в WordPress с помощью мета-полей
15.01.2026
×
День SEO
Время сделать подарок своему WordPress!
-20% на премиум

шаблоны и плагины

Порадуй свой сайт ⋙