Получение метаданных записи в том же запросе, что и основной цикл

28 авг. 2014 г., 16:59:22
Просмотры: 129
Голосов: 0

У меня есть пользовательский тип записи "staff" (сотрудники), и у каждой записи есть пользовательское поле "_staff_purpose" (описывающее их функцию).

Я хочу, чтобы шаблон archive-staff.php отображал всех сотрудников, отсортированных по их _staff_purpose, чтобы я мог затем пройтись по результатам, используя _staff_purpose в качестве заголовка. Желаемый результат должен выглядеть так:

ID  |   post_title    |  _staff_purpose
-----------------------------------------
1   |   Трейси Чеп.   |  администратор
-----------------------------------------
2   |   Джон Доу      |  учитель
-----------------------------------------
3   |   Роберт Смит   |  учитель
-----------------------------------------

Сырой SQL-запрос должен быть таким:

SELECT * FROM `bj_posts` p

LEFT JOIN (
    SELECT post_id, meta_value as purpose
    FROM `bj_postmeta` pm 
    WHERE  `meta_key`='purpose'
    ) pm ON p.ID=pm.post_id
WHERE p.`post_type`='staff' AND p.`post_status`='publish'
ORDER BY purpose ASC, post_title ASC

Я пробовал это:

add_action( 'pre_get_posts', 'fetch_staff_people' );

function fetch_staff_people( $query )
{
    // Проверяем, что это главный запрос для шаблона archive-staff.php
    if ( is_page_template('archive-staff.php') && $query->is_main_query() )
    {
        $query->set( 'post_per_page', '-1' ); // Получаем все записи
        $query->set( 'meta_key', '_staff_purpose' ); // Устанавливаем ключ метаполя
        $query->set('orderby', 'meta_value title'); // Сортируем по назначению, затем по имени
        $query->set( 'order', 'ASC ASC' );

    } else { 
        return;
    }

    return $query;
}

Запрос вроде работает, но значение пользовательского поля не появляется в цикле.

6
Комментарии

Вам нужно показать нам ваш код цикла.

Wyck Wyck
28 авг. 2014 г. 17:19:30

Я не уверен, что правильно понял ваш вопрос. Вы хотите получить метаданные записи в основном запросе, чтобы их значение хранилось в объекте $post, используемом в цикле? Думаю, это невозможно с помощью WP Query, поэтому вы не можете сделать это через хук preg_get_posts.

cybmeta cybmeta
28 авг. 2014 г. 19:36:52

Да, именно это я и хочу сделать.

pixeline pixeline
28 авг. 2014 г. 19:48:43

Для доступа к метаданным используйте get_post_meta( get_the_ID(), '_staff_purpose', true ); в вашем цикле. Также обратите внимание, что двойная сортировка будет работать в данном случае, так как вы сортируете по возрастанию.

bonger bonger
28 авг. 2014 г. 23:21:36

@bonger это вызвало бы SQL-запрос для каждой записи в цикле. Именно этого я хотел избежать. В итоге я использовал прямой SQL-запрос с get_results().

pixeline pixeline
29 авг. 2014 г. 00:02:08

Нет, как это ни парадоксально, это не так, поскольку WordPress кэширует все метаданные за кулисами при выполнении запроса, поэтому использование get_post_meta является общепринятым способом работы в WP.

bonger bonger
29 авг. 2014 г. 00:10:10
Показать остальные 1 комментариев
Все ответы на вопрос 1
1

Вы не можете использовать двойную сортировку. Попробуйте этот код:

add_action( 'pre_get_posts', 'fetch_staff_people' );
function fetch_staff_people( $query )
{
  if ( is_post_type_archive('staff') && $query->is_main_query() )
  {
    $query->set( 'post_per_page', '-1' );
    $query->set( 'meta_key', '_staff_purpose' );
    $query->set('orderby', 'meta_value_num'); // сортировка по назначению, затем по имени сотрудника.
    $query->set( 'order', 'ASC' );
  }
}

Примечание: Я использовал функцию is_post_type_archive() в условном теге. Она проверяет архивную страницу. Смотрите Кодекс

28 авг. 2014 г. 18:18:40
Комментарии

Я могу обойтись без двойной сортировки. Мне важно понять, как включить meta_key в результаты SQL-запроса. Я добавил исходный SQL-код, который хотел бы выразить с помощью логики запросов WordPress.

pixeline pixeline
28 авг. 2014 г. 19:26:25