Сортировка записей по пользовательским полям

Обзор

В этой статье показано, как получить и отсортировать массив объектов записей из базы данных с помощью стандартных функций WP. Существует много способов выполнить запрос записей в WP, однако в этой статье мы рассмотрим распространённую функцию get_posts, объект WP_Query и фильтр pre_get_posts.

Начало работы

Если вы уже знакомы с указанными выше функцией, объектом и фильтром, можете пропустить этот раздел.

Объект WP_Query используется для запроса записей и возвращает объект, содержащий массив объектов $post и множество полезных методов.

Функция get_posts использует указанный выше объект WP_Query, однако возвращает только массив объектов $post, поэтому это более простой способ находить записи и проходить по ним в цикле.

Фильтр pre_get_posts вызывается после создания объекта запроса, но до выполнения самого запроса.

Примеры

get_posts

В этом примере используется функция get_posts для загрузки всех записей типа «event», отсортированных по значению пользовательского поля «start_date».

<?php 

// Получаем записи
$posts = get_posts(array(
    'post_type'         => 'event',
    'posts_per_page'    => -1,
    'meta_key'          => 'start_date',
    'orderby'           => 'meta_value',
    'order'             => 'DESC'
));

if( $posts ): ?>
    
    <ul>
        
    <?php foreach( $posts as $post ): 
        
        setup_postdata( $post )
        
        ?>
        <li>
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?> (дата: <?php the_field('start_date'); ?>)</a>
        </li>
    
    <?php endforeach; ?>
    
    </ul>
    
    <?php wp_reset_postdata(); ?>

<?php endif; ?>

WP_Query

В этом примере используется объект WP_Query для загрузки всех записей типа «event», отсортированных по пользовательскому полю «featured». В данном случае «featured» — это пользовательское поле True / False, и в результате отмеченные записи будут показаны выше остальных.

<?php 

// Запрос
$the_query = new WP_Query(array(
    'post_type'         => 'event',
    'posts_per_page'    => -1,
    'meta_key'          => 'featured',
    'orderby'           => 'meta_value',
    'order'             => 'DESC'
));

?>
<?php if( $the_query->have_posts() ): ?>
    <ul>
    <?php while( $the_query->have_posts() ) : $the_query->the_post(); 
        
        $class = get_field('featured') ? 'class="featured"' : '';
        
        ?>
        <li <?php echo $class; ?>>
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </li>
    <?php endwhile; ?>
    </ul>
<?php endif; ?>

<?php wp_reset_query();   // Восстанавливает глобальные данные записи, перезаписанные the_post(). ?>

pre_get_posts

В этом примере показано, как изменить текущий запрос записей. Это полезно для изменения существующего архива типа записи. Этот фильтр следует использовать в файле functions.php, и для него нужна некоторая логика, чтобы не изменять все запросы.

functions.php

<?php

function my_pre_get_posts( $query ) {
    
    // Не изменять запросы в админке
    if( is_admin() ) {
        
        return $query;
        
    }
    

    // Изменяем только запросы для типа записи 'event'
    if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'event' ) {
        
        $query->set('orderby', 'meta_value');    
        $query->set('meta_key', 'start_date');    
        $query->set('order', 'DESC'); 
        
    }
    

    // Возвращаем
    return $query;

}

add_action('pre_get_posts', 'my_pre_get_posts');

?>

Обновлено: 01.06.2026