Сортировка записей по пользовательскому полю
Я пытаюсь отсортировать свои записи по пользовательскому полю artwork_title
. Когда я использую следующий код, я получаю только одну определенную категорию записей, независимо от того, в каком архиве категории я нахожусь.
Также пагинация показывает правильное количество страниц, но переход на следующую страницу всегда отображает тот же набор записей. Кто-нибудь видит, что я делаю не так?
<?php $query = new WP_Query(
array(
'posts_per_page' => 20,
'orderby' => 'meta_value',
'meta_key' => 'artwork_title',
'order' => 'ASC'
) ); ?>
<?php while ( $query->have_posts() ) : $query->the_post(); ?>
<?php get_template_part( 'content', get_post_format() );
?>
<?php endwhile; ?>
@PieterGoosen предложил использовать pre_get_posts
. У меня нет опыта работы с этим, но я попробовал следующий код, однако не получаю никаких результатов. Наверное, я допустил глупую ошибку.
<?php add_action( 'pre_get_posts', 'sort_artwork_title' );?>
function sort_artwork_title( $query )
{
if (is_admin()){
return;
}
if( $query->is_main_query() && is_post_type_archive() ) {
$query->set('orderby', 'artwork_title');
$query->set('posts_per_page', '20');
$query->set('order', 'ASC' );
}
return $query;
}

Развивая комментарий @pieter-goosen, вам действительно стоит использовать pre_get_posts
. В вашем примере, используя WP_Query
, вы полностью перезаписываете запрос и сбрасываете большинство параметров к значениям по умолчанию. Фактически, вы, вероятно, вообще не видите записи из определённой категории. Вместо этого вы видите все записи, поскольку это поведение по умолчанию класса WP_Query
.
Вместо этого используйте pre_get_posts
, который модифицирует существующий запрос, а не создаёт совершенно новый. Вот [непроверенный] фрагмент кода, который должен работать в вашем файле functions.php
:
add_action( 'pre_get_posts', 'wpse183601_filter_category_query' );
function wpse183601_filter_category_query( $query ) {
// изменяем только архивные страницы категорий на фронтенде
if( is_category() && !is_admin() && $query->is_main_query() ) {
$query->set( 'posts_per_page','20' );
$query->set( 'orderby','meta_value' );
$query->set( 'meta_key','artwork_title' );
$query->set( 'order','ASC' );
}
}

Вы ответили, пока я редактировал свой пост, чтобы спросить о pre_get_posts. Огромное спасибо. Похоже, всё работает. Вопрос: откуда взялось это название функции? Есть ли причина, по которой оно не могло быть просто artwork_title_filter_category_query или что-то в этом роде?

@ThomasMartin вы можете назвать свою функцию как угодно. Многие из нас просто используют префикс wpse****
, чтобы иметь уникальное имя для функций. wpse
означает wordpress stackechange, а цифры — это номер поста :-). Просто заметка: не забудьте соответствующим образом переименовать имя функции обратного вызова

Нужно ли мне что-то добавлять в мои файлы archive.php, index.php или search.php? Вроде бы всё работает корректно на страницах архивов, но на главной странице список постов отображается в случайном порядке (или я не вижу сортировки).

Неважно. Я понял, что index, скорее всего, просто сортирует последние записи (они все были созданы одновременно, поэтому я не могу понять порядок). Ещё раз спасибо за помощь.

Условие if()
в сниппете определяет, к каким страницам (точнее, к каким запросам) применяется сортировка. Вы упомянули страницы категорий, поэтому я выбрал именно их. Вы можете использовать большинство других условных выражений без проблем. Последние две вещи лучше не трогать, чтобы не нарушить работу других частей WordPress. Если хотите разобраться глубже, прочитайте страницу Codex по ссылке и посмотрите доклад Нацина "You Don't Know Query" на WordPress.tv.
