В WordPress часто возникает необходимость изменить стандартные запросы на выборку записей, чтобы автоматически фильтровать контент по определённым критериям. Для этого существует мощный хук pre_get_posts, который позволяет модифицировать параметры запроса до его выполнения. В этой статье подробно разберём, как использовать фильтр pre_get_posts для автоматической фильтрации записей, рассмотрим несколько практических задач и примеры кода.
Что такое хук filter pre_get_posts и где он применяется
Хук pre_get_posts срабатывает перед выполнением WP_Query — основного класса WordPress для выборки записей из базы данных. С помощью этого хука можно изменить параметры запроса, такие как тип записей, таксономии, количество элементов на странице, порядок сортировки и многое другое.
Главное преимущество pre_get_posts — возможность централизованно управлять выборкой записей без необходимости создавать собственные SQL-запросы или дублировать код. Это особенно полезно для автоматизации фильтрации контента, например, скрытия определённых категорий в публичной части сайта или вывода только определённых типов записей в админке.
Однако важно учитывать, что pre_get_posts применяется ко всем запросам WP_Query, включая главную страницу, архивы, виджеты и даже админ-панель, поэтому нужно корректно прописывать условия, чтобы не повлиять на админку или ненужные части сайта.
Типовые задачи автоматической фильтрации через pre_get_posts
1. Исключение записей из определённой категории на главной странице
Допустим, вы хотите, чтобы на главной странице не показывались посты из категории с ID 10. Для этого можно изменить параметры основного запроса, добавив исключение категорий.
add_action('pre_get_posts', 'wpteam_exclude_category_from_home');
function wpteam_exclude_category_from_home($query) {
if (!is_admin() && $query->is_main_query() && $query->is_home()) {
$query->set('cat', '-10'); // минус перед ID означает исключение
}
}Этот код проверяет, что запрос не в админке, является основным и относится к главной странице, после чего задаёт параметр cat с отрицательным значением для исключения категории.
2. Фильтрация записей по пользовательскому метаполю
Если нужно выводить только записи, у которых в метаданных есть определённое значение, можно добавить мета-запрос:
add_action('pre_get_posts', 'wpteam_filter_posts_by_meta');
function wpteam_filter_posts_by_meta($query) {
if (!is_admin() && $query->is_main_query() && is_post_type_archive('post')) {
$meta_query = array(
array(
'key' => 'wpteam_featured',
'value' => 'yes',
'compare' => '='
)
);
$query->set('meta_query', $meta_query);
}
}Здесь мы фильтруем архив записей, выводя только те, у которых пользовательское поле wpteam_featured равно «yes».
3. Изменение количества записей в пагинации на странице архива
Иногда нужно задать уникальное число записей для конкретного архива, например, отображать по 20 элементов вместо стандартных 10:
add_action('pre_get_posts', 'wpteam_change_posts_per_page');
function wpteam_change_posts_per_page($query) {
if (!is_admin() && $query->is_main_query() && is_category('news')) {
$query->set('posts_per_page', 20);
}
}Этот код изменит количество постов в категории «news» на 20.
Особенности и рекомендации при работе с pre_get_posts
Работа с pre_get_posts требует аккуратности, чтобы не нарушить поведение других запросов. Вот несколько советов:
- Всегда проверяйте условия: используйте
is_main_query(),is_admin(), а также условные теги (is_home(),is_category(),is_post_type_archive()) чтобы точно определить, к какому запросу применяется фильтр. - Не меняйте параметры, если это не нужно: ненужные изменения могут привести к неожиданным результатам, например, в виджетах или на страницах поиска.
- Тестируйте на разных страницах: проверяйте, как изменится вывод на главной, архивах, страницах записи и в админке.
- Пишите уникальные имена функций: чтобы избежать конфликтов, добавляйте префиксы, связанные с доменом или проектом, например,
wpteam_.
Пример сложной фильтрации с несколькими условиями
Рассмотрим пример, где нужно вывести записи типа «post» из категории «Новости», исключая посты с мета-ключом wpteam_hidden равным «1», и при этом сортировать их по дате изменения:
add_action('pre_get_posts', 'wpteam_advanced_post_filter');
function wpteam_advanced_post_filter($query) {
if (!is_admin() && $query->is_main_query() && is_category('news')) {
$query->set('post_type', 'post');
$query->set('orderby', 'modified');
$query->set('order', 'DESC');
$meta_query = array(
array(
'key' => 'wpteam_hidden',
'value' => '1',
'compare' => '!='
)
);
$query->set('meta_query', $meta_query);
}
}Такой код исключит из категории «news» записи, отмеченные как скрытые, и выведет обновлённые записи первыми.
Использование плагинов для расширения возможностей фильтрации
Для тех, кто не хочет писать код, есть плагины, которые добавляют удобный интерфейс для управления фильтрами запросов:
- Query Monitor — инструмент для анализа и отладки запросов WP_Query.
- Clearfy Pro — плагин с множеством оптимизаций, включая гибкое управление запросами.
Использование таких плагинов поможет понять, как именно изменяются запросы на вашем сайте и выявить узкие места.
Заключение
Хук pre_get_posts — мощный инструмент для автоматической фильтрации записей в WordPress. С его помощью можно гибко изменять параметры запросов, исключать или добавлять записи, менять порядок вывода и количество элементов. Главное — правильно фильтровать запросы и тестировать изменения. Практические примеры из этой статьи помогут вам быстро внедрить нужную логику в код вашего сайта на базе WordPress.