Изучаем метаданные в WordPress: Часть 4. Получение записей и пользователей по метаданным

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

Используем WP_Query для выполнения запросов по значению мета-полей

Чтобы выполнить запросы по значению мета-полей, нам нужно использовать WP_Query и определить meta_query. Если, к примеру, у нас есть произвольный тип записей, который называется films, содержащий в себе произвольное поле с названием director, то мы можем создать запрос на получение всех фильмов, которые были сняты одним из трех режиссеров Star Wars.

Давайте взглянем на код, представленный ниже. Особое внимание обратите на meta_query:

$sw_args = array(
    'post_type' => 'films',
    'meta_query' => array(
        array(
            'key' => 'director',
            'value' => array( 'George Lucas', 'Richard Marquand', 'Irvin Kershner' ),
            'compare' => 'IN',
        )
    )
);
$query = new WP_Query( $sw_args );
if ( $the_query->have_posts() ) {
     echo '<h2>Films By Star Wards Directors</h2>';
     echo '<ul>';
        while ( $the_query->have_posts() ) {
            $the_query->the_post();
            echo '<li>' . get_the_title() . '</li>';
    }
        echo '</ul>';
}
/* Restore original Post Data */
wp_reset_postdata();

У нас есть массив с именами режиссеров, также состоящий из массивов. Сначала мы переходим к массиву для наших аргументов WP_Query. После нашего первого аргумента post_type мы открываем массив, содержащий наши meta_query аргументы. В нем мы задаем ключ, который мы будем искать – в нашем случае это director. Также мы задаем массив значений, которые мы будем искать в этом ключе (поле).

Самый последний аргумент отображает то, как именно мы будем сравнивать значения. В нашем случае мы воспользуемся сравнением IN, что позволит нам получить любые записи с этими значениями в поле director.

Другие виды сравнений

Как быть, если мы хотим получить фильмы, которые были сняты режиссерами Star Wars, но хотим исключить приквелы Star Wars? Мы можем просто добавить еще один массив аргументов к нашему meta_query, однако в этот раз для значений будет использоваться массив с названиями фильмов для ключа film_title, а в качестве сравнения мы зададим NOT LIKE, чтобы исключить все  записи с этими значениями в поле film_title.

$sw_args = array(
    'post_type' => 'films',
    'meta_query' => array(
        array(
            'key' => 'director',
            'value' => array( 'George Lucas', 'Richard Marquand', 'Irvin Kershner' ),
            'compare' => 'IN',
        ),
                array(
            'key' => 'film_title',
            'value' => 'Phantom Menace', 'Attack of the Clones', 'Revenge of the Sith' ),
            'compare' => 'NOT LIKE'
        ),
 
    )
);
$query = new WP_Query( $sw_args );

Теперь WordPress будет искать фильмы этих трех режиссеров с названиями, которые не являются заголовками ни одного из трех приквелов.

Вывод мета-полей в WP_Query

До сих пор я показывал вам, как использовать WP_Query для поиска записей, которые имеют определенное значение в произвольном поле. Давайте теперь рассмотрим, как выводить эти поля.

Отображение этих полей происходит примерно так же, как и раньше, за одним исключением – вместо использования get_the_ID(), чтобы задать ID для get_post_meta(), мы будем использовать контекст объекта. Таким образом, в нашем цикле, который вы можете видеть ниже, ID получается несколько иначе – через $query->post->ID.

$sw_args = array(
    'post_type' => 'films',
    'meta_query' => array(
        array(
            'key' => 'director',
            'value' => array( 'George Lucas', 'Richard Marquand', 'Irvin Kershner' ),
            'compare' => 'IN',
        ),
                array(
            'key' => 'film_title',
            'value' => 'Phantom Menace', 'Attack of the Clones', 'Revenge of the Sith' ),
            'compare' => 'NOT LIKE'
        ),
 
    )
);
$query = new WP_Query( $sw_args );
if ( $the_query->have_posts() ) {
     echo '<h2>Films By Star Wards Directors</h2>';
     echo '<ul>';
        while ( $the_query->have_posts() ) {
            $the_query->the_post();
            echo '<li><ul>';
            echo '<li>' . get_the_title() . '</li>';
            echo '<li>' . get_post_meta( $query->post->ID, 'director', true ). '</li>';
            echo '</ul></li>''
        }
        echo '</ul>';
}
/* Restore original Post Data */
wp_reset_postdata();

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

Как и в случае с WP_Query, чтобы найти записи с определенными значениями для различных полей, мы можем использовать эквивалент таблицы WP_Query для пользователей — WP_User_Query.

К примеру, если у нас есть поле с названием subscriber_level и мы хотим найти только тех пользователей, которые имеют уровень подписчиков как extra_special или super_special, то мы можем воспользоваться тем же способом, который мы применяли для поиска фильмов трех режиссеров Star Wars:

$args = array(
    'meta_query' => array(
        array(
            'key'     => 'subscriber_level',
            'value'   => array('extra_special', 'super_special' );
            'compare' => '='
        )
    )
 );
$user_query = new WP_User_Query( $args );
 
if ( ! empty( $user_query->results ) ) {
    echo '<h3>Extra and Super Special Users</h3>';
    echo '<ul>';
    foreach ( $user_query->results as $user ) {
        echo '<li>' . $user->display_name . '</li>';
    }
    echo '</ul>';
}

Как и в случае с WP_Query, мы можем объединяться разные виды сравнений, чтобы управлять тем, какие пользователи нам будут возвращены. В следующем примере мы объединим предыдущий запрос с запросом пользователей, чьи имена Luke, Han или Leia:

$args = array(
    'meta_query' => array(
        array(
            'key'     => 'subscriber_level',
            'value'   => array('extra_special', 'super_special' );
            'compare' => '='
        )
    ),
    'search'         => array( 'Luke', 'Han', 'Leia' ),
    'search_columns' => array( 'user_nicename', 'display_name' ),
 );
$user_query = new WP_User_Query( $args );
if ( ! empty( $user_query->results ) ) {
    echo '<h3>Extra and Super Special Users Named Luke, Han or Leia</h3>';
    echo '<ul>';
    foreach ( $user_query->results as $user ) {
        echo '<li>' . $user->display_name . '</li>';
    }
    echo '</ul>';
}

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

Источник: code.tutsplus.com

Блог про WordPress
Комментарии: 7
  1. artool

    Здравствуйте!
    Хочу создать страницы с популярными записями определённых тегов/рубрик, но столкнулся с проблемой, не могли бы вы подсказать как её решить?

    Суть проблемы:
    Если я буду использовать один из приведённых вами вариантов, мне придётся создавать отдельные шаблоны страниц с циклом для вывода популярных записей той или иной рубрики или тега.
    Это обусловлено ‘key’ => ‘director’,

    Можно ли ‘key’ передать из произвольного поля записи?
    Т.е. можно ли создать универсальный шаблон, в котором ‘key’ меняется на содержимое определённого произвольного поля?

    http://pastebin.com/8LA9D6XL

    1. Дмитрий (автор)

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

      Вот, как пример, статья в WordPress:

      http://codex.wordpress.org/Function_Reference/get_post_custom_keys

  2. artool

    Благодарю за ответ!
    Вы мне очень помогли.

  3. Денис

    Здравствуйте! Подскажите как правильно мне вывести, например нужно сделать вывод 10 записей с одинаковым произвольным полем в сайдбаре. Произвольные поля были сделаны с помощью плагина Custom Field Suite. Сайт на кулинарную тематику. Есть произвольное поле — КУХНЯ, вот хочу чтобы в сайдбаре был список рецептов с произвольным полем — кухня : русская (например).

  4. Дмитрий (автор)
  5. Mark

    Вы объявляете переменную $user_query
    $user_query = new WP_User_Query( $args );

    А потом обращаетесь к $the_query
    if ( $the_query->have_posts() )

    Это опечатка или так и должно быть?

    1. Дмитрий (автор)

      Возможно, что вы правы. Пока не могу точно сказать, нужно смотреть код, вспоминать, что да как.

Добавить комментарий

Получать новые комментарии по электронной почте.