Как использовать pre_get_posts для автоматизации выборки записей в WordPress

Диагностика проблемы: почему стандартный запрос WordPress не всегда подходит

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

Если вам нужно изменить логику выборки записей без создания отдельных WP_Query, то правильный способ — использовать фильтр pre_get_posts. Он позволяет модифицировать основной запрос WordPress до его выполнения.

Пошаговое решение: как изменить post_status через pre_get_posts

Шаг 1. Подключите хук в functions.php вашей темы или в плагине

add_action('pre_get_posts', 'custom_modify_main_query');
function custom_modify_main_query($query) {
    // Убедимся, что мы в главном запросе на фронтэнде
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    // Пример: показать также черновики на главной
    if (is_home()) {
        $query->set('post_status', array('publish', 'draft'));
    }
}

Шаг 2. Подберите условия для нужных страниц и типов записей

Вы можете проверять:

  • is_home() — главная страница блога
  • is_post_type_archive('product') — архив кастомного типа записи
  • is_category('news') — категория по имени или ID

Например, чтобы вывести на странице архива кастомного типа записи product только опубликованные и отложенные (future) товары:

add_action('pre_get_posts', 'modify_product_archive_query');
function modify_product_archive_query($query) {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    if ($query->is_post_type_archive('product')) {
        $query->set('post_status', array('publish', 'future'));
    }
}

Как проверить, что решение сработало

1. Откройте соответствующую страницу сайта. Например, главную или архив.

2. Если выводятся записи с нужным статусом (например, черновики или отложенные), значит фильтр работает.

3. Для более точной проверки можно временно включить отладку и вывести SQL-запрос:

add_action('pre_get_posts', function($query) {
    if (is_admin() || !$query->is_main_query()) return;
    if (is_home()) {
        $query->set('post_status', array('publish', 'draft'));
        add_action('shutdown', function() use ($query) {
            global $wpdb;
            error_log($query->request); // SQL-запрос в лог
        });
    }
});

Частые ошибки при использовании pre_get_posts для изменения post_status

  • Изменение в админке без проверки is_admin(): приводит к сбоям и неправильной работе интерфейса.
  • Не проверяется is_main_query(): влияет на все запросы, включая второстепенные и виджеты, что может вызвать неожиданные результаты.
  • Установка одного статуса как строки вместо массива: например, 'draft,publish' — это неправильный формат, нужен массив array('draft', 'publish').
  • Забывают задать условие, и фильтр применяет изменения на всех страницах: это может нарушить логику сайта.

Практические советы по безопасности и производительности

  • Всегда ограничивайте область действия фильтра проверками is_main_query() и !is_admin(), чтобы не влиять на административную часть.
  • Избегайте сложных и ресурсоёмких условий в pre_get_posts, чтобы не замедлять загрузку страниц.
  • Если нужно сложное кэширование, используйте Transients API для хранения результатов запросов с кастомным статусом.
  • Регулярно проверяйте, что новые статусы не нарушают логику плагинов SEO и кэширования.

Сравнение способов изменения выборки по post_status

МетодПлюсыМинусыКогда использовать
Изменение WP_Query напрямуюГибко, для кастомных запросовНе влияет на основной запросНовые запросы в шаблонах
Фильтр pre_get_postsИзменяет основной запрос, универсальноНужно аккуратно проверять условияИзменение вывода стандартных страниц
Плагины для управления статусамиПростота настройки без кодаМожет быть избыточно, конфликтыДля пользователей без навыков PHP
Как добавить автоматическое удаление старых записей через WP-Cron в WordPress
31.01.2026
Как запретить автозагрузку медиа-содержимого в WordPress для ускорения сайта
27.03.2026
Как добавить кастомный виджет в WordPress с поддержкой настроек и стилей
11.02.2026
Автоматический импорт постов из Яндекс.Дзен в WordPress
16.02.2026
Как сделать автоматическое удаление старых пользователей в WordPress
12.04.2026