wphow.ru wordpress WPHow

Как создать уникальный фильтр постов WordPress по мета-данным

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

Что такое мета-данные в WordPress и зачем фильтровать по ним

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

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

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

Создание базового фильтра по мета-данным с WP_Query

Самый простой способ — использовать параметр meta_query в WP_Query. Рассмотрим пример, где нужно вывести посты с мета-данным price меньше 1000:

function wphow_get_posts_by_price() {
    $args = [
        'post_type' => 'product',
        'meta_query' => [
            [
                'key' => 'price',
                'value' => 1000,
                'compare' => '<',
                'type' => 'NUMERIC'
            ]
        ]
    ];

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            echo '<h3>' . get_the_title() . '</h3>';
            echo '<p>Цена: ' . get_post_meta(get_the_ID(), 'price', true) . '</p>';
        }
    } else {
        echo '<p>Посты не найдены.</p>';
    }
    wp_reset_postdata();
}

Этот код можно вызвать в шаблоне, чтобы вывести отфильтрованные посты. Но это только базовый пример без интерфейса для выбора фильтров пользователем.

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

Чтобы пользователи могли фильтровать посты, создадим HTML-форму, которая отправляет параметры фильтрации через GET-запрос. Затем обработаем эти параметры в WP_Query.

Пример формы фильтра

<form method="GET" action="">
    <label>Максимальная цена:</label>
    <input type="number" name="max_price" value="<?php echo isset($_GET['max_price']) ? intval($_GET['max_price']) : ''; ?>" />
    <label>Цвет:</label>
    <select name="color">
        <option value="">Любой</option>
        <option value="red" <?php selected($_GET['color'] ?? '', 'red'); ?>>Красный</option>
        <option value="blue" <?php selected($_GET['color'] ?? '', 'blue'); ?>>Синий</option>
        <option value="green" <?php selected($_GET['color'] ?? '', 'green'); ?>>Зелёный</option>
    </select>
    <button type="submit">Фильтровать</button>
</form>

Обработка и формирование meta_query

function wphow_filter_posts_by_meta() {
    $meta_query = ['relation' => 'AND'];

    if (!empty($_GET['max_price'])) {
        $max_price = intval($_GET['max_price']);
        $meta_query[] = [
            'key' => 'price',
            'value' => $max_price,
            'compare' => '<=',
            'type' => 'NUMERIC'
        ];
    }

    if (!empty($_GET['color'])) {
        $color = sanitize_text_field($_GET['color']);
        $meta_query[] = [
            'key' => 'color',
            'value' => $color,
            'compare' => '='
        ];
    }

    $args = [
        'post_type' => 'product',
        'meta_query' => $meta_query
    ];

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        echo '<ul>';
        while ($query->have_posts()) {
            $query->the_post();
            echo '<li>' . get_the_title() . ' - Цена: ' . get_post_meta(get_the_ID(), 'price', true) . ', Цвет: ' . get_post_meta(get_the_ID(), 'color', true) . '</li>';
        }
        echo '</ul>';
    } else {
        echo '<p>Нет подходящих товаров.</p>';
    }
    wp_reset_postdata();
}

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

Оптимизация фильтров по мета-данным: индексы и кэширование

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

  • Добавьте индексы на колонки meta_key и meta_value в таблице wp_postmeta (если вы уверены в своих действиях и сделали резервную копию).
  • Используйте транзиенты (set_transient) для кэширования результатов запросов, если данные меняются нечасто.
  • Ограничивайте количество результатов и используйте пагинацию.

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

Создание сложных фильтров с несколькими условиями и операторами

WP_Query поддерживает сложные запросы с операторами AND и OR внутри meta_query. Например, можно вывести посты, где цена от 500 до 1500, и цвет — красный или синий:

$args = [
    'post_type' => 'product',
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'price',
            'value' => [500, 1500],
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC'
        ],
        [
            'relation' => 'OR',
            [
                'key' => 'color',
                'value' => 'red',
                'compare' => '='
            ],
            [
                'key' => 'color',
                'value' => 'blue',
                'compare' => '='
            ]
        ]
    ]
];
$query = new WP_Query($args);

Такие запросы позволяют создавать гибкие фильтры для пользователей.

Интеграция с AJAX для динамической фильтрации без перезагрузки страницы

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

Примерный план действий:

  1. Добавить JavaScript-код, который при изменении формы отправляет AJAX-запрос.
  2. Создать обработчик AJAX в functions.php, который формирует WP_Query с параметрами из запроса.
  3. Вернуть HTML с результатами и обновить блок с постами на странице.

Для упрощения AJAX-запросов можно использовать jQuery и стандартные WordPress AJAX хуки wp_ajax_ и wp_ajax_nopriv_.

Пример JS для отправки формы AJAX

jQuery(document).ready(function($){
    $('#filter-form').on('change', 'input, select', function(){
        var data = $('#filter-form').serialize();
        $.ajax({
            url: wphow_ajax_object.ajax_url,
            type: 'GET',
            data: data + '&action=wphow_filter_posts',
            success: function(response){
                $('#filter-results').html(response);
            }
        });
    });
});

Пример PHP-обработчика AJAX

add_action('wp_ajax_wphow_filter_posts', 'wphow_ajax_filter_posts');
add_action('wp_ajax_nopriv_wphow_filter_posts', 'wphow_ajax_filter_posts');

function wphow_ajax_filter_posts() {
    // Аналогично формируем meta_query из $_GET
    // ... код из предыдущего примера
    // Выводим результаты
    wphow_filter_posts_by_meta();
    wp_die();
}

Заключение

Фильтрация постов по мета-данным — мощный инструмент для кастомизации вывода контента на WordPress. С помощью meta_query WP_Query можно создавать как простые, так и сложные условия фильтрации. Добавление пользовательского интерфейса с формами и AJAX позволяет сделать сайт удобным и современным.

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

Используйте приведённые примеры кода как основу для своих проектов и адаптируйте под конкретные задачи.

×
Оптимизируй свой сайт!

Скидка -15% на премиум плагин Clearfy Pro

Купить плагин сейчас ⋙