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

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

Создание собственного типа записей «Заказы» и добавление мета-полей

Первым шагом создадим кастомный тип записей для заказов, например, wporders_order. Это позволит хранить заказы как отдельные записи с нужными мета-данными.

function wporders_register_order_post_type() {
    $labels = array(
        'name' => 'Заказы',
        'singular_name' => 'Заказ',
        'menu_name' => 'Заказы',
        'add_new' => 'Добавить заказ',
        'add_new_item' => 'Добавить новый заказ',
        'edit_item' => 'Редактировать заказ',
        'new_item' => 'Новый заказ',
        'view_item' => 'Просмотр заказа',
        'search_items' => 'Поиск заказов',
        'not_found' => 'Заказы не найдены',
        'not_found_in_trash' => 'Заказы не найдены в корзине',
    );
    $args = array(
        'labels' => $labels,
        'public' => false,
        'show_ui' => true,
        'show_in_menu' => true,
        'capability_type' => 'post',
        'supports' => array('title','editor'),
        'has_archive' => false,
    );
    register_post_type('wporders_order', $args);
}
add_action('init', 'wporders_register_order_post_type');

Для хранения информации о статусе заказа, дате оформления и клиенте добавим произвольные поля (мета-поля). Например:

  • order_status — статус заказа (в обработке, выполнен, отменён и т.д.)
  • order_date — дата заказа
  • order_customer — ID или имя клиента

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

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

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

Шорткод для вывода фильтрованного списка заказов

function wporders_shortcode_order_list($atts) {
    // Получаем параметры фильтра из GET-запроса
    $status = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : '';
    $customer = isset($_GET['customer']) ? sanitize_text_field($_GET['customer']) : '';
    $date_from = isset($_GET['date_from']) ? sanitize_text_field($_GET['date_from']) : '';
    $date_to = isset($_GET['date_to']) ? sanitize_text_field($_GET['date_to']) : '';

    // Формируем аргументы WP_Query
    $meta_query = array('relation' => 'AND');

    if ($status) {
        $meta_query[] = array(
            'key' => 'order_status',
            'value' => $status,
        );
    }
    if ($customer) {
        $meta_query[] = array(
            'key' => 'order_customer',
            'value' => $customer,
            'compare' => 'LIKE'
        );
    }
    if ($date_from || $date_to) {
        $date_query = array('key' => 'order_date');
        if ($date_from) {
            $date_query['value'][] = $date_from;
            $date_query['compare'][] = '>=';
        }
        if ($date_to) {
            $date_query['value'][] = $date_to;
            $date_query['compare'][] = '<=';
        }
        $meta_query[] = $date_query;
    }

    $args = array(
        'post_type' => 'wporders_order',
        'posts_per_page' => 20,
        'meta_query' => $meta_query,
        'orderby' => 'meta_value',
        'meta_key' => 'order_date',
        'order' => 'DESC',
    );

    $query = new WP_Query($args);

    ob_start();
    ?>
    <form method="get" class="wporders-filter-form">
        <label>Статус:
            <select name="status">
                <option value="">Все</option>
                <option value="processing" <?php selected($status, 'processing'); ?>>В обработке</option>
                <option value="completed" <?php selected($status, 'completed'); ?>>Выполнен</option>
                <option value="cancelled" <?php selected($status, 'cancelled'); ?>>Отменён</option>
            </select>
        </label>
        <label>Клиент:
            <input type="text" name="customer" value="<?php echo esc_attr($customer); ?>" placeholder="Имя или ID клиента">
        </label>
        <label>Дата с:
            <input type="date" name="date_from" value="<?php echo esc_attr($date_from); ?>">
        </label>
        <label>Дата по:
            <input type="date" name="date_to" value="<?php echo esc_attr($date_to); ?>">
        </label>
        <button type="submit">Фильтровать</button>
    </form>

    <table class="wporders-table" border="1" cellpadding="5" cellspacing="0" style="width:100%; margin-top:15px;">
        <thead>
            <tr>
                <th>ID</th>
                <th>Название</th>
                <th>Статус</th>
                <th>Клиент</th>
                <th>Дата</th>
            </tr>
        </thead>
        <tbody>
    <?php
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            $status_val = get_post_meta(get_the_ID(), 'order_status', true);
            $customer_val = get_post_meta(get_the_ID(), 'order_customer', true);
            $date_val = get_post_meta(get_the_ID(), 'order_date', true);
            echo '<tr>';
            echo '<td>' . get_the_ID() . '</td>';
            echo '<td><a href="' . get_edit_post_link() . '">' . get_the_title() . '</a></td>';
            echo '<td>' . esc_html($status_val) . '</td>';
            echo '<td>' . esc_html($customer_val) . '</td>';
            echo '<td>' . esc_html($date_val) . '</td>';
            echo '</tr>';
        }
    } else {
        echo '<tr><td colspan="5">Заказы не найдены</td></tr>';
    }
    wp_reset_postdata();
    ?></tbody>
    </table>
    <?php
    return ob_get_clean();
}
add_shortcode('wporders_order_list', 'wporders_shortcode_order_list');

Этот шорткод можно вставить в любую страницу или запись для отображения заказов с фильтрами.

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

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

Пример обработчика AJAX для фильтрации заказов

add_action('wp_ajax_wporders_filter_orders', 'wporders_ajax_filter_orders');
add_action('wp_ajax_nopriv_wporders_filter_orders', 'wporders_ajax_filter_orders');

function wporders_ajax_filter_orders() {
    $status = isset($_POST['status']) ? sanitize_text_field($_POST['status']) : '';
    $customer = isset($_POST['customer']) ? sanitize_text_field($_POST['customer']) : '';
    $date_from = isset($_POST['date_from']) ? sanitize_text_field($_POST['date_from']) : '';
    $date_to = isset($_POST['date_to']) ? sanitize_text_field($_POST['date_to']) : '';

    // Аналогично формируем WP_Query с фильтрами, как в шорткоде
    $meta_query = array('relation' => 'AND');

    if ($status) {
        $meta_query[] = array('key' => 'order_status', 'value' => $status);
    }
    if ($customer) {
        $meta_query[] = array('key' => 'order_customer', 'value' => $customer, 'compare' => 'LIKE');
    }
    if ($date_from || $date_to) {
        $date_query = array('key' => 'order_date');
        if ($date_from) $date_query['value'][] = $date_from;
        if ($date_to) $date_query['value'][] = $date_to;
        if ($date_from && $date_to) $date_query['compare'] = 'BETWEEN';
        elseif ($date_from) $date_query['compare'] = '>=';
        elseif ($date_to) $date_query['compare'] = '<=';
        $meta_query[] = $date_query;
    }

    $args = array(
        'post_type' => 'wporders_order',
        'posts_per_page' => 20,
        'meta_query' => $meta_query,
        'orderby' => 'meta_value',
        'meta_key' => 'order_date',
        'order' => 'DESC',
    );

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            $status_val = get_post_meta(get_the_ID(), 'order_status', true);
            $customer_val = get_post_meta(get_the_ID(), 'order_customer', true);
            $date_val = get_post_meta(get_the_ID(), 'order_date', true);
            echo '<tr>';
            echo '<td>' . get_the_ID() . '</td>';
            echo '<td>' . get_the_title() . '</td>';
            echo '<td>' . esc_html($status_val) . '</td>';
            echo '<td>' . esc_html($customer_val) . '</td>';
            echo '<td>' . esc_html($date_val) . '</td>';
            echo '</tr>';
        }
    } else {
        echo '<tr><td colspan="5">Заказы не найдены</td></tr>';
    }
    wp_reset_postdata();
    wp_die();
}

В JS необходимо отправлять AJAX-запрос на admin-ajax.php с действием wporders_filter_orders и параметрами фильтра. При успешном ответе заменять содержимое таблицы.

Советы по расширению функционала

Можно добавить:

  • Пагинацию с AJAX для загрузки следующей страницы заказов
  • Экспорт отфильтрованных заказов в CSV
  • Добавление кнопок для быстрого изменения статуса заказа в списке
  • Использование плагина WPRemark для управления комментариями и заметками по заказам

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

Как добавить автоматическое возврашение денег в WooCommerce
27.01.2026
Автоматизация создания заказов в WordPress без WooCommerce
16.12.2025
Как создать настройки плагина в WordPress: подробное руководство
30.11.2025
Создание автоматических уведомлений о статусах заказов WooCommerce
24.12.2025
Создание и использование shortcode в WordPress: подробное руководство с примерами кода
11.11.2025