Как отфильтровать функцию получения предыдущей записи по значению метаданных DESC и дате публикации DESC?

Вопрос или проблема

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

Однако, когда я использую <?php echo get_previous_post(); ?>, он берёт посты в обратном хронологическом порядке.

Как мне добавить фильтр к функции предыдущего поста, аналогичный этому, но вместо этого фильтруя по массиву, как: 'orderby' => array( 'meta_value' => 'DESC', 'date' => 'DESC')?


Код:


ОБНОВЛЕНИЕ: Убрал лишние элементы в цикле index.php после помощи от @sMyles и @JackJohansson

Цикл index.php:

$args = array(
    'posts_per_page' => - 1,
    'meta_key' => 'meta-checkbox',
    'orderby' => array( 'meta_value' => 'DESC', 'date' => 'DESC')
);

$posts = new WP_Query( $args );

if($posts->have_posts() ){

    while( $posts->have_posts() ){

        $posts->the_post();

        // Устанавливаем шаблон контента по умолчанию
        $template="content";

        // Меняем шаблон на избранный, когда мета `is_featured` имеет значение
        if(get_post_meta(get_the_ID(), 'meta-checkbox', 'yes')){
            $template="featured";
        }

        // Загружаем часть шаблона
        get_template_part( $template, get_post_format() );

    }
}


ОБНОВЛЕНИЕ: Как было предложено, я добавил, где использую функцию предыдущего поста

Функция Предыдущего Поста

<div id="next-post">
    <?php $prev_post = get_previous_post();
    if(!empty($prev_post)) {
        echo '<a class="next-story" href="' . get_permalink($prev_post->ID) . '">Следующая История</a>'; 
        echo '<a class="next-story-title" href="' . get_permalink($prev_post->ID) . '" title="' . $prev_post->post_title . '">' . $prev_post->post_title . '</a>'; 
    } ?>
</div>


Функция Для Избранных Постов:

function sm_custom_meta() {
    add_meta_box( 'sm_meta', __( 'Избранные Посты', 'sm-textdomain' ), 'sm_meta_callback', 'post' );
}
function sm_meta_callback( $post ) {
    $featured = get_post_meta( $post->ID );
?>

<p>
<div class="sm-row-content">
    <label for="meta-checkbox">
        <input type="checkbox" name="meta-checkbox" id="meta-checkbox" value="yes" <?php if ( isset ( $featured['meta-checkbox'] ) ) checked( $featured['meta-checkbox'][0], 'yes' ); ?> />
        <?php _e( 'Избранный этот пост', 'sm-textdomain' )?>
    </label>

</div>
</p>

<?php
}
add_action( 'add_meta_boxes', 'sm_custom_meta' );

function sm_meta_save( $post_id ) {

    // Проверяет статус сохранения
    $is_autosave = wp_is_post_autosave( $post_id );
    $is_revision = wp_is_post_revision( $post_id );
    $is_valid_nonce = ( isset( $_POST[ 'sm_nonce' ] ) && wp_verify_nonce( $_POST[ 'sm_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';

    // Выход из скрипта в зависимости от статуса сохранения
    if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
        return;
    }

    // Проверяет ввод и сохраняет
    if( isset( $_POST[ 'meta-checkbox' ] ) ) {
        update_post_meta( $post_id, 'meta-checkbox', 'yes' );

    } else {
        update_post_meta( $post_id, 'meta-checkbox', '' );
    }

}
add_action( 'save_post', 'sm_meta_save' );

Вам следует просто сделать новый полный запрос для всех постов (не только избранных) и установить orderby на meta_value, а затем просто проверить в цикле, имеет ли этот пост мета значение yes, и вывести избранный шаблон, иначе вывести стандартный.

https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters

ОБНОВЛЕНИЕ:
Может что-то вроде этого:

$args = array(
    'posts_per_page' => - 1,
    'meta_key' => 'meta-checkbox',
    'orderby' => array( 'meta_value' => 'DESC', 'date' => 'DESC')
);

$posts = new WP_Query( $args );

if($posts->have_posts() ){

    while( $posts->have_posts() ){

        $posts->the_post();

        // Устанавливаем шаблон контента по умолчанию
        $template="content";

        // Меняем шаблон на избранный, когда мета `is_featured` имеет значение
        if(get_post_meta(get_the_ID(), 'meta-checkbox', true)){
            $template="featured";
        }

        // Загружаем часть шаблона
        get_template_part( $template, get_post_format() );

    }
}

Вы заметите, что я изменил мета ключ на is_featured .. это хорошая практика использовать подчеркивания вместо дефисов.

Чтобы получить значение мета для поста, просто используйте объект $post, который имеет магический метод PHP __get, который вернёт мета поста, если она существует.

http://php.net/manual/en/language.oop5.overloading.php#object.get

Добавьте это в файл functions.php вашей дочерней темы, чтобы изменить основной запрос цикла постов:

add_action( 'pre_get_posts', 'smyles_main_query_custom_orderby' );
/**
 *  Измените основной запрос постов, сортируя по мета ключу и дате
 *
 * @param \WP_Query $query
 */
function smyles_main_query_custom_orderby( $query ) {

    // Подтверждает, что запрос является основным архивом блога
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'meta_key', 'meta-checkbox' );
        $query->set( 'orderby', array( 'meta_value' => 'DESC', 'date' => 'DESC' ) );
    }

}

https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts
https://make.wordpress.org/core/2014/08/29/a-more-powerful-order-by-in-wordpress-4-0/

Ваш цикл в файле index.php может выглядеть так:

if ( have_posts() ) {

    while( have_posts() ) {

        the_post();

        $template = get_post_meta( get_the_ID(), 'meta-checkbox', true ) ? 'featured' : 'content';
        // Это могло бы быть просто код ниже, если бы вы использовали подчеркивания, как я упомянул ранее
        // $template = $post->meta_checkbox ? 'featured' : 'content';

        // Загружаем часть шаблона
        get_template_part( $template, get_post_format() );

    }
}

Ответ или решение

Чтобы отфильтровать функцию get_previous_post, используя значения метаданных в порядке убывания, а также дату публикации в убывающем порядке, необходимо внести изменения в стандартное поведение этой функции. Давайте подробно разберем, как это сделать.

Контекст задачи

Ваша функция get_previous_post() по умолчанию возвращает предыдущий пост в обратном хронологическом порядке. Это не всегда соответствует вашим требованиям, особенно если вы хотите учитывать мета-значения и дату публикации. Вам необходимо модифицировать логику извлечения постов, чтобы учитывать указанные вами параметры: meta_value и date.

Решение

  1. Создание собственного запроса для предыдущего поста:

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

  1. Код для получения предыдущего поста:

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

function get_custom_previous_post() {
    // Получаем текущий пост
    global $post;

    // Устанавливаем параметры запроса
    $args = array(
        'posts_per_page' => 1,
        'meta_key' => 'meta-checkbox', // Замена на ключ метаданных
        'meta_value' => 'yes', // Убедитесь, что у вас есть такая проверка
        'orderby' => array('meta_value' => 'DESC', 'date' => 'DESC'),
        'order' => 'DESC',
        'post_type' => 'post', // Убедитесь, что это нужный тип поста
        'post_status' => 'publish',
        'date_query' => array(
            array(
                'before' => $post->post_date // Получаем пост, который был до текущего
            )
        )
    );

    // Новый запрос
    $query = new WP_Query($args);

    // Если пост найден, возвращаем его
    if($query->have_posts()) {
        $query->the_post(); // Устанавливаем пост из запроса
        return $post; // Возвращаем текущий объект поста
    }

    // Сбрасываем данные запроса
    wp_reset_postdata();

    return null; // Если пост не найден
}

// Использование функции
$prev_post = get_custom_previous_post();
if($prev_post) {
    echo '<a class="prev-story" href="' . get_permalink($prev_post->ID) . '">Предыдущая история</a>';
    echo '<a class="prev-story-title" href="' . get_permalink($prev_post->ID) . '" title="' . $prev_post->post_title . '">' . $prev_post->post_title . '</a>';
}

Объяснение кода

  • Создание аргументов запроса: Мы настраиваем массив $args, который включает параметры сортировки по метадате meta-checkbox и дате публикации.

  • Запрос: Используем WP_Query для выполнения запроса и получения поста, соответствующего заданным критериям.

  • Логика: После выполнения запроса мы проверяем, найден ли предыдущий пост, и выводим его заголовок и ссылку.

Заключение

Используя предложенное решение, вы сможете фильтровать предыдущие посты по метадатам и дате публикации, получая желаемый результат. Обязательно протестируйте изменения на локальной среде перед развертыванием на живом сайте. Это обеспечит стабильность и правильное поведение вашего сайта.

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

Капча загружается...