Свои запросы: WP_Query
Основной цикл выводит то, что WordPress выбрал по адресу страницы. Но на главной нужны ещё три свежие книги, а под статьёй — похожие записи. Для таких выборок служит класс WP_Query.
Второй цикл
<?php
// front-page.php
$books = new WP_Query([
'post_type' => 'book',
'posts_per_page' => 3,
]);
if ($books->have_posts()) :
while ($books->have_posts()) :
$books->the_post();
?>
<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
<?php
endwhile;
wp_reset_postdata();
endif;Методы have_posts() и the_post() вызывают у объекта запроса. После цикла wp_reset_postdata() возвращает текущей записью ту, что была до него.
Частые параметры
| Параметр | Что задаёт |
|---|---|
post_type | Тип записей: post, page, свой тип |
posts_per_page | Сколько записей; -1 — все |
orderby, order | Сортировка: date, title, rand, meta_value_num; ASC или DESC |
category_name | Адрес рубрики |
s | Поисковая фраза |
post__in, post__not_in | Только эти идентификаторы или все, кроме них |
paged | Номер страницы |
author | Идентификатор автора |
Выборка по таксономии
$query = new WP_Query([
'post_type' => 'book',
'tax_query' => [
[
'taxonomy' => 'genre',
'field' => 'slug',
'terms' => ['fantasy', 'detective'],
],
],
]);Выборка по полю
$query = new WP_Query([
'post_type' => 'book',
'meta_key' => 'book_price',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => [
[
'key' => 'book_price',
'value' => 500,
'compare' => '<=',
'type' => 'NUMERIC',
],
],
]);Запрос вернёт книги не дороже 500, отсортированные по цене.
Похожие записи
<?php
// single.php
$related = new WP_Query([
'category__in' => wp_get_post_categories(get_the_ID()),
'post__not_in' => [get_the_ID()],
'posts_per_page' => 3,
]);Просто массив записей
Когда цикл не нужен, удобнее get_posts() — она возвращает массив объектов:
$latest = get_posts(['post_type' => 'book', 'numberposts' => 5]);
foreach ($latest as $book) {
echo esc_html($book->post_title);
}Изменение основного запроса
Чтобы изменить то, что выводит основной цикл, новый запрос не создают, а поправляют существующий — хуком pre_get_posts:
// functions.php
add_action('pre_get_posts', function (WP_Query $query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if ($query->is_post_type_archive('book')) {
$query->set('posts_per_page', 12);
$query->set('orderby', 'title');
$query->set('order', 'ASC');
}
});Постраничный вывод при этом работает правильно.
Частая ошибка
Без wp_reset_postdata() после своего цикла функции the_title() и get_the_ID() дальше по шаблону будут относиться к последней записи вашего запроса: под статьёй появятся чужие комментарии и чужой заголовок. И не используйте старую функцию query_posts(): она ломает постраничный вывод — для основного запроса есть pre_get_posts.