Использование pre_get_posts с WP_Query
Я читал отличный ответ Стивена Харриса на этот вопрос относительно использования WP_query()
, query_posts()
и pre_get_posts
.
Он пишет: "pre_get_posts — это фильтр для изменения любого запроса. Чаще всего он используется для изменения только 'главного запроса'".
Возможно ли использовать pre_get_posts
для фильтрации только конкретного вторичного запроса, созданного с помощью WP_Query
? Например:
$my_secondary_loop = new WP_Query(...);
if( $my_secondary_loop->have_posts() ):
while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post();
// Вторичный цикл вывода записей
endwhile;
endif;
wp_reset_postdata();
Буду благодарен за любую помощь.

Самый простой способ - добавить действие прямо перед запросом и удалить его сразу после.
add_action('pre_get_posts', 'some_function_in_functionsphp');
$my_secondary_loop = new WP_Query(...);
remove_action('pre_get_posts', 'some_function_in_functionsphp');
if( $my_secondary_loop->have_posts() ):
while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post();
//Вторичный цикл
endwhile;
endif;
wp_reset_postdata();
РЕДАКТИРОВАТЬ
Другой метод, который можно использовать - установить свою собственную переменную запроса и проверять её в хуке:
// сообщаем WordPress о нашей новой переменной запроса
function wpse52480_query_vars( $query_vars ){
$query_vars[] = 'my_special_query';
return $query_vars;
}
add_filter( 'query_vars', 'wpse52480_query_vars' );
// проверяем, установлена ли наша переменная запроса в любом запросе
function wpse52480_pre_get_posts( $query ){
if( isset( $query->query_vars['my_special_query'] ) )
// выполняем специальные действия
return $query;
}
add_action( 'pre_get_posts', 'wpse52480_pre_get_posts' );
и в шаблоне:
// устанавливаем переменную запроса (вместе с другими), чтобы активировать фильтр
$args = array(
'my_special_query' => true
);
$my_secondary_loop = new WP_Query( $args );

Большое спасибо, Мило. Это действительно очень полезно. Я всегда задавался вопросом, возможно ли установить собственную переменную запроса.

pre_get_posts
срабатывает для каждого запроса постов:
- get_posts()
- new WP_Query()
- Тот случайный виджет последних записей, который ваш клиент установил без вашего ведома.
- Все запросы
-- @nacin
Учитывая это, если вы не исключите свой фильтр с помощью условного оператора is_main_query()
, ваш фильтр будет срабатывать и на вашем новом WP_Query.
Если вы хотите нацелить только ваш конкретный новый WP_Query, то способа сделать это не существует.

Его техника сработает. Я сам не использовал ее для pre_get_posts, но применял для других фильтров типа posts_where
