Изучаем WP_Query: 10 полезных примеров

В этой статье я хочу познакомить вас с 10 разными сценариями применения класса WP_Query и связанных с ним функций.

Вспоминаем, как при помощи WP_Query создаются циклы

Чтобы выделить эту статью среди других частей серии «Изучаем WP_Query», позвольте представить вам маленькое руководство, посвященное созданию циклов в WordPress при помощи класса WP_Query.

Этот процесс никак не отличается от создания обычного цикла. Типичный цикл в WordPress выглядит следующим образом:

<?php

if ( have_posts() ) {

    while ( have_posts() ) {

        the_post();

        // Здесь идут данные записи.

    }

}

?>

А в случае создания цикла при помощи класса WP_Query будет лишь пара отличий:

<?php

$args = array(
    'category_name' => 'news',
    'posts_per_page' => 3
);

$my_query = new WP_Query( $args );

if ( $my_query->have_posts() ) {

    while ( $my_query->have_posts() ) {

        $my_query->the_post();

        // Здесь идут данные записи.

    }

}

// Сбрасываем данные `$post` до текущей записи из основного запроса. 
wp_reset_postdata();

?>

Давайте обсудим различия этих двух вариантов реализации:

  • Мы выставляем некоторые аргументы для нашего WP_Query;
  • Мы запускаем класс WP_Query;
  • В самое начало функций have_posts() и the_post() добавляем $my_query->. Так они становятся методами класса WP_Query;
  • Затем мы сбрасываем данные $post, чтобы получить данные при помощи основного запроса.

Теперь мы знаем, как создавать циклы при помощи WP_Query. Давайте не будем включать запуск циклов в каждый пример. Но если у вас возникнут проблемы с созданием цикла, то вы всегда можете вернуться к началу статьи.

Пример 1: все записи автора за текущий год

Предположим, что вам необходимо вывести список записей определенного автора, опубликованных в текущем году. Для этого будет достаточно комбинации из двух параметров WP_Query:

<?php

// Определяем текущий год.
$current_year = date( 'Y' );

// Устанавливаем аргументы.
$args = array(
    // Ищем автора "john".
    'author' => 'john',
    // Получаем все его записи за текущий год.
    'year'   => $current_year
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

Внесите этот запрос в цикл, и все заработает.

Пример 2: получаем свежие записи из категории (за исключением текущей записи)

Вам нужно создать цикл под каждой отдельной записью, и вывести туда список свежих записей из той же категории, но при этом исключить из списка просматриваемую на данный момент запись. Это можно реализовать при помощи параметров 'cat' и 'post__not_in':

<?php

// Получаем ID записи.
$current_post_id = get_the_ID();

// Получаем сведения о рубрике текущей записи (первую в том случае, если указано несколько категорий).
$current_post_cats = get_the_category();
$current_post_first_cat_id = $current_post_cats[ 0 ]->term_id;

// Устанавливаем аргументы.
$args = array(
    // Получаем записи из категории.
    'cat' => $current_post_first_cat_id,
    // Исключаем текущую запись.
    'post__not_in' => array( $current_post_id )
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

Что касается самого цикла, то я бы рекомендовал вам сделать три или четыре колонки с миниатюрами записей выше заголовков. Такой блок рекомендаций отлично смотрится под записями.

Пример 3: выводим “самые популярные записи”, отсортированные по количеству комментариев

В WordPress отсутствует встроенная функция подсчета просмотров записи, а специализированные плагины серьезно замедляют работу сайтов. Но есть и другой способ определить самые популярные записи: подсчитать комментарии. И в отличие от количества просмотров все данные о комментариях уже есть в базе данных.

WP_Query позволяет без труда отсортировать записи по количеству комментариев:

<?php

// Устанавливаем аргументы.
$args = array(
    // Сортируем по количеству комментариев.
    'orderby' => 'comment_count'
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

Теперь вы можете без труда создать собственный шаблон страницы с циклом, который выдает список популярных записей, основываясь на количестве комментариев.

Пример 4: настройка простого слайдера

Я не особый любитель слайдеров, но людям они нравятся, и поэтому я не могу отказывать своим клиентам в этой прихоти. Если им нужен слайдер, я делаю простой запрос при помощи класса WP_Query:

<?php

// Устанавливаем аргументы.
$args = array(
    // Получаем тип записи "slider".
    'post_type' => 'slider',
    // Получаем определенную категорию слайдера.
    'category_name' => 'home-slides',
    // Выводим все слайды и не используем пагинацию.
    'nopaging' => true
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

Аргумент 'cat' можно использовать для получения слайдов из различных категорий, и это дает возможность использовать сразу несколько слайдеров на странице. Если вы планируете использовать только один слайдер, то можно удалить эту строку кода.

Пример 5: выводим случайную цитату в боковой панели

Если вам нужно выводить случайную цитату в боковой панели при каждом просмотре страницы, то можно воспользоваться следующим кодом для создания типа записи, а также использовать следующий запрос для создания цикла в сайдбаре:

<?php

/* 
 * создаем новый тип записи "Quotes"
 * (ищите информацию о функции
 * `register_post_type` чтобы узнать больше
 * о создании произвольных типов записей).
 */
function quote_post_type() {

    $args = array(
        'label' => 'Quotes',
        'public' => true
    );

    register_post_type( 'quotes', $args );
}

add_action( 'init', 'quote_post_type' );

// Устанавливаем аргументы.
$args = array(
    // Получаем тип записи "quotes".
    'post_type' => 'quotes',
    // Сортируем в случайном порядке.
    'orderby' => 'rand',
    // Выводим один элемент.
    'posts_per_page' => 1,
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

Пример 6: выводим перечень продуктов из определенной ценовой категории

Ниже привожу фрагмент кода, который нужно использовать, если вам нужно вывести элементы пользовательского типа записи "Product", и отфильтровать результаты по значению пользовательского поля "price":

<?php

// Source: http://scribu.net/wordpress/advanced-metadata-queries.html

// Устанавливаем аргументы.
$args = array(
    // Получаем тип записи "product".
    'post_type' => 'product',
    // Устанавливаем "meta query".
    'meta_query' => array(
        array(
            // Получаем произвольное поле "price".
            'key' => 'price',
            // Устанавливаем ценовой диапазон.
            'value' => array(100, 200),
            // Устанавливаем оператор сравнения.
            'compare' => 'BETWEEN',
            // Учитываем только цифровые поля.
            'type' => 'numeric',
        )
    )
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

Пример 7: шорткод для встраивания записей внутри записей

В этом примере я хочу создать шорткод, который позволит встраивать запись в другую запись. В приведенном ниже коде мы создаем функцию shortcode, которая позволяет вставлять записи (или любой произвольный тип записи), а также указать формат отображения: полная версия записи или фрагмент записи:

<?php

/*
 * Применение:
 *
 * [embed_post slug="my-post"]
 * [embed_post slug="my-post" full="false"]
 * [embed_post type="movie" slug="inception"]
 */

function tutsplus_embedded_post_shortcode( $attributes ) {

    // Извлекаем атрибуты шорткода.
    extract(
        shortcode_atts(
            array(
                'type' => 'post',
                'slug' => '',
                'full' => true
            ),
            $attributes
        )
    );

    // Устанавливаем аргументы.
    $args = array(
        // Получаем тип записи ("post" по умолчанию).
        'post_type' => $type,
        // Получаем запись по slug.
        'name' => $slug
    );

    // Запускаем новый запрос.
    $my_query = new WP_Query( $args );

    // Проверка наличия результатов запроса.
    if ( $my_query->have_posts() ) {

        // Начало разметки.
        $output = '<section class="embedded-post">';

        // начало цикла обработки данных из результатов запроса.
        while ( $my_query->have_posts() ) {

            $my_query->the_post();

            // Добавляем заголовок в вывод.
            $output .= '<h2 class="embedded-post-title">';
                $output .= get_the_title();
            $output .= '</h2>';

            // Выводим полную версию, если параметр `$full` выставлен на true. Если нет, то выводим фрагмент записи.

            if ( 'true' === $full ) {

                // Добавляем полную версию записи в вывод.
                $output .= '<div class="embedded-post-content">';
                    $output .= get_the_content();
                $output .= '</div>';

            } else {

                // Добавляем фрагмент записи в вывод.
                $output .= '<div class="embedded-post-excerpt">';
                    $output .= get_the_excerpt();
                    $output .= '&hellip; <a href="' . get_permalink() . '">' . __( 'Посмотреть полную версию', 'tutsplus' ) . ' &raquo;</a>';
                $output .= '</div>';

            }

        }

        // Завершение разметки.
        $output .= '</section>';

    } else {

        // Сообщаем пользователю о том, что запрашиваемые записи не найдены.
        $output = '<section class="embedded-post-error">';
            $output .= '<p>' . __( 'Ничего не найдено.', 'tutsplus' ) . '</p>';
        $output .= '</section>';

    }

    wp_reset_postdata();

    return $output;

}

add_shortcode( 'embed_post', 'tutsplus_embedded_post_shortcode' );

?>

Пример 8: выводим список запланированных записей (с возможностью показа фрагментов записей)

Почему бы не подогреть интерес посетителей с помощью анонса публикаций на ближайшее время? Вы можете использовать следующую функцию для вывода списка запланированных к публикации записей, а также по желанию отобразить фрагменты записей после заголовков:

<?php

/*
 * Применение с фрагментами записей:
 *
 * <?php echo tutsplus_show_drafts(); ?>
 *
 * Применение без текста записей:
 *
 * <?php echo tutsplus_show_drafts( false ); ?>
 */

function tutsplus_show_drafts( $show_excerpts = true ) {

    // Устанавливаем аргументы.
    $args = array(
        'post_status' => 'future',
        'nopaging' => true
    );

    // Запускаем новый запрос.
    $my_query = new WP_Query( $args );

    // Проверка наличия результатов запроса.
    if ( $my_query->have_posts() ) {

        // Начало разметки.
        $output = '<section class="pending-posts">';

        // начало цикла обработки данных из результатов запроса.
        while ( $my_query->have_posts() ) {

            $my_query->the_post();

            // Выводим заголовки запланированных записей с фрагментом содержимого (если функция включена).
            $output .= '<div class="pending">';
                $output .= '<h3 class="pending-title">' . get_the_title() . '</h3>';
                    $output .= get_the_title();
                $output .= '</h3>';

                if ( $show_excerpts ) {

                    $output .= '<div class="pending-excerpt">';
                        $output .= get_the_excerpt();
                    $output .= '</div>';

                }

            $output .= '</div>';

        }

        // Конец разметки.
        $output .= '</section>';

    } else {

        // Сообщаем пользователю, что ничего не найдено.
        $output = '<section class="drafts-error">';
            $output .= '<p>' . __( 'Ничего не найдено', 'tutsplus' ) . '</p>';
        $output .= '</section>';

    }

    wp_reset_postdata();

    return $output;

}

?>

Пример 9: запись, опубликованная в этот день в прошлом году

Можно создать специальную функцию, которая бы выводила запись с сегодняшней датой, но только опубликованную ровно год назад:

<?php

// Устанавливаем аргументы.
$args = array(
    // День (1 - 31).
    'day' => date( 'j' ),
    // Месяц (1 - 12).
    'monthnum' => date( 'n' ),
    // Год (minus 1).
    'year' => date( 'Y' ) - 1,
    // Показываем только одну запись.
    'posts_per_page' => 1
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

Пример 10: показываем дочерние страницы текущего поста

Не можете предложить ничего другого, кроме заголовков других страниц в разделах «О нас», «Услуги» или «Портфолио»? Но лучше разместить в них ссылки на дочерние страницы. Можно реализовать это в виде таблицы, состоящей из небольших миниатюр и заголовков под ними.

Давайте посмотрим, какой запрос нужно использовать, чтобы получить необходимый шаблон страницы:

<?php

$current_page_id = get_the_ID();

// Устанавливаем аргумент.
$args = array(
    // Получаем дочерние страницы для текущей страницы.
    'parent' => $current_page_id,
    // Отключаем пагинацию.
    'nopaging' => true
);

// Запускаем новый запрос.
$my_query = new WP_Query( $args );

?>

В завершение

Надеюсь, вам понравились сегодняшние примеры. Я специально старался отобрать разные, чтобы показать, насколько широки возможности класса WP_Query!

Если у вас есть другие интересные идеи, то обязательно напишите о них в комментариях! И если вам понравилась сегодняшняя статья, обязательно расскажите о ней своим друзьям!

Перевод статьи “Mastering WP_Query: 10 Useful Examples” был подготовлен дружной командой проекта Сайтостроение от А до Я.

12 декабря 2015 в 11:38
Материалы по теме
{"url":"http://www.fastvps.ru/", "src":"/images/advbanners/fastvps.png", "alt":"Хостинг Fastvps.ru. Наш выбор!"}
Заработок