Получите следующие и предыдущие 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;
}
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 );
Ваш синтаксис немного отличается - $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
}