Динамическая иерархия типов постов в WordPress с поддержкой AJAX

|

В современных проектах на WordPress часто возникает необходимость организовать сложную структуру из пользовательских типов постов (Custom Post Types, CPT) с иерархией, которая должна динамически подгружаться без перезагрузки страницы. В этой статье мы рассмотрим, как создать такую динамическую иерархию с поддержкой AJAX, что позволит улучшить UX и оптимизировать работу сайта.

Почему нужна динамическая иерархия типов постов с AJAX

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

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

Создание иерархии CPT: подготовительный этап

Для примера создадим два пользовательских типа постов — product_category (категории продуктов) и product (продукты). Важно, чтобы product_category был иерархическим, а product — связанным с категориями.

Регистрируем CPT в файле functions.php или в плагине:

function wphierarchy_register_cpts() {
    register_post_type('product_category', [
        'label' => 'Категории продуктов',
        'public' => true,
        'hierarchical' => true,
        'show_ui' => true,
        'supports' => ['title', 'editor', 'page-attributes'],
        'rewrite' => ['slug' => 'product-category'],
    ]);

    register_post_type('product', [
        'label' => 'Продукты',
        'public' => true,
        'hierarchical' => false,
        'show_ui' => true,
        'supports' => ['title', 'editor', 'thumbnail'],
        'taxonomies' => ['product_category'],
        'rewrite' => ['slug' => 'product'],
    ]);
}
add_action('init', 'wphierarchy_register_cpts');

Здесь product_category — иерархический тип, что позволяет создавать вложенные категории, а product — тип с таксономией категорий.

Реализация AJAX-подгрузки иерархии

Основная идея — при клике по категории отправлять AJAX-запрос и получать дочерние категории и продукты, которые будут отображены под выбранным элементом.

Подключение скриптов и локализация

Добавим скрипт в админку или фронтенд (например, в шаблон):

function wphierarchy_enqueue_scripts() {
    wp_enqueue_script('wphierarchy-ajax', get_template_directory_uri() . '/js/wphierarchy-ajax.js', ['jquery'], null, true);
    wp_localize_script('wphierarchy-ajax', 'wphierarchy_ajax', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('wphierarchy_nonce'),
    ]);
}
add_action('wp_enqueue_scripts', 'wphierarchy_enqueue_scripts');

JavaScript для обработки кликов и AJAX-запросов

В файле js/wphierarchy-ajax.js пишем следующий код:

jQuery(document).ready(function($) {
    $(document).on('click', '.wphierarchy-toggle', function(e) {
        e.preventDefault();
        var parentId = $(this).data('parent');
        var container = $('#wphierarchy-children-' + parentId);

        if(container.is(':empty')) {
            $.ajax({
                url: wphierarchy_ajax.ajax_url,
                type: 'POST',
                data: {
                    action: 'wphierarchy_load_children',
                    parent_id: parentId,
                    nonce: wphierarchy_ajax.nonce
                },
                success: function(response) {
                    if(response.success) {
                        container.html(response.data.html);
                        container.slideDown();
                    } else {
                        alert('Ошибка загрузки данных');
                    }
                }
            });
        } else {
            container.slideToggle();
        }
    });
});

Обработка AJAX-запроса на сервере

В functions.php добавляем обработчик:

function wphierarchy_ajax_load_children() {
    check_ajax_referer('wphierarchy_nonce', 'nonce');

    $parent_id = intval($_POST['parent_id']);

    // Получаем дочерние категории
    $child_categories = get_posts([
        'post_type' => 'product_category',
        'post_parent' => $parent_id,
        'numberposts' => -1,
        'orderby' => 'title',
        'order' => 'ASC',
    ]);

    // Получаем продукты, привязанные к категории
    $products = get_posts([
        'post_type' => 'product',
        'tax_query' => [[
            'taxonomy' => 'product_category',
            'field' => 'term_id',
            'terms' => get_post_meta($parent_id, '_term_id', true),
        ]],
        'numberposts' => -1,
        'orderby' => 'title',
        'order' => 'ASC',
    ]);

    ob_start();
    if($child_categories) {
        echo '<ul class="wphierarchy-category-list">';
        foreach($child_categories as $cat) {
            echo '<li>' . esc_html($cat->post_title) . ' <a href="#" class="wphierarchy-toggle" data-parent="' . $cat->ID . '">+</a>';
            echo '<div id="wphierarchy-children-' . $cat->ID . '" class="wphierarchy-children" style="display:none;"></div>';
            echo '</li>';
        }
        echo '</ul>';
    }
    if($products) {
        echo '<ul class="wphierarchy-product-list">';
        foreach($products as $prod) {
            echo '<li>' . esc_html($prod->post_title) . '</li>';
        }
        echo '</ul>';
    }

    $html = ob_get_clean();

    wp_send_json_success(['html' => $html]);
}
add_action('wp_ajax_wphierarchy_load_children', 'wphierarchy_ajax_load_children');
add_action('wp_ajax_nopriv_wphierarchy_load_children', 'wphierarchy_ajax_load_children');

Обратите внимание, что для корректной работы запроса к продуктам по таксономии нужно хранить ID терма таксономии в мета-поле категории или сделать дополнительный запрос для получения term_id.

Оптимизация и дополнительные улучшения

Для больших иерархий стоит применять кеширование результатов AJAX-запросов, например, с помощью transient API WordPress или внешних кешей.

Также можно внедрить индикаторы загрузки, анимации для раскрытия списков и улучшить UX с помощью дополнительных JS-библиотек.

Для удобства администрирования можно использовать плагин Clearfy Pro, который оптимизирует AJAX-запросы и повышает безопасность сайта.

Выводы

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

Как создать иерархию таксономий с поддержкой AJAX в WordPress
01.01.2026
Как создать иерархию отзывов с поддержкой рейтингов в WordPress
20.02.2026
Как создать иерархию для виджетов WordPress с динамической подгрузкой
28.01.2026
Динамическая иерархия типов постов в WordPress с поддержкой AJAX
10.02.2026
WooCommerce: исправляем ошибку неправильного присвоения родительской категории товара
20.04.2026
×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше