Получите следующие и предыдущие 3 сообщения за один срок на одной странице публикации


У меня есть следующее

  • Пользовательский тип записи: episode

  • Пользовательская таксономия: series

    • дополнительные термины real deal -> season 1, season 2, season 3, и т.д.

Термины являются иерархическими, и все это должно быть структурировано как телесериал (в каждой "серии" есть "сезоны").

На странице single-episode.php я хочу отобразить текущий эпизод, А ТАКЖЕ ссылки на следующие 3 эпизода и предыдущие 3 эпизода в этом сезоне.

В качестве примера, если на странице "1 сезон - 5 серия" мне нужно получить контент для 1 сезона,

Эпизоды 4,3,2 + Эпизоды 1 сезона 6,7,8.

Мне трудно понять, как это сделать внутри цикла на одной странице эпизода.

Вот что у меня есть в настоящее время, однако это не работает - он просто повторяет название текущего эпизода страницы снова и снова с

Попытка получить собственность не-объекта

Ошибка.

<?php
  $args = array(
      'post-type'      => 'episode',
      'post-status'    => 'publish',
      'posts_per_page' => 6,
      'tax_query'      => array(
          'relation' => 'AND',
          array(
              'taxonomy' => 'series',
              'field'    => 'slug',
              /* Name of the "series" (in slug format) */
              'terms'    => array( 'season-1' ),
          ),
          array(
              'taxonomy' => 'series',
              'field'    => 'slug',
              /* Name of the "seasons" (in slug format) DYNAMIC */
              'terms'    => array( $term->slug ),
          )
      )
  );
  $episodes = new WP_Query( $args );
  foreach( $episodes as $episode ) {
    echo get_the_title($episode->id);
  }
?>

РЕДАКТИРОВАТЬ:

Вот мой обновленный запрос, над которым все еще ведется работа. Похоже, в данный момент он ничего не получает. Я хочу получить в общей сложности 6 результатов, 3 опубликованных ДО текущего сообщения, 3 опубликованных ПОСЛЕ текущего сообщения. Я пытаюсь использовать post_date как для before, так и для after свойств date_query, но не уверен, правильно ли я это делаю.

$args = [
    'tax_query' => [
      'relation' => 'AND', [
        'taxonomy' => 'series',
        'field'    => 'slug',
        /* Name of the "series" (in slug format) */
        'terms'    => ['season-1'],
      ]
    ],
    'posts_per_page' => 6,
    /* make query more efficient */
    'no_found_rows' => true,
    /* dont let filters/pre_get_posts modify query */
    'suppress_filters' => true,
    'date_query' => [
      [
        'before'    => $post_object->post_date,
        'after'     => $post_object->post_date,
      ],
      'inclusive' => false
    ]
];
$q = new WP_Query( $args );
return $q->posts;

РЕДАКТИРОВАТЬ 2:

Я добился желаемого эффекта, используя очень неэффективный метод - он работает, но я хотел бы услышать несколько советов по его оптимизации! кажется очень дорогим с точки зрения запросов прямо сейчас.

$orig_post = $post;
$orig_terms = wp_get_post_terms($orig_post->ID, 'series');
$current_post = $post;
$adjPost = [
  'prev' => [],
  'next' => []
];

for($i = 1; $i <= 3; $i++){
  $post = get_previous_post(true, '', 'series'); // this uses $post->ID
  if ( $post ) {
    $these_terms = wp_get_post_terms($post->ID, 'series');
    if ( $these_terms[1]->slug === $orig_terms[1]->slug) {
      array_push( $adjPost['prev'], $post );
    }
  }
}
$post = $current_post;

for($i = 1; $i <= 3; $i++){
  $post = get_next_post(true, '', 'series'); // this uses $post->ID
  if ( $post ) {
    $these_terms = wp_get_post_terms($post->ID, 'series');
    if ( $these_terms[1]->slug === $orig_terms[1]->slug) {
      array_push( $adjPost['next'], $post );
    }
  }
}
$post = $current_post;

echo "<h1>Prev:</h1>";
foreach ( $adjPost['prev'] as $prev ) {
  echo '<br>';
  echo $prev->post_title;
}

echo "<h1>Next:</h1>";
foreach ( $adjPost['next'] as $next ) {
  echo '<br>';
  echo $next->post_title;
}
Author: T_Conroy, 2015-04-01

2 answers

Ваш второй подход (РЕДАКТИРОВАТЬ 2), к сожалению, довольно глючный и неэффективный. Кроме того, вы не собираетесь делать это в одном запросе.

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

Я оптимизировал код, чтобы получите только необходимую информацию и ничего больше. WP_Query результаты также кэшируются, так что вам действительно не нужно так сильно беспокоиться об эффективности.

Я не собираюсь снова повторять все детали в этом ответе, вам следует подробно просмотреть связанный пост, но вы можете попробовать что-то вроде этого ( ПРЕДОСТЕРЕЖЕНИЕ: Непроверено. Пожалуйста, ознакомьтесь с примечаниями в связанном ответе)

$post_object = get_queried_object();
$terms = wp_get_post_terms( $post_object->ID, 'series', array( 'fields' => 'ids' ) ); // Set fields to get only term ID's to make this more effient
$args = [
    'post_type' => $post_object->post_type,
    'tax_query' => [
       [
        'taxonomy' => 'series',
        'terms'    => $terms,
      ]
    ],
    'posts_per_page' => 3,
    'order' => 'ASC' // CHANDE TO DESC IF NOT CORRECT
    /* make query more efficient */
    'no_found_rows' => true,
    /* dont let filters modify query */
    'suppress_filters' => true,
    'date_query' => [
      [
        'before'    => $post_object->post_date,
        'inclusive' => false
      ],
    ]
];
$q1 = new WP_Query( $args );
var_dump( $q1->posts );

$args1 = [
    'post_type' => $post_object->post_type,
    'tax_query' => [
       [
        'taxonomy' => 'series',
        'terms'    => $terms,
      ]
    ],
    'posts_per_page' => 3,
    'order' => 'DESC' // CHANDE TO ASC IF NOT CORRECT
    /* make query more efficient */
    'no_found_rows' => true,
    /* dont let filters modify query */
    'suppress_filters' => true,
    'date_query' => [
      [
        'after'    => $post_object->post_date,
        'inclusive' => false
      ],
    ]
];
$q2 = new WP_Query( $args1 );
var_dump( $q2->posts );
 1
Author: Pieter Goosen, 2017-04-13 12:37:38

Ваш синтаксис немного отличается - $episodes является экземпляром WP_Query, а не массивом. Если вам нужен полноценный цикл для использования всех тегов шаблона, используйте:

while ( $episodes->have_posts() ) {
    $episodes->the_post();

    the_title(); // Episode title
    the_content(); // Episode content
}

wp_reset_postdata(); // Restore current episode

В противном случае вы можете просто foreach в свойстве posts:

foreach ( $episodes->posts as $episode ) {
    echo get_the_title( $episode ); // Most template tags accept a post object
    echo get_the_post_thumbnail( $episode->ID ); // Only accepts post ID
    echo get_the_content(); // Does not accept a post argument, you'd need the loop above to set up the global post object
}
 0
Author: TheDeadMedic, 2015-04-01 16:10:46