Запрос пользовательских типов сообщений и порядок по пользовательскому типу сообщений

Можно ли запросить несколько CPT, а затем заказать заранее заданным способом?

Например, у меня есть 2 CPT и 1, являющийся «публикацией» WP по умолчанию, и я хотел бы, чтобы цикл возвращал 6 результатов в порядке, указанном ниже.

  • СРТ-1
  • КПТ-2
  • СООБЩЕНИЕ
  • СРТ-1
  • КПТ-2
  • СООБЩЕНИЕ

Возможно ли это без разделения цикла?

У меня был быстрый поиск, но я смог найти только одну статью, касающуюся этого, решения из которой больше не работают...

Wordpress упорядочивает сообщения по типу сообщения

То есть всегда должно быть по 2 элемента из каждого типа поста?

Krzysiek Dróżdż 07.04.2019 15:35

Ага, правильно...

user1235285 08.04.2019 04:28
Как убрать количество товаров в категории WooCommerce
Как убрать количество товаров в категории WooCommerce
По умолчанию WooCommerce показывает количество товаров рядом с категорией, как показано ниже.
2
2
380
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это то, что я делал некоторое время назад, и хотя это выполнимо с помощью всего одного запроса, это немного многословная настройка.

Суть в том, что вы можете использовать один запрос, а затем перебирать запрос, пока не найдете первое сообщение, которое вам нужно. Затем выйдите из цикла и используйте 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
     */
}

Нет ли решения без многократной временной петли?

Mahmudul Hasan Sohag 20.06.2021 01:50
Ответ принят как подходящий

Вот сокращенная версия кода 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();

Это значительно более элегантно и намного менее неуклюже, чем мой старый код. Обязательно пойдите с этим.

Sephsekla 12.04.2019 12:17

Как бы вы изменили свой код @vayu-robins, чтобы включить разные файлы шаблонов для каждого типа сообщений?

revive 17.12.2021 16:40

@revive пожалуйста, взгляните на developer.wordpress.org/reference/functions/get_template_par‌​t. Вы можете называть свои части шаблона по-разному, используя get_post_typ()

Vayu Robins 20.12.2021 09:29

Я пытаюсь сделать что-то подобное, и хотя код супер элегантный Ваю не выполняет то, что мне нужно, в частности, мне нужно иметь возможность включать разные части шаблона для каждого типа сообщения (у них немного разное содержимое), а также добавить $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 для каждого из циклов типа сообщения....

Другие вопросы по теме

WordPress: невозможно включить пользовательский цикл типа записи (с использованием «the_field» ACF) внутри эхо-строки PHP
Как создать цикл, в котором цикл изменяет каждый пост в пользовательском типе поста?
Как я могу отменить регистрацию этого пользовательского типа сообщений?
Вставьте пользовательский тип записи в логин пользователя WordPress, возможно ли это?
Получить все сообщения, если в сообщениях есть одинаковые значения настраиваемых полей
Ошибка 404 при нумерации страниц для настраиваемого типа записи, настраиваемых таксономий
Wordpress: конфликт имени сообщения и постоянной ссылки на страницу
Как сделать видимость пользовательского типа записи WordPress закрытой после редактирования?
Добавить настраиваемое поле в продукты для отображения в корзине, оформлении заказа и в заказах
Имя пользовательской таксономии не извлекается