Можно ли запросить несколько CPT, а затем заказать заранее заданным способом?
Например, у меня есть 2 CPT и 1, являющийся «публикацией» WP по умолчанию, и я хотел бы, чтобы цикл возвращал 6 результатов в порядке, указанном ниже.
Возможно ли это без разделения цикла?
У меня был быстрый поиск, но я смог найти только одну статью, касающуюся этого, решения из которой больше не работают...
Ага, правильно...
Это то, что я делал некоторое время назад, и хотя это выполнимо с помощью всего одного запроса, это немного многословная настройка.
Суть в том, что вы можете использовать один запрос, а затем перебирать запрос, пока не найдете первое сообщение, которое вам нужно. Затем выйдите из цикла и используйте WP_Query->rewind_posts()
, чтобы вернуть запрос в начало.
Затем вы можете запустить второй цикл с другим условием. А потом третий.
Для четвертой, пятой и шестой петель вам также нужно убедиться, что вы не повторяете первый подход.
См. ниже код во всей его красе.
<?php
$my_query = new WP_Query(
array(
'post_status' => 'publish',
)
);
$post_1 = $post_2 = $post_3 = $post_4 = $post_5 = $post_6 = 0;
if ( $my_query->have_posts() ) {
/*First loop through posts*/
while ( $my_query->have_posts() ) {
$my_query->the_post();
/**
* Find the first post
*/
if ( 'CPT-1' == get_post_type() && $post_1 == 0 ) {
do_something_with_the_post();
$post_1 = get_the_id();
break;
}
}
$my_query->rewind_posts();
/*Second loop through posts*/
while ( $my_query->have_posts() ) {
$my_query->the_post();
/**
* Find the second post
*/
if ( 'CPT-2' == get_post_type() && $post_2 == 0 ) {
do_something_with_the_post();
$post_2 = get_the_id();
break;
}
}
$my_query->rewind_posts();
/*Third loop through posts*/
while ( $my_query->have_posts() ) {
$my_query->the_post();
/**
* Find the third post
*/
if ( 'post' == get_post_type() && $post_3 == 0 ) {
do_something_with_the_post();
$post_3 = get_the_id();
break;
}
}
$my_query->rewind_posts();
/**
* Then we repeat this process but also check we don't use the same post twice
*/
/*Fourth loop through posts*/
while ( $my_query->have_posts() ) {
$my_query->the_post();
/**
* Find the fourth post
*/
if ( 'CPT-1' == get_post_type() && $post_4 == 0 && get_the_id() !== $post_1 ) {
do_something_with_the_post();
$post_1 = get_the_id();
break;
}
}
$my_query->rewind_posts();
/*Fifth loop through posts*/
while ( $my_query->have_posts() ) {
$my_query->the_post();
/**
* Find the fifth post
*/
if ( 'CPT-2' == get_post_type() && $post_5 == 0 && get_the_id() !== $post_2 ) {
do_something_with_the_post();
$post_5 = get_the_id();
break;
}
}
$my_query->rewind_posts();
/*Sixth loop through posts*/
while ( $my_query->have_posts() ) {
$my_query->the_post();
/**
* Find the sixth post
*/
if ( 'post' == get_post_type() && $post_6 == 0 && get_the_id() !== $post_3 ) {
do_something_with_the_post();
$post_6 = get_the_id();
break;
}
}
/**
* And we're finished
*/
}
Нет ли решения без многократной временной петли?
Вот сокращенная версия кода Sephsekla:
$my_post_types = array( 'CPT-1', 'CPT-2', 'post', 'CPT-1', 'CPT-2', 'post' );
$posts_shown = array();
$args = array(
'post_type' => array( 'CPT-1', 'CPT-2', 'post' ),
'post_status' => 'publish',
'posts_per_page' => -1
);
$my_query = new WP_Query( $args );
foreach ( $my_post_types as $post_type ):
while ( $my_query->have_posts() ): $my_query->the_post();
if ( $post_type == get_post_type() && ! in_array( get_the_ID(), $posts_shown ) ) {
echo '<pre>' . get_post_type() .': '. get_the_title() . '</pre>';
$posts_shown[] = get_the_id();
break;
}
endwhile;
$my_query->rewind_posts();
endforeach;
wp_reset_postdata();
Это значительно более элегантно и намного менее неуклюже, чем мой старый код. Обязательно пойдите с этим.
Как бы вы изменили свой код @vayu-robins, чтобы включить разные файлы шаблонов для каждого типа сообщений?
@revive пожалуйста, взгляните на developer.wordpress.org/reference/functions/get_template_part. Вы можете называть свои части шаблона по-разному, используя get_post_typ()
Я пытаюсь сделать что-то подобное, и хотя код супер элегантный Ваю не выполняет то, что мне нужно, в частности, мне нужно иметь возможность включать разные части шаблона для каждого типа сообщения (у них немного разное содержимое), а также добавить $arg для публикации WP (не CPT) для таргетинга на определенную категорию
То, что я пытаюсь сделать, это (только в логическом формате с $args выше):
$my_post_types = array( 'auctions', 'liquidations', 'inventory', 'post' );
// set args for ALL posts
$args = array(
'post_type' => $my_post_types,
'orderby' => 'date',
'order' => 'DESC',
'post_status' => 'publish',
);
Now we loop through posts (while loop)
IF 'post_type == auctions'
add number_posts to $args from ACF field for this post type
get_template_part( 'template-parts/card', 'auction' );
IF 'post_type == liquidations'
add number_posts to $args from ACF field for this post type
get_template_part( 'template-parts/card', 'liquidations' );
IF 'post_type == inventory'
add number_posts to $args from ACF field for this post type
get_template_part( 'template-parts/card', 'inventory' );
IF 'post_type == post'
add 'cat => 304' to $args
add number_posts to $args from ACF field for this post type
and get_template_part( 'template-parts/card', 'studies' );
Цель состоит в том, чтобы показать все CPT и сообщения в количестве, установленном для каждого типа в админке, отсортированные по дате, на одной странице. Мне нужно обновить/добавить в $args для каждого из циклов типа сообщения....
То есть всегда должно быть по 2 элемента из каждого типа поста?