Как создать динамические таблицы с вложенными фильтрами в WordPress

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

Почему нужны динамические таблицы с вложенными фильтрами

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

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

Подготовка данных: мета-поля и таксономии

Для примера создадим таблицу с кастомными постами типа product, у которых есть таксономии product_category и product_subcategory, а также мета-поле price. Вложенный фильтр будет работать так: сначала выбирается категория, затем подгружаются подкатегории только для выбранной категории, и после можно фильтровать по цене.

Добавим таксономии в functions.php или в отдельном плагине:

function hueman_register_product_taxonomies() {
    register_taxonomy('product_category', 'product', [
        'hierarchical' => true,
        'label' => 'Категории продуктов',
        'show_ui' => true,
        'rewrite' => ['slug' => 'product_category'],
    ]);
    register_taxonomy('product_subcategory', 'product', [
        'hierarchical' => true,
        'label' => 'Подкатегории продуктов',
        'show_ui' => true,
        'rewrite' => ['slug' => 'product_subcategory'],
    ]);
}
add_action('init', 'hueman_register_product_taxonomies');

Для мета-поля цены можно использовать Advanced Custom Fields (ACF) или создать поле вручную.

Реализация AJAX-фильтрации с вложенными фильтрами

Создаем форму фильтра

В шаблоне страницы выводим форму с двумя выпадающими списками и полем для цены:

<form id="hueman-filter-form">
  <select id="hueman-product-category" name="product_category">
    <option value="">Выберите категорию</option>
    <?php
    $categories = get_terms(['taxonomy' => 'product_category', 'hide_empty' => false]);
    foreach ($categories as $cat) {
        echo '<option value="' . esc_attr($cat->term_id) . '">' . esc_html($cat->name) . '</option>';
    }
    ?>
  </select>

  <select id="hueman-product-subcategory" name="product_subcategory" disabled>
    <option value="">Выберите подкатегорию</option>
  </select>

  <input type="number" name="max_price" id="hueman-max-price" placeholder="Максимальная цена" min="0" />

  <button type="submit">Фильтровать</button>
</form>

<div id="hueman-table-container"></div>

Обратите внимание, что список подкатегорий изначально отключен.

Подгрузка подкатегорий через AJAX

Добавим скрипт, который при выборе категории отправляет AJAX-запрос и подгружает подкатегории:

jQuery(document).ready(function($) {
  $('#hueman-product-category').on('change', function() {
    var catId = $(this).val();
    if (!catId) {
      $('#hueman-product-subcategory').html('<option value="">Выберите подкатегорию</option>').attr('disabled', true);
      return;
    }
    $.ajax({
      url: hueman_ajax_object.ajax_url,
      method: 'POST',
      data: {
        action: 'hueman_get_subcategories',
        category_id: catId
      },
      success: function(response) {
        var options = '<option value="">Выберите подкатегорию</option>';
        if (response.success) {
          $.each(response.data, function(index, subcat) {
            options += '<option value="' + subcat.term_id + '">' + subcat.name + '</option>';
          });
          $('#hueman-product-subcategory').html(options).attr('disabled', false);
        } else {
          $('#hueman-product-subcategory').html(options).attr('disabled', true);
        }
      }
    });
  });
});

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

function hueman_ajax_get_subcategories() {
    $category_id = intval($_POST['category_id'] ?? 0);
    if (!$category_id) {
        wp_send_json_error();
    }
    $subcategories = get_terms([
        'taxonomy' => 'product_subcategory',
        'hide_empty' => false,
        'parent' => 0, // Можно изменить логику, если есть вложенность
        'meta_query' => [[
            'key' => 'parent_category', // Зависит от структуры, может понадобиться кастомный метаполе или связь
            'value' => $category_id,
            'compare' => '=',
        ]],
    ]);
    if (empty($subcategories) || is_wp_error($subcategories)) {
        wp_send_json_error();
    }
    $data = [];
    foreach ($subcategories as $subcat) {
        $data[] = ['term_id' => $subcat->term_id, 'name' => $subcat->name];
    }
    wp_send_json_success($data);
}
add_action('wp_ajax_hueman_get_subcategories', 'hueman_ajax_get_subcategories');
add_action('wp_ajax_nopriv_hueman_get_subcategories', 'hueman_ajax_get_subcategories');

Важно: В данном примере предполагается, что у подкатегорий есть связь с родительской категорией через метаполе parent_category. Если используется иерархическая таксономия, то можно просто установить parent в get_terms.

Вывод таблицы с применением фильтров

При отправке формы будем делать AJAX-запрос, который вернет отфильтрованные продукты для вывода в таблице.

JS для обработки формы

$('#hueman-filter-form').on('submit', function(e) {
  e.preventDefault();
  var data = {
    action: 'hueman_filter_products',
    product_category: $('#hueman-product-category').val(),
    product_subcategory: $('#hueman-product-subcategory').val(),
    max_price: $('#hueman-max-price').val()
  };
  $.post(hueman_ajax_object.ajax_url, data, function(response) {
    if (response.success) {
      $('#hueman-table-container').html(response.data.html);
    } else {
      $('#hueman-table-container').html('<p>Товары не найдены.</p>');
    }
  });
});

PHP: обработка фильтра и вывод таблицы

function hueman_ajax_filter_products() {
    $args = [
        'post_type' => 'product',
        'posts_per_page' => -1,
        'tax_query' => [],
        'meta_query' => [],
    ];

    if (!empty($_POST['product_category'])) {
        $args['tax_query'][] = [
            'taxonomy' => 'product_category',
            'field' => 'term_id',
            'terms' => intval($_POST['product_category']),
        ];
    }

    if (!empty($_POST['product_subcategory'])) {
        $args['tax_query'][] = [
            'taxonomy' => 'product_subcategory',
            'field' => 'term_id',
            'terms' => intval($_POST['product_subcategory']),
        ];
    }

    if (!empty($_POST['max_price']) && is_numeric($_POST['max_price'])) {
        $args['meta_query'][] = [
            'key' => 'price',
            'value' => floatval($_POST['max_price']),
            'compare' => '<=',
            'type' => 'NUMERIC',
        ];
    }

    // Если есть несколько tax_query, нужно указать relation
    if (count($args['tax_query']) > 1) {
        $args['tax_query']['relation'] = 'AND';
    }

    $query = new WP_Query($args);

    if (!$query->have_posts()) {
        wp_send_json_error();
    }

    ob_start();
    echo '<table><thead><tr><th>Название</th><th>Категория</th><th>Подкатегория</th><th>Цена</th></tr></thead><tbody>';
    while ($query->have_posts()) {
        $query->the_post();
        $categories = get_the_terms(get_the_ID(), 'product_category');
        $subcategories = get_the_terms(get_the_ID(), 'product_subcategory');
        $price = get_post_meta(get_the_ID(), 'price', true);

        echo '<tr>';
        echo '<td>' . get_the_title() . '</td>';
        echo '<td>' . ($categories ? esc_html($categories[0]->name) : '') . '</td>';
        echo '<td>' . ($subcategories ? esc_html($subcategories[0]->name) : '') . '</td>';
        echo '<td>' . esc_html($price) . '</td>';
        echo '</tr>';
    }
    echo '</tbody></table>';
    wp_reset_postdata();

    $html = ob_get_clean();
    wp_send_json_success(['html' => $html]);
}
add_action('wp_ajax_hueman_filter_products', 'hueman_ajax_filter_products');
add_action('wp_ajax_nopriv_hueman_filter_products', 'hueman_ajax_filter_products');

Оптимизация и расширение функционала

Для повышения производительности рекомендуется использовать кеширование результатов AJAX-запросов, например, с помощью Transients API. Также можно добавить пагинацию и сортировку по столбцам таблицы.

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

Заключение

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

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
Как использовать хук pre_get_posts для динамической фильтрации выводимых постов в WordPress
21.04.2026
Как создать динамическую футбольную таблицу в WordPress с AJAX
27.02.2026
Как сделать динамические отзывы с оценкой в WordPress: практическое руководство
02.02.2026
Как создать динамические таблицы в WordPress с помощью шорткодов
20.11.2025
Как создать динамический календарь событий в WordPress с поддержкой AJAX
24.02.2026
×
WordPress
прокачай свой сайт!

-20% на премиум темы и плагины

Сделай апгрейд сайта ⋙