Знакомство с WP_Query
WP_Query — это PHP класс, который позволяет получать посты из базы данных по самым разным критериям. Например, мы можем получить посты:
- за определенный промежуток времени;
- из указанной категории, метки;
- свежие посты, случайные посты, популярные посты;
- посты с указанными произвольными полями или набором таких полей.
WP_Query используется в WordPress для любых запросов связанные с постами. Например, во время генерации любой страницы WP - WP_Query запрос записывается в глобальную переменную $wp_query и кроме данных постов содержит также данные самого запроса - данные о текущей странице. Ни одна генерация базовой страницы WP не обходиться без использования WP_Query.
При построении стандартного цикла WordPress, данные берутся из глобальной переменной $wp_query и выводятся на экран через вспомогательные функции: the_permalink(), the_content().
Кроме списка постов в $wp_query хранится информация о текущем запросе. На основе этой информации WP определяет на какой странице мы сейчас находимся (пост, архив, метка и т.д.). Информация о текущем запросе актуальна только для глобального объекта $wp_query (для объектов в подзапросах эта информация не имеет смысла). Посмотреть что находится в глобально объекте можно так:
print_r( $GLOBALS['wp_query'] );
Часто мы получаем информацию не работая напрямую с этим классом и глобальными переменными - все это скрыто под капотом. А мы пользуемся набором готовых функций - это: условные теги, теги шаблона относящиеся к выводу данных внутри Цикла и другие функции. Почти все условные теги обращаются к этому классу.
Рассмотрим простой запрос:
$query = new WP_Query( [ 'category_name' => 'news' ] );
Так, WordPress сделает запрос в базу данных, чтобы получить записи из категории "news".
Теперь, переменная $query содержит в себе объект с результатами запроса. Обработаем результат с помощью специальных методов:
while ( $query->have_posts() ) { $query->the_post(); the_title(); // выведем заголовок поста } wp_reset_postdata(); // ВАЖНО вернуть global $post обратно
Если в цикле используется the_post(), то обязательно после цикла нужно вызвать функцию wp_reset_postdata().
have_posts() проверяет есть ли посты в цикле (в объекте $query). the_post() устанавливает global $post
- туда записывается следующий пост из цикла, а также устанавливает другие глобальные переменные - см. setup_postdata(). Все это дает возможность использовать в цикле привычные WP функции без передачи параметров: the_title(), the_content() и т.д.
Подробнее о том как это работает читайте в have_posts() и the_post().
Как не затрагивать global $post
Если нам не нужны стандартные функции, которые работают с global $post
, то можно использовать $query->next_post()
вместо $query->the_post()
. В этом случае глобальная переменная $post не затрагивается:
while ( $query->have_posts() ) { $my_post = $query->next_post(); $url = get_permalink( $my_post ); }
WP_Query через foreach
Если не передать никаких параметров, то запроса не произойдет и будет просто создан объект WP_Query.
Код цикла может выглядеть следующим образом (это тоже самое что get_posts(), только без предустановленных параметров):
// создаем экземпляр $my_posts = new WP_Query; // делаем запрос $myposts = $my_posts->query( [ 'post_type' => 'page' ] ); // обрабатываем результат foreach( $myposts as $pst ){ echo esc_html( $pst->post_title ); }
Для лучшего понимания и визуального восприятия работы функций запроса, изучите картинку:
—