Перейти к содержимому

WP_Query: рецепты запросов

WP_Query — основной класс для выборки записей в WordPress. Всегда сбрасывайте запрос через wp_reset_postdata() после кастомного цикла.

$query = new WP_Query( [ /* аргументы */ ] );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
// the_title(), the_content(), get_the_ID() ...
}
wp_reset_postdata();
}
$paged = get_query_var( 'paged' ) ?: 1;
$query = new WP_Query( [
'cat' => 5, // ID категории
'posts_per_page' => 10,
'paged' => $paged,
'orderby' => 'date',
'order' => 'DESC',
] );

Вывод пагинации:

echo paginate_links( [
'total' => $query->max_num_pages,
'current' => $paged,
] );
$query = new WP_Query( [
'tag' => 'wordpress',
'posts_per_page' => 6,
] );
$query = new WP_Query( [
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1, // все записи
'orderby' => 'title',
'order' => 'ASC',
] );
$query = new WP_Query( [
'post_type' => 'post',
'meta_query' => [
[
'key' => 'featured',
'value' => '1',
'compare' => '=',
],
],
] );
$query = new WP_Query( [
'post_type' => 'product',
'meta_query' => [
[
'key' => 'price',
'value' => [ 100, 500 ],
'compare' => 'BETWEEN',
'type' => 'NUMERIC',
],
],
] );
// Записи из категории 3 ИЛИ 7
$query = new WP_Query( [
'category__in' => [ 3, 7 ],
'posts_per_page' => 10,
] );
// Записи, которые принадлежат категориям 3 И 7 одновременно
$query = new WP_Query( [
'category__and' => [ 3, 7 ],
'posts_per_page' => 10,
] );
$query = new WP_Query( [
'date_query' => [
[
'after' => '30 days ago',
'inclusive' => true,
],
],
'posts_per_page' => 10,
] );

7. Исключить текущую запись (например, в блоке «Похожие»)

Заголовок раздела «7. Исключить текущую запись (например, в блоке «Похожие»)»
$query = new WP_Query( [
'post_type' => get_post_type(),
'posts_per_page' => 4,
'post__not_in' => [ get_the_ID() ],
'orderby' => 'rand',
] );
$query = new WP_Query( [
'post_type' => 'post',
'title_filter'=> 'WordPress', // Не нативный параметр — нужен фильтр ниже
] );
// Фильтр для поддержки title_filter
add_filter( 'posts_where', function ( string $where, WP_Query $q ): string {
$title = $q->get( 'title_filter' );
if ( $title ) {
global $wpdb;
$where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( $wpdb->esc_like( $title ) ) . '%\'';
}
return $where;
}, 10, 2 );
$query = new WP_Query( [
'post_type' => 'product',
'meta_key' => 'price',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => [
[
'key' => 'price',
'type' => 'NUMERIC',
],
],
] );

10. get_posts() — быстрая альтернатива для простых выборок

Заголовок раздела «10. get_posts() — быстрая альтернатива для простых выборок»
$posts = get_posts( [
'numberposts' => 5,
'category' => 3,
'orderby' => 'date',
'order' => 'DESC',
] );
foreach ( $posts as $post ) {
setup_postdata( $post );
the_title();
}
wp_reset_postdata();

get_posts() не запускает основной цикл и не поддерживает пагинацию. Подходит для виджетов и шорткодов.