Получение предыдущего и следующего поста по ID записи

14 июн. 2012 г., 22:20:45
Просмотры: 14.8K
Голосов: 8

Как я могу получить предыдущий и следующий пост вне стандартного цикла? Все мои попытки, кроме кастомного SQL-запроса (используя get_posts или WP_Query), ломают дальнейшую работу страницы.

Сейчас у меня есть рекурсивная функция, которая должна находить первый "предыдущий" пост, удовлетворяющий определенному условию. Я получаю первое значение для проверки через get_previous_post(), но не знаю, как получить previous_previous_post().

add_action( 'wp_ajax_nopriv_myajax-submit', 'ajax_project_load' );
add_action( 'wp_ajax_myajax-submit', 'ajax_project_load' );

function ajax_project_load() {
    $the_slug = $_POST['slug'];
    $args=array(
      'name' => $the_slug,
      'post_type' => 'projects',
      'post_status' => 'publish',
      'showposts' => 1,
      'ignore_sticky_posts' => 1
    );
    $my_posts = get_posts($args);
    if( $my_posts ) :

        global $post;
        $post = $my_posts[0]; 
        $postCapabilityFilter = $_POST['capFilter']=='undefined' ? $_POST['capFilter'] : substr($_POST['capFilter'], 1);

        $response = json_encode( "Success" );
        header( "Content-Type: application/json" );     


$next_post = get_previous_post();
function filtered_next_post($next_post){
    if($next_post){
        $next_slug = $next_post->post_name;
        $next_ID = $next_post->ID;
        global $wpdb;
        global $postCapabilityFilter;
        $querystr = "
        SELECT $wpdb->postmeta.*
        FROM $wpdb->posts, $wpdb->postmeta
        WHERE $wpdb->posts.post_type = 'projects' 
        AND $wpdb->posts.post_status = 'publish' 
        AND $wpdb->posts.ID = $next_ID
        AND $wpdb->posts.ID = $wpdb->postmeta.post_id
        AND $wpdb->postmeta.meta_key = '_slideshow_content'
        ORDER BY $wpdb->posts.post_name DESC
        ";
        $nextProjQuery = $wpdb->get_results($querystr, OBJECT);
        foreach($nextProjQuery as $nextProj):
            $nextProjMetaArr = unserialize($nextProj->meta_value);
            foreach ($nextProjMetaArr['slides'] as $npSlideArr){
                echo 'и..';
                if ( !in_array( $postCapabilityFilter, $npSlideArr['slideCap'] ) ){
                    echo 'не содержит..';
                    //$next_post = get_previous_previous_post();
                    //filtered_next_post($next_post);
                }
            }
        endforeach;                        
        return $next_slug;
    }
}
$next_slug = filtered_next_post($next_post);
0
Все ответы на вопрос 3
1
12

Если взглянуть на функции get_previous_post() и get_next_post(), можно заметить, что обе они используют get_adjacent_post() для поиска предыдущей или следующей записи.

Допустим, вам нужно получить ID предыдущей записи относительно текущей. Вот как это можно сделать:

function get_previous_post_id( $post_id ) {
    // Получаем глобальную ссылку на запись, так как get_adjacent_post() использует её
    global $post;

    // Сохраняем текущий объект записи, чтобы не потерять его
    $oldGlobal = $post;

    // Получаем объект записи по указанному ID и помещаем его в глобальную переменную
    $post = get_post( $post_id );

    // Получаем объект предыдущей записи
    $previous_post = get_previous_post();

    // Восстанавливаем исходный глобальный объект
    $post = $oldGlobal;

    if ( '' == $previous_post ) {
        return 0;
    }

    return $previous_post->ID;
}

Аналогичным образом можно получить ID следующей записи... или даже сделать это рекурсивно, если нужно получить запись перед предыдущей:

$two_posts_ago = get_previous_post_id( get_previous_post_id( $post->ID ) );

Коротко о главном

По сути, обе функции get_previous_post() и get_next_post() используют глобальный объект $post для определения соседних записей. Этот объект нужно установить перед вызовом функций, иначе они не будут знать, относительно какой записи искать предыдущую/следующую.

Приведённая выше обёрточная функция просто устанавливает глобальный $post на основе переданного ID. Вы можете модифицировать её, чтобы она возвращала весь объект предыдущей записи вместо ID — всё зависит от ваших потребностей.

15 июн. 2012 г. 01:03:54
Комментарии

Это именно тот подход, с которого я начал, но по какой-то причине всё зависало, когда я пытался вернуть $post в $oldpost. Никаких ошибок, никаких указаний на то, что шло не так - только крутящийся индикатор загрузки. Вероятно, что-то странное в моём коде, но я так и не смог понять, в чём проблема. Сейчас мой код в основном работает, но он представляет собой чудовище из SQL-запросов и занял несколько часов на сборку.

Zach Lysobey Zach Lysobey
15 июн. 2012 г. 06:30:07
1

Здесь вы можете получить соседнюю запись для определённого типа поста с помощью пользовательского SQL-запроса и фильтра get_{$adjacent}_post_where, где по умолчанию соседний пост является предыдущим. Также результат зависит от $current_post_date и оператора сравнения $op.

function bm_get_adjacent_post( $post_id, $author_id, $previous = 1 ) {
global $wpdb;

if ( ( ! $post = get_post( $post_id ) )  )
    return null;

$current_post_date = $post->post_date;

$adjacent = $previous ? 'previous' : 'next';
$op = $previous ? '<' : '>';
$order = $previous ? 'DESC' : 'ASC';

$where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE  p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' AND p.post_author = %d", $current_post_date, 'projects' , $author_id ), '', '' );
$sort  = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" );

$query = "SELECT p.ID FROM $wpdb->posts AS p $where $sort";
//echo $query;
$result = $wpdb->get_var( $query );
if ( null === $result )
    $result = '';
if ( $result )
    $result = get_post( $result );

return $result;
}
13 мая 2014 г. 09:43:26
Комментарии

Это не ответ. Пожалуйста, добавьте объяснение того, что делает ваш код и как он работает.

Pieter Goosen Pieter Goosen
13 мая 2014 г. 10:02:39
0

Мне очень нравится этот ответ, найденный по ссылке: https://stackoverflow.com/a/33688032/2062851

function get_previous_post_id( $post_id ) {
    // Получаем глобальную ссылку на пост, так как get_adjacent_post() ссылается на неё
    global $post;
    // Сохраняем существующий объект поста, чтобы не потерять его
    $oldGlobal = $post;
    // Получаем объект поста для указанного ID и помещаем его в глобальную переменную
    $post = get_post( $post_id );
    // Получаем объект предыдущего поста
    $previous_post = get_previous_post();
    // Восстанавливаем глобальный объект
    $post = $oldGlobal;
    if ( '' == $previous_post ) 
        return 0;
    return $previous_post->ID; 
} 

function get_next_post_id( $post_id ) {
    // Получаем глобальную ссылку на пост, так как get_adjacent_post() ссылается на неё
    global $post;
    // Сохраняем существующий объект поста, чтобы не потерять его
    $oldGlobal = $post;
    // Получаем объект поста для указанного ID и помещаем его в глобальную переменную
    $post = get_post( $post_id );
    // Получаем объект следующего поста
    $next_post = get_next_post();
    // Восстанавливаем глобальный объект
    $post = $oldGlobal;
    if ( '' == $next_post ) 
        return 0;
    return $next_post->ID; 
} 

Затем всё, что вам нужно сделать, это вызвать функцию следующим образом:

echo get_previous_post_id( $current_id );
echo get_next_post_id( $current_id );
28 нояб. 2020 г. 06:03:03