Как создать динамический фильтр товаров в WooCommerce без плагинов

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

Почему стоит отказаться от плагинов фильтрации

Многие используют популярные плагины вроде WooCommerce Product Filter, FacetWP или Themify Filter. Они удобны, но имеют существенные минусы:

  • Нагрузка на сайт — дополнительные скрипты и запросы замедляют загрузку.
  • Конфликты с темами и другими плагинами — часто возникают проблемы совместимости.
  • Зависимость от обновлений и поддержки разработчиков.

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

Основы динамической фильтрации в WooCommerce

Фильтрация товаров в WooCommerce базируется на WP_Query и таксономиях. Атрибуты товаров — это таксономии, например, цвет, размер, бренд. Цена — это мета-поле. Для динамического фильтра нам нужно:

  1. Вывести форму с фильтрами, значения которых подтягиваются из базы.
  2. Обработать отправленные данные и изменить запрос товаров.
  3. Отобразить результаты без перезагрузки страницы (опционально).

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

Для начала сформируем форму, которая будет содержать чекбоксы с атрибутами и диапазон цен. Предположим, что у вас есть атрибут "Цвет" (pa_color).

<form method="GET" id="wordpresses-filter">
  <h3>Цвет</h3>
  <?php
  $colors = get_terms(array(
    'taxonomy' => 'pa_color',
    'hide_empty' => true
  ));
  foreach ($colors as $color) {
    $checked = isset($_GET['filter_color']) && in_array($color->slug, $_GET['filter_color']) ? 'checked' : '';
    echo '<label><input type="checkbox" name="filter_color[]" value="' . esc_attr($color->slug) . '" ' . $checked . '>' . esc_html($color->name) . '</label><br>';
  }
  ?>
  <h3>Цена</h3>
  <label>От <input type="number" name="price_min" value="<?php echo esc_attr($_GET['price_min'] ?? ''); ?>" min="0"></label>
  <label>До <input type="number" name="price_max" value="<?php echo esc_attr($_GET['price_max'] ?? ''); ?>" min="0"></label>
  <button type="submit">Фильтровать</button>
</form>

Обработка фильтра на стороне запроса

Чтобы изменить отображаемые товары в зависимости от фильтра, нужно подключиться к фильтру woocommerce_product_query. В нем мы добавим условия для атрибутов и цены.

add_action('woocommerce_product_query', 'wordpresses_filter_products_query');
function wordpresses_filter_products_query($query) {
  if (!is_admin() && is_shop()) {
    $tax_query = array();
    if (!empty($_GET['filter_color'])) {
      $tax_query[] = array(
        'taxonomy' => 'pa_color',
        'field' => 'slug',
        'terms' => array_map('sanitize_text_field', $_GET['filter_color']),
        'operator' => 'IN',
      );
    }
    if ($tax_query) {
      $query->set('tax_query', $tax_query);
    }
    $meta_query = $query->get('meta_query') ? $query->get('meta_query') : array();
    $price_min = isset($_GET['price_min']) ? floatval($_GET['price_min']) : 0;
    $price_max = isset($_GET['price_max']) ? floatval($_GET['price_max']) : 0;
    if ($price_min > 0 || $price_max > 0) {
      $price_filter = array('key' => '_price');
      if ($price_min > 0) {
        $price_filter['value'][] = $price_min;
        $price_filter['compare'] = '>=';
        $price_filter['type'] = 'NUMERIC';
      }
      if ($price_max > 0) {
        $price_filter['value'][] = $price_max;
        $price_filter['compare'] = isset($price_filter['compare']) ? 'BETWEEN' : '<=';
        $price_filter['type'] = 'NUMERIC';
      }
      if ($price_filter['compare'] === 'BETWEEN' && count($price_filter['value']) === 2) {
        $price_filter['value'] = array($price_min, $price_max);
      }
      $meta_query[] = $price_filter;
    }
    if ($meta_query) {
      $query->set('meta_query', $meta_query);
    }
  }
}

Опциональная AJAX-фильтрация

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

Пример простого AJAX-запроса:

jQuery(document).ready(function($) {
  $('#wordpresses-filter').on('submit', function(e) {
    e.preventDefault();
    var data = $(this).serialize();
    $.ajax({
      url: wc_add_to_cart_params.ajax_url,
      type: 'GET',
      data: data + '&action=wordpresses_filter_products',
      success: function(response) {
        $('#products-container').html(response);
      }
    });
  });
});

И серверная обработка AJAX запроса:

add_action('wp_ajax_wordpresses_filter_products', 'wordpresses_filter_products_ajax');
add_action('wp_ajax_nopriv_wordpresses_filter_products', 'wordpresses_filter_products_ajax');
function wordpresses_filter_products_ajax() {
  // Повторяем логику фильтрации из woocommerce_product_query
  // И выводим товары, например, через wc_get_template_part('content', 'product')
  $args = array(
    'post_type' => 'product',
    'posts_per_page' => 12,
    // Здесь добавляем таксономии и мета-запросы по аналогии с хуком выше
  );
  $query = new WP_Query($args);
  if ($query->have_posts()) {
    while ($query->have_posts()) {
      $query->the_post();
      wc_get_template_part('content', 'product');
    }
  } else {
    echo '<p>Товары не найдены</p>';
  }
  wp_die();
}

Выводы и рекомендации

Динамический фильтр без плагинов — отличный способ оптимизировать сайт, уменьшить количество сторонних зависимостей и повысить скорость загрузки. Главное — внимательно работать с WP_Query и безопасно обрабатывать входящие данные.

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

Если хотите усовершенствовать функционал, можно интегрировать данный фильтр с плагином Clearfy Pro для оптимизации базы данных и кеширования запросов. Подробнее об этом на wpshop.ru.

Решение проблемы: не работает визуальный редактор Gutenberg в WordPress
08.12.2025
Как добавить автоматическое сохранение постов через AJAX в WordPress
23.01.2026
Как создать внешний API для WordPress с поддержкой авторизации
23.12.2025
Как создать собственный вид записи в WordPress для специфических типов данных
15.12.2025
Как создать глобальный кеш для REST API и ускорить запросы
05.12.2025