Использование pre_get_posts с WP_Query

17 мая 2012 г., 22:59:49
Просмотры: 16.5K
Голосов: 26

Я читал отличный ответ Стивена Харриса на этот вопрос относительно использования 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();

Буду благодарен за любую помощь.

0
Все ответы на вопрос 2
2
28

Самый простой способ - добавить действие прямо перед запросом и удалить его сразу после.

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 );
17 мая 2012 г. 23:10:19
Комментарии

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

Ben Pearson Ben Pearson
18 мая 2012 г. 08:52:22

Как я могу использовать этот трюк для страницы архива? Я не хочу переписывать весь запрос заново для страницы архива, но хочу применить эту технику.

Rohit Pande Rohit Pande
2 июл. 2013 г. 12:17:06
3

pre_get_posts срабатывает для каждого запроса постов:

  • get_posts()
  • new WP_Query()
  • Тот случайный виджет последних записей, который ваш клиент установил без вашего ведома.
  • Все запросы

-- @nacin

Учитывая это, если вы не исключите свой фильтр с помощью условного оператора is_main_query(), ваш фильтр будет срабатывать и на вашем новом WP_Query.

Если вы хотите нацелить только ваш конкретный новый WP_Query, то способа сделать это не существует.

17 мая 2012 г. 23:11:34
Комментарии

Как насчет техники Мило? Я раньше такого не видел...

brasofilo brasofilo
18 мая 2012 г. 00:56:29

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

Chris_O Chris_O
18 мая 2012 г. 01:02:57

Круто, сегодня узнал что-то новое!

brasofilo brasofilo
18 мая 2012 г. 01:05:00